From 3eae1685be3ad75feb21e953cdee8c2af68713e9 Mon Sep 17 00:00:00 2001 From: Allan Banaag Date: Tue, 17 Sep 2019 14:21:23 -0700 Subject: [PATCH 01/22] Update ACME config to include email adddress and acme challenge port. Update certcache to use certfetcher if cert autorenew is turned on. Update certloader.PopulateCertCache to instantiate certfetcher and pass it on to certcache instance. --- cmd/amppkg/main.go | 3 +- packager/certcache/certcache.go | 119 +++++++++++++++++++++++-- packager/certcache/certcache_test.go | 3 +- packager/certloader/certloader.go | 30 ++++++- packager/certloader/certloader_test.go | 5 +- packager/util/config.go | 2 + packager/util/config_test.go | 8 ++ 7 files changed, 154 insertions(+), 16 deletions(-) diff --git a/cmd/amppkg/main.go b/cmd/amppkg/main.go index e79e0ce58..2c19ebb58 100644 --- a/cmd/amppkg/main.go +++ b/cmd/amppkg/main.go @@ -39,6 +39,7 @@ import ( var flagConfig = flag.String("config", "amppkg.toml", "Path to the config toml file.") var flagDevelopment = flag.Bool("development", false, "True if this is a development server.") var flagInvalidCert = flag.Bool("invalidcert", false, "True if invalid certificate intentionally used in production.") +var flagAutoRenewCert = flag.Bool("autorenewcert", false, "True if amppackager is to attempt cert auto-renewal.") // Prints errors returned by pkg/errors with stack traces. func die(err interface{}) { log.Fatalf("%+v", err) } @@ -82,7 +83,7 @@ func main() { die(errors.Wrap(err, "loading key file")) } - certCache, err := certloader.PopulateCertCache(config, key, *flagDevelopment || *flagInvalidCert); + certCache, err := certloader.PopulateCertCache(config, key, *flagDevelopment || *flagInvalidCert, *flagAutoRenewCert) if err != nil { die(errors.Wrap(err, "building cert cache")) } diff --git a/packager/certcache/certcache.go b/packager/certcache/certcache.go index 692f7216c..33acda622 100644 --- a/packager/certcache/certcache.go +++ b/packager/certcache/certcache.go @@ -29,6 +29,7 @@ import ( "time" "github.com/WICG/webpackage/go/signedexchange/certurl" + "github.com/ampproject/amppackager/packager/certfetcher" "github.com/ampproject/amppackager/packager/mux" "github.com/ampproject/amppackager/packager/util" "github.com/pkg/errors" @@ -46,10 +47,19 @@ var infiniteFuture = time.Unix(1<<63-62135596801, 999999999) // 1MB is the maximum used by github.com/xenolf/lego/acmev2 in GetOCSPForCert. // Alternatively, here's a random documented example of a 20K limit: // https://www.ibm.com/support/knowledgecenter/en/SSPREK_9.0.0/com.ibm.isam.doc/wrp_stza_ref/reference/ref_ocsp_max_size.html -const maxOCSPResponseBytes = 1024 * 1024 +const MaxOCSPResponseBytes = 1024 * 1024 // How often to check if OCSP stapling needs updating. -const ocspCheckInterval = 1 * time.Hour +const OcspCheckInterval = 1 * time.Hour + +// How often to check if certs needs updating. +const CertCheckInterval = 24 * time.Hour + +// Recommended renewal duration for certs. +// 8 days is recommended duration to start requesting new certs to allow for ACME server outages. +// It's 6 days + 2 days renewal grace period. +// TODO(banaag): make 2 days renewal grace period configurable in toml. +const CertRenewalInterval = 8 * 24 * time.Hour type CertHandler interface { GetLatestCert() (*x509.Certificate) @@ -59,24 +69,33 @@ type CertCache struct { // TODO(twifkak): Support multiple cert chains (for different domains, for different roots). certName string certs []*x509.Certificate + // If certFetcher is not set, that means cert auto-renewal is not available. + certFetcher *certfetcher.CertFetcher + renewedCertsMu sync.RWMutex + renewedCerts []*x509.Certificate ocspUpdateAfterMu sync.RWMutex ocspUpdateAfter time.Time // TODO(twifkak): Implement a registry of Updateable instances which can be configured in the toml. - ocspFile Updateable - client http.Client + ocspFile Updateable + client http.Client // "Virtual methods", exposed for testing. // Given a certificate, returns the OCSP responder URL for that cert. extractOCSPServer func(*x509.Certificate) (string, error) // Given an HTTP request/response, returns its cache expiry. httpExpiry func(*http.Request, *http.Response) time.Time + // Is CertCache initialized to do cert renewal or OCSP refreshes? + isInitialized bool } -// Must call Init() on the returned CertCache before you can use it. -func New(certs []*x509.Certificate, ocspCache string) *CertCache { +// Callers need to call Init() on the returned CertCache before the cache can auto-renew certs. +// Callers can use the uninitialized CertCache either for testing certificates (without doing OCSP or +// cert refreshes). +func New(certs []*x509.Certificate, certFetcher *certfetcher.CertFetcher, ocspCache string) *CertCache { return &CertCache{ certName: util.CertName(certs[0]), certs: certs, + certFetcher: certFetcher, ocspUpdateAfter: infiniteFuture, // Default, in case initial readOCSP successfully loads from disk. // Distributed OCSP cache to support the following sleevi requirements: // 1. Support for keeping a long-lived (disk) cache of OCSP responses. @@ -104,6 +123,7 @@ func New(certs []*x509.Certificate, ocspCache string) *CertCache { return expiry } }, + isInitialized: false, } } @@ -122,6 +142,13 @@ func (this *CertCache) Init(stop chan struct{}) error { // to raise an alert if something has gone really wrong. // 7. The ability to serve old responses while fetching new responses. go this.maintainOCSP(stop) + + if this.certFetcher != nil { + // Update Certs in the background. + go this.maintainCerts(stop) + } + + this.isInitialized = true return nil } @@ -129,8 +156,26 @@ func (this *CertCache) Init(stop chan struct{}) error { // For follow-on changes, we will transform this to a lambda so that anything // that needs a cert can do the cert refresh logic (if needed) on demand. func (this *CertCache) GetLatestCert() (*x509.Certificate) { - // TODO(banaag): check if cert is still valid, refresh if not. - return this.certs[0] + if !this.isInitialized || this.certFetcher == nil { + // If certcache is not initialized or certFetcher is not set, + // just return cert without checking if it needs auto-renewal. + return this.certs[0] + } + d, err := util.GetDurationToExpiry(this.certs[0], this.certs[0].NotAfter) + if err != nil { + // Current cert is already invalid. Check if renewal is available. + log.Println("Current cert is expired, attempting to renew.") + return nil + } + if d >= time.Duration(CertRenewalInterval) { + // Cert is still valid. + return this.certs[0] + } else if d < time.Duration(CertRenewalInterval) { + // Cert is still valid, but we need to start process of requesting new cert. + log.Println("Current cert is close to expiry threshold, attempting to renew in the background.") + return this.certs[0] + } + return nil } func (this *CertCache) createCertChainCBOR(ocsp []byte) ([]byte, error) { @@ -263,7 +308,7 @@ func (this *CertCache) maintainOCSP(stop chan struct{}) { // has trouble getting a request, hopefully it does something // smarter than just retry in a busy loop, hammering the OCSP server // into further oblivion. - ticker := time.NewTicker(ocspCheckInterval) + ticker := time.NewTicker(OcspCheckInterval) for { select { @@ -440,3 +485,59 @@ func (this *CertCache) fetchOCSP(orig []byte, ocspUpdateAfter *time.Time) []byte } return respBytes } + + +// Checks for cert updates every certCheckInterval hours. Never terminates. +func (this *CertCache) maintainCerts(stop chan struct{}) { + // Only make one request per certCheckInterval, to minimize the impact + // on servers that are buckling under load. + ticker := time.NewTicker(CertCheckInterval) + + for { + select { + case <-ticker.C: + this.updateCertIfNecessary() + case <-stop: + ticker.Stop() + return + } + } +} + +// Set new cert with mutex protection. +func (this *CertCache) setNewCerts(certs []*x509.Certificate) { + this.renewedCertsMu.Lock() + defer this.renewedCertsMu.Unlock() + this.renewedCerts = certs +} + +// Update the cert in the cache if necessary. +func (this *CertCache) updateCertIfNecessary() { + if this.certFetcher == nil { + // Do nothing if certFetcher is not set. + return + } + d, err := util.GetDurationToExpiry(this.certs[0], this.certs[0].NotAfter) + if err != nil { + // Current cert is already invalid. Try refreshing. + log.Println("Warning current cert is expired, attempting to renew: ", err) + certs, err := this.certFetcher.FetchNewCert() + if err != nil { + log.Println("Error trying to fetch new certificates from CA: ", err) + return + } + this.setNewCerts(certs) + } + if d >= time.Duration(CertRenewalInterval) { + // Cert is still valid, don't do anything. + } else if d < time.Duration(CertRenewalInterval) { + // Cert is still valid, but we need to start process of requesting new cert. + log.Println("Warning: Current cert crossed threshold for renewal, attempting to renew.") + certs, err := this.certFetcher.FetchNewCert() + if err != nil { + log.Println("Error trying to fetch new certificates from CA: ", err) + return + } + this.setNewCerts(certs) + } +} diff --git a/packager/certcache/certcache_test.go b/packager/certcache/certcache_test.go index 7c0515c13..c38ca2771 100644 --- a/packager/certcache/certcache_test.go +++ b/packager/certcache/certcache_test.go @@ -74,7 +74,8 @@ type CertCacheSuite struct { func (this *CertCacheSuite) New() (*CertCache, error) { // TODO(twifkak): Stop the old CertCache's goroutine. - certCache := New(pkgt.B3Certs, filepath.Join(this.tempDir, "ocsp")) + // TODO(banaag): Set certfetcher. + certCache := New(pkgt.B3Certs, nil, filepath.Join(this.tempDir, "ocsp")) certCache.extractOCSPServer = func(*x509.Certificate) (string, error) { return this.ocspServer.URL, nil } diff --git a/packager/certloader/certloader.go b/packager/certloader/certloader.go index 860b63596..a38860a9d 100644 --- a/packager/certloader/certloader.go +++ b/packager/certloader/certloader.go @@ -24,24 +24,48 @@ import ( "github.com/pkg/errors" "github.com/ampproject/amppackager/packager/certcache" + "github.com/ampproject/amppackager/packager/certfetcher" "github.com/ampproject/amppackager/packager/util" ) // Creates cert cache by loading certs and keys from disk, doing validation // and populating the cert cache with current set of certificate related information. // If development mode is true, prints a warning for certs that can't sign HTTP exchanges. -func PopulateCertCache(config *util.Config, key crypto.PrivateKey, developmentMode bool) (*certcache.CertCache, error) { +func PopulateCertCache(config *util.Config, key crypto.PrivateKey, + developmentMode bool, autoRenewCert bool) (*certcache.CertCache, error) { + certs, err := loadCertsFromFile(config, developmentMode) if err != nil { return nil, err } + domain := "" for _, urlSet := range config.URLSet { - domain := urlSet.Sign.Domain + domain = urlSet.Sign.Domain if err := util.CertificateMatches(certs[0], key, domain); err != nil { return nil, errors.Wrapf(err, "checking %s", config.CertFile) } } - certCache := certcache.New(certs, config.OCSPCache) + + certFetcher := (*certfetcher.CertFetcher)(nil) + if autoRenewCert { + emailAddress := config.ACMEConfig.Production.EmailAddress + acmeDiscoveryURL := config.ACMEConfig.Production.DiscoURL + challengePort := config.ACMEConfig.Production.ChallengePort + if developmentMode { + emailAddress = config.ACMEConfig.Development.EmailAddress + acmeDiscoveryURL = config.ACMEConfig.Development.DiscoURL + challengePort = config.ACMEConfig.Development.ChallengePort + } + + // Create the cert fetcher that will auto-renew the cert. + certFetcher, err = certfetcher.NewFetcher(emailAddress, key, acmeDiscoveryURL, + []string{domain}, challengePort, !developmentMode) + if err != nil { + return nil, errors.Wrap(err, "creating certfetcher") + } + } + + certCache := certcache.New(certs, certFetcher, config.OCSPCache) return certCache, nil } diff --git a/packager/certloader/certloader_test.go b/packager/certloader/certloader_test.go index 186eed037..d435af700 100644 --- a/packager/certloader/certloader_test.go +++ b/packager/certloader/certloader_test.go @@ -59,10 +59,11 @@ func TestPopulateCertCache(t *testing.T) { }}, }, pkgt.B3Key, - true) + true, + false) + assert.Nil(t, err) assert.NotNil(t, certCache) assert.Equal(t, pkgt.B3Certs[0], certCache.GetLatestCert()) - assert.Nil(t, err) } func TestLoadCertsFromFile(t *testing.T) { diff --git a/packager/util/config.go b/packager/util/config.go index 75d6d0553..8cb3e26f9 100644 --- a/packager/util/config.go +++ b/packager/util/config.go @@ -68,6 +68,8 @@ type ACMEServerConfig struct { DiscoURL string // ACME Directory Resource URL AccountURL string // ACME Account URL. If non-empty, we // will auto-renew cert via ACME. + EmailAddress string // Email address registered with ACME CA. + ChallengePort int // ACME challenge port. } // TODO(twifkak): Extract default values into a function separate from the one diff --git a/packager/util/config_test.go b/packager/util/config_test.go index 688854a7c..08f79717e 100644 --- a/packager/util/config_test.go +++ b/packager/util/config_test.go @@ -214,9 +214,13 @@ func TestOptionalACMEConfig(t *testing.T) { [ACMEConfig.Production] DiscoURL = "prod.disco.url" AccountURL = "prod.account.url" + EmailAddress = "prodtest@test.com" + ChallengePort = 777 [ACMEConfig.Development] DiscoURL = "dev.disco.url" AccountURL = "dev.account.url" + EmailAddress = "devtest@test.com" + ChallengePort = 888 `)) require.NoError(t, err) assert.Equal(t, Config{ @@ -228,10 +232,14 @@ func TestOptionalACMEConfig(t *testing.T) { Production: &ACMEServerConfig{ DiscoURL: "prod.disco.url", AccountURL: "prod.account.url", + EmailAddress: "prodtest@test.com", + ChallengePort: 777, }, Development: &ACMEServerConfig{ DiscoURL: "dev.disco.url", AccountURL: "dev.account.url", + EmailAddress: "devtest@test.com", + ChallengePort: 888, }, }, URLSet: []URLSet{{ From 6e6936f767da83d1ffb4dcbcd5dbae7012e2cb7c Mon Sep 17 00:00:00 2001 From: Allan Banaag Date: Wed, 18 Sep 2019 10:11:02 -0700 Subject: [PATCH 02/22] Update ACME config to include email adddress and acme challenge port. Update certcache to use certfetcher if cert autorenew is turned on. Update certloader.PopulateCertCache to instantiate certfetcher and pass it on to certcache instance. --- cmd/amppkg/main.go | 2 ++ packager/certcache/certcache.go | 21 ++++++++++++++++++++- packager/certcache/certcache_test.go | 3 ++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/cmd/amppkg/main.go b/cmd/amppkg/main.go index 2c19ebb58..670212517 100644 --- a/cmd/amppkg/main.go +++ b/cmd/amppkg/main.go @@ -39,6 +39,8 @@ import ( var flagConfig = flag.String("config", "amppkg.toml", "Path to the config toml file.") var flagDevelopment = flag.Bool("development", false, "True if this is a development server.") var flagInvalidCert = flag.Bool("invalidcert", false, "True if invalid certificate intentionally used in production.") + +// IMPORTANT: do not turn on this flag for now, it's still under development. var flagAutoRenewCert = flag.Bool("autorenewcert", false, "True if amppackager is to attempt cert auto-renewal.") // Prints errors returned by pkg/errors with stack traces. diff --git a/packager/certcache/certcache.go b/packager/certcache/certcache.go index 33acda622..54fdacc54 100644 --- a/packager/certcache/certcache.go +++ b/packager/certcache/certcache.go @@ -68,6 +68,7 @@ type CertHandler interface { type CertCache struct { // TODO(twifkak): Support multiple cert chains (for different domains, for different roots). certName string + certsMu sync.RWMutex certs []*x509.Certificate // If certFetcher is not set, that means cert auto-renewal is not available. certFetcher *certfetcher.CertFetcher @@ -504,6 +505,13 @@ func (this *CertCache) maintainCerts(stop chan struct{}) { } } +// Set current cert with mutex protection. +func (this *CertCache) setCerts(certs []*x509.Certificate) { + this.certsMu.Lock() + defer this.certsMu.Unlock() + this.certs = certs +} + // Set new cert with mutex protection. func (this *CertCache) setNewCerts(certs []*x509.Certificate) { this.renewedCertsMu.Lock() @@ -519,6 +527,15 @@ func (this *CertCache) updateCertIfNecessary() { } d, err := util.GetDurationToExpiry(this.certs[0], this.certs[0].NotAfter) if err != nil { + if this.renewedCerts != nil { + // If renewedCerts is set, copy that over to certs + // and set renewedCerts to nil. + // TODO(banaag): do the same cert setting dance on disk. + // Purge OCSP cache? Make shouldUpdateOCSP() return true? + this.setCerts(this.renewedCerts) + this.setNewCerts(nil) + return + } // Current cert is already invalid. Try refreshing. log.Println("Warning current cert is expired, attempting to renew: ", err) certs, err := this.certFetcher.FetchNewCert() @@ -526,7 +543,8 @@ func (this *CertCache) updateCertIfNecessary() { log.Println("Error trying to fetch new certificates from CA: ", err) return } - this.setNewCerts(certs) + this.setCerts(certs) + return } if d >= time.Duration(CertRenewalInterval) { // Cert is still valid, don't do anything. @@ -538,6 +556,7 @@ func (this *CertCache) updateCertIfNecessary() { log.Println("Error trying to fetch new certificates from CA: ", err) return } + // TODO(banaag): save this cert to disk. this.setNewCerts(certs) } } diff --git a/packager/certcache/certcache_test.go b/packager/certcache/certcache_test.go index c38ca2771..b3814b364 100644 --- a/packager/certcache/certcache_test.go +++ b/packager/certcache/certcache_test.go @@ -74,7 +74,8 @@ type CertCacheSuite struct { func (this *CertCacheSuite) New() (*CertCache, error) { // TODO(twifkak): Stop the old CertCache's goroutine. - // TODO(banaag): Set certfetcher. + // TODO(banaag): Consider adding a test with certfetcher set. + // For now, this tests certcache without worrying about certfetcher. certCache := New(pkgt.B3Certs, nil, filepath.Join(this.tempDir, "ocsp")) certCache.extractOCSPServer = func(*x509.Certificate) (string, error) { return this.ocspServer.URL, nil From da284318ff11c83968ea54cb0b172317c20dbb9c Mon Sep 17 00:00:00 2001 From: Allan Banaag Date: Wed, 18 Sep 2019 12:12:21 -0700 Subject: [PATCH 03/22] Fix build errors in last commit. --- cmd/gateway_server/go.mod | 11 +++++++++ cmd/gateway_server/go.sum | 45 ++++++++++++++++++++++++++++++++++++ cmd/gateway_server/server.go | 2 +- 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 cmd/gateway_server/go.sum diff --git a/cmd/gateway_server/go.mod b/cmd/gateway_server/go.mod index e69de29bb..b140cade6 100644 --- a/cmd/gateway_server/go.mod +++ b/cmd/gateway_server/go.mod @@ -0,0 +1,11 @@ +module github.com/ampproject/amppackager/cmd/gateway_server + +go 1.13 + +require ( + github.com/WICG/webpackage v0.0.0-20190904045429-ab0e18a2113c // indirect + github.com/ampproject/amppackager v0.0.0-20190911170541-c9993b8ac4d1 // indirect + github.com/golang/protobuf v1.3.2 // indirect + golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 // indirect + google.golang.org/grpc v1.23.1 // indirect +) diff --git a/cmd/gateway_server/go.sum b/cmd/gateway_server/go.sum new file mode 100644 index 000000000..2519f92a7 --- /dev/null +++ b/cmd/gateway_server/go.sum @@ -0,0 +1,45 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/WICG/webpackage v0.0.0-20190904045429-ab0e18a2113c h1:z+hJKXGCAdk9H/JKAmACY2bKyLhAInkjMh/VVlKNxEI= +github.com/WICG/webpackage v0.0.0-20190904045429-ab0e18a2113c/go.mod h1:RmCSqjSsrBtTrYiO+OKMBfMgztnTnFXVSapi/mNB7IA= +github.com/ampproject/amppackager v0.0.0-20190911170541-c9993b8ac4d1 h1:vwqF8hQdUaCP6u9FzVXwwFKJ+5kdQDOkp2vYlTbTSGE= +github.com/ampproject/amppackager v0.0.0-20190911170541-c9993b8ac4d1/go.mod h1:kqUX/cvxB07nOtlh8/35T4sXNOos7/kqOJTN34XAvF8= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/influxdata/influxdb v1.6.3/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/mrichman/hargo v0.1.2-0.20190117125451-162adce4527e/go.mod h1:ycD51zRGXcO6ak4DnFPjHv4xzbgRU5tYyWDzbMzFYKw= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20190110200230-915654e7eabc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/cmd/gateway_server/server.go b/cmd/gateway_server/server.go index 535950d60..0b0c6e8da 100644 --- a/cmd/gateway_server/server.go +++ b/cmd/gateway_server/server.go @@ -74,7 +74,7 @@ func (s *gatewayServer) GenerateSXG(ctx context.Context, request *pb.SXGRequest) } // Note: do not initialize certCache, we just want it to hold the certs for now. - certCache := certcache.New(certs, ""); + certCache := certcache.New(certs, nil, ""); privateKey, err := util.ParsePrivateKey(request.PrivateKey) if err != nil { From 53252cefb3d9bc89167682e81be141f0b3e270bd Mon Sep 17 00:00:00 2001 From: Allan Banaag Date: Wed, 18 Sep 2019 13:10:41 -0700 Subject: [PATCH 04/22] Add config file error checking for PopulateCertCache. --- packager/certloader/certloader.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packager/certloader/certloader.go b/packager/certloader/certloader.go index a38860a9d..52255dcc7 100644 --- a/packager/certloader/certloader.go +++ b/packager/certloader/certloader.go @@ -48,12 +48,41 @@ func PopulateCertCache(config *util.Config, key crypto.PrivateKey, certFetcher := (*certfetcher.CertFetcher)(nil) if autoRenewCert { + if config.ACMEConfig == nil { + return nil, errors.New("missing ACMEConfig") + } + if config.ACMEConfig.Production == nil { + return nil, errors.New("missing ACMEConfig.Production") + } + if config.ACMEConfig.Production.EmailAddress == "" { + return nil, errors.New("missing email address") + } emailAddress := config.ACMEConfig.Production.EmailAddress + if config.ACMEConfig.Production.DiscoURL == "" { + return nil, errors.New("missing acme disco url") + } acmeDiscoveryURL := config.ACMEConfig.Production.DiscoURL + if config.ACMEConfig.Production.ChallengePort == 0 { + return nil, errors.New("missing challenge port") + } challengePort := config.ACMEConfig.Production.ChallengePort if developmentMode { + if config.ACMEConfig.Development == nil { + return nil, errors.New("missing ACMEConfig.Development") + } + if config.ACMEConfig.Development.EmailAddress == "" { + return nil, errors.New("missing email address") + } emailAddress = config.ACMEConfig.Development.EmailAddress + + if config.ACMEConfig.Development.DiscoURL == "" { + return nil, errors.New("missing acme disco url") + } acmeDiscoveryURL = config.ACMEConfig.Development.DiscoURL + + if config.ACMEConfig.Development.ChallengePort == 0 { + return nil, errors.New("missing challenge port") + } challengePort = config.ACMEConfig.Development.ChallengePort } From 848dbff735b99e34495804e63d2fa1fd0592300c Mon Sep 17 00:00:00 2001 From: Allan Banaag Date: Wed, 18 Sep 2019 14:33:51 -0700 Subject: [PATCH 05/22] Add more logic to handle initial conditions with invalid cert and to address comments from gregable@. --- packager/certcache/certcache.go | 17 ++++++++++++----- packager/certloader/certloader.go | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packager/certcache/certcache.go b/packager/certcache/certcache.go index 54fdacc54..81835c719 100644 --- a/packager/certcache/certcache.go +++ b/packager/certcache/certcache.go @@ -55,7 +55,7 @@ const OcspCheckInterval = 1 * time.Hour // How often to check if certs needs updating. const CertCheckInterval = 24 * time.Hour -// Recommended renewal duration for certs. +// Recommended renewal duration for certs. This is duration before next cert expiry. // 8 days is recommended duration to start requesting new certs to allow for ACME server outages. // It's 6 days + 2 days renewal grace period. // TODO(banaag): make 2 days renewal grace period configurable in toml. @@ -129,6 +129,8 @@ func New(certs []*x509.Certificate, certFetcher *certfetcher.CertFetcher, ocspCa } func (this *CertCache) Init(stop chan struct{}) error { + this.updateCertIfNecessary() + // Prime the OCSP disk and memory cache, so we can start serving immediately. _, _, err := this.readOCSP() if err != nil { @@ -150,12 +152,14 @@ func (this *CertCache) Init(stop chan struct{}) error { } this.isInitialized = true + return nil } -// For now this just returns the first entry in the certs field in the cache. -// For follow-on changes, we will transform this to a lambda so that anything -// that needs a cert can do the cert refresh logic (if needed) on demand. +// Gets the latest cert. +// Returns the current cert if the cache has not been initialized or if the certFetcher is not set (good for testing) +// If cert is invalid, it will attempt to renew. +// If cert is still valid, returns the current cert. func (this *CertCache) GetLatestCert() (*x509.Certificate) { if !this.isInitialized || this.certFetcher == nil { // If certcache is not initialized or certFetcher is not set, @@ -166,7 +170,8 @@ func (this *CertCache) GetLatestCert() (*x509.Certificate) { if err != nil { // Current cert is already invalid. Check if renewal is available. log.Println("Current cert is expired, attempting to renew.") - return nil + this.updateCertIfNecessary() + return this.certs[0] } if d >= time.Duration(CertRenewalInterval) { // Cert is still valid. @@ -521,8 +526,10 @@ func (this *CertCache) setNewCerts(certs []*x509.Certificate) { // Update the cert in the cache if necessary. func (this *CertCache) updateCertIfNecessary() { + log.Println("Updating cert if necessary"); if this.certFetcher == nil { // Do nothing if certFetcher is not set. + log.Println("Certfetcher is not set, skipping cert updates."); return } d, err := util.GetDurationToExpiry(this.certs[0], this.certs[0].NotAfter) diff --git a/packager/certloader/certloader.go b/packager/certloader/certloader.go index 52255dcc7..b879f2243 100644 --- a/packager/certloader/certloader.go +++ b/packager/certloader/certloader.go @@ -92,6 +92,7 @@ func PopulateCertCache(config *util.Config, key crypto.PrivateKey, if err != nil { return nil, errors.Wrap(err, "creating certfetcher") } + log.Println("Certfetcher created successfully.") } certCache := certcache.New(certs, certFetcher, config.OCSPCache) From bfd3a6d6685917f049e48a01010308e3b9b384df Mon Sep 17 00:00:00 2001 From: Allan Banaag Date: Mon, 23 Sep 2019 09:58:57 -0700 Subject: [PATCH 06/22] Code refactor/cleanup involving certs. --- packager/certcache/certcache.go | 52 ++++++++++++++----- packager/certfetcher/certfetcher.go | 5 ++ packager/certloader/certloader.go | 11 ++-- .../lego/v3/certificate/certificates.go | 3 ++ 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/packager/certcache/certcache.go b/packager/certcache/certcache.go index 81835c719..7d675e85e 100644 --- a/packager/certcache/certcache.go +++ b/packager/certcache/certcache.go @@ -93,8 +93,12 @@ type CertCache struct { // Callers can use the uninitialized CertCache either for testing certificates (without doing OCSP or // cert refreshes). func New(certs []*x509.Certificate, certFetcher *certfetcher.CertFetcher, ocspCache string) *CertCache { + certName := "" + if len(certs) > 0 && certs[0] != nil { + certName = util.CertName(certs[0]) + } return &CertCache{ - certName: util.CertName(certs[0]), + certName: certName, certs: certs, certFetcher: certFetcher, ocspUpdateAfter: infiniteFuture, // Default, in case initial readOCSP successfully loads from disk. @@ -110,7 +114,7 @@ func New(certs []*x509.Certificate, certFetcher *certfetcher.CertFetcher, ocspCa ocspFile: &Chained{first: &InMemory{}, second: &LocalFile{path: ocspCache}}, client: http.Client{Timeout: 60 * time.Second}, extractOCSPServer: func(cert *x509.Certificate) (string, error) { - if len(cert.OCSPServer) < 1 { + if cert == nil || len(cert.OCSPServer) < 1 { return "", errors.New("Cert missing OCSPServer.") } // This is a URI, per https://tools.ietf.org/html/rfc5280#section-4.2.2.1. @@ -164,22 +168,27 @@ func (this *CertCache) GetLatestCert() (*x509.Certificate) { if !this.isInitialized || this.certFetcher == nil { // If certcache is not initialized or certFetcher is not set, // just return cert without checking if it needs auto-renewal. - return this.certs[0] + return this.getCert() + } + + if !this.hasCert() { + return nil } + d, err := util.GetDurationToExpiry(this.certs[0], this.certs[0].NotAfter) if err != nil { // Current cert is already invalid. Check if renewal is available. log.Println("Current cert is expired, attempting to renew.") this.updateCertIfNecessary() - return this.certs[0] + return this.getCert() } if d >= time.Duration(CertRenewalInterval) { // Cert is still valid. - return this.certs[0] + return this.getCert() } else if d < time.Duration(CertRenewalInterval) { // Cert is still valid, but we need to start process of requesting new cert. log.Println("Current cert is close to expiry threshold, attempting to renew in the background.") - return this.certs[0] + return this.getCert() } return nil } @@ -200,7 +209,7 @@ func (this *CertCache) createCertChainCBOR(ocsp []byte) ([]byte, error) { } func (this *CertCache) ocspMidpoint(bytes []byte, issuer *x509.Certificate) (time.Time, error) { - resp, err := ocsp.ParseResponseForCert(bytes, this.certs[0], issuer) + resp, err := ocsp.ParseResponseForCert(bytes, this.getCert(), issuer) if err != nil { return time.Time{}, errors.Wrap(err, "Parsing OCSP") } @@ -267,7 +276,7 @@ func (this *CertCache) isHealthy(ocspResp []byte) bool { log.Println("Cannot find issuer certificate in CertFile.") return false } - resp, err := ocsp.ParseResponseForCert(ocspResp, this.certs[0], issuer) + resp, err := ocsp.ParseResponseForCert(ocspResp, this.getCert(), issuer) if err != nil { log.Println("Error parsing OCSP response:", err) return false @@ -374,6 +383,9 @@ func (this *CertCache) shouldUpdateOCSP(bytes []byte) bool { // Finds the issuer of this cert (i.e. the second from the bottom of the // chain). func (this *CertCache) findIssuer() *x509.Certificate { + if !this.hasCert() { + return nil + } issuerName := this.certs[0].Issuer for _, cert := range this.certs { // The subject name is guaranteed to match the issuer name per @@ -406,13 +418,13 @@ func (this *CertCache) fetchOCSP(orig []byte, ocspUpdateAfter *time.Time) []byte // The default SHA1 hash function is mandated by the Lightweight OCSP // Profile, https://tools.ietf.org/html/rfc5019 2.1.1 (sleevi #4, see above). - req, err := ocsp.CreateRequest(this.certs[0], issuer, nil) + req, err := ocsp.CreateRequest(this.getCert(), issuer, nil) if err != nil { log.Println("Error creating OCSP request:", err) return orig } - ocspServer, err := this.extractOCSPServer(this.certs[0]) + ocspServer, err := this.extractOCSPServer(this.getCert()) if err != nil { log.Println("Error extracting OCSP server:", err) return orig @@ -465,7 +477,7 @@ func (this *CertCache) fetchOCSP(orig []byte, ocspUpdateAfter *time.Time) []byte // 2. Validate the server responses to make sure it is something the client will accept. // and also per sleevi #4 (see above), as required by // https://tools.ietf.org/html/rfc5019#section-2.2.2. - resp, err := ocsp.ParseResponseForCert(respBytes, this.certs[0], issuer) + resp, err := ocsp.ParseResponseForCert(respBytes, this.getCert(), issuer) if err != nil { log.Println("Error parsing OCSP response:", err) return orig @@ -510,6 +522,18 @@ func (this *CertCache) maintainCerts(stop chan struct{}) { } } +// Returns true iff cert cache contains at least 1 cert. +func (this *CertCache) hasCert() bool { + return len(this.certs) > 0 && this.certs[0] != nil +} + +func (this *CertCache) getCert() *x509.Certificate { + if !this.hasCert() { + return nil + } + return this.certs[0] +} + // Set current cert with mutex protection. func (this *CertCache) setCerts(certs []*x509.Certificate) { this.certsMu.Lock() @@ -532,7 +556,11 @@ func (this *CertCache) updateCertIfNecessary() { log.Println("Certfetcher is not set, skipping cert updates."); return } - d, err := util.GetDurationToExpiry(this.certs[0], this.certs[0].NotAfter) + d := time.Duration(0) + err := errors.New("") + if this.hasCert() { + d, err = util.GetDurationToExpiry(this.certs[0], this.certs[0].NotAfter) + } if err != nil { if this.renewedCerts != nil { // If renewedCerts is set, copy that over to certs diff --git a/packager/certfetcher/certfetcher.go b/packager/certfetcher/certfetcher.go index 87e08a2e1..3a3181724 100644 --- a/packager/certfetcher/certfetcher.go +++ b/packager/certfetcher/certfetcher.go @@ -23,6 +23,7 @@ import ( "github.com/go-acme/lego/v3/certcrypto" "github.com/go-acme/lego/v3/certificate" "github.com/go-acme/lego/v3/challenge/http01" + "github.com/go-acme/lego/v3/challenge/tlsalpn01" "github.com/go-acme/lego/v3/lego" "github.com/go-acme/lego/v3/registration" "github.com/pkg/errors" @@ -80,6 +81,10 @@ func NewFetcher(email string, privateKey crypto.PrivateKey, acmeDiscoURL string, if err != nil { return nil, errors.Wrap(err, "Setting up HTTP01 challenge provider.") } + err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "5001")) + if err != nil { + return nil, errors.Wrap(err, "Setting up TLSALPN01 challenge provider.") + } // Theoretically, this should always be set to false as users should have pre-registered for access // to the ACME CA and agreed to the TOS. diff --git a/packager/certloader/certloader.go b/packager/certloader/certloader.go index b879f2243..c35f169e3 100644 --- a/packager/certloader/certloader.go +++ b/packager/certloader/certloader.go @@ -36,13 +36,16 @@ func PopulateCertCache(config *util.Config, key crypto.PrivateKey, certs, err := loadCertsFromFile(config, developmentMode) if err != nil { - return nil, err + log.Println(errors.Wrap(err, "Can't load cert file.")) + certs = nil } domain := "" for _, urlSet := range config.URLSet { domain = urlSet.Sign.Domain - if err := util.CertificateMatches(certs[0], key, domain); err != nil { - return nil, errors.Wrapf(err, "checking %s", config.CertFile) + if certs != nil { + if err := util.CertificateMatches(certs[0], key, domain); err != nil { + return nil, errors.Wrapf(err, "checking %s", config.CertFile) + } } } @@ -88,7 +91,7 @@ func PopulateCertCache(config *util.Config, key crypto.PrivateKey, // Create the cert fetcher that will auto-renew the cert. certFetcher, err = certfetcher.NewFetcher(emailAddress, key, acmeDiscoveryURL, - []string{domain}, challengePort, !developmentMode) + []string{domain}, challengePort, true) if err != nil { return nil, errors.Wrap(err, "creating certfetcher") } diff --git a/vendor/github.com/go-acme/lego/v3/certificate/certificates.go b/vendor/github.com/go-acme/lego/v3/certificate/certificates.go index 8f54a58ca..5269ef7d2 100644 --- a/vendor/github.com/go-acme/lego/v3/certificate/certificates.go +++ b/vendor/github.com/go-acme/lego/v3/certificate/certificates.go @@ -120,9 +120,12 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) { log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", ")) + log.Infof("acme: order = ", order) + failures := make(obtainError) cert, err := c.getForOrder(domains, order, request.Bundle, request.PrivateKey, request.MustStaple) if err != nil { + log.Infof("acme: error = ", err) for _, auth := range authz { failures[challenge.GetTargetedDomain(auth)] = err } From 058fdff5d692ebd681dd2249db4624186db03238 Mon Sep 17 00:00:00 2001 From: Allan Banaag Date: Fri, 27 Sep 2019 10:41:00 -0700 Subject: [PATCH 07/22] Add DNS and TLS challenges, added them to load from config, cleaned up autorenewcert config parsing. --- go.sum | 81 ++++ packager/certcache/certcache.go | 12 + packager/certfetcher/certfetcher.go | 65 ++- packager/certfetcher/certfetcher_test.go | 6 +- packager/certloader/certloader.go | 47 ++- packager/util/config.go | 14 +- packager/util/config_test.go | 20 +- .../lego/v3/certificate/certificates.go | 3 - vendor/modules.txt | 382 ++++++++++++++++++ 9 files changed, 591 insertions(+), 39 deletions(-) diff --git a/go.sum b/go.sum index fb7429f31..3affd96f5 100644 --- a/go.sum +++ b/go.sum @@ -1,71 +1,102 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc= contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= +github.com/Azure/azure-sdk-for-go v32.4.0+incompatible h1:1JP8SKfroEakYiQU2ZyPDosh8w2Tg9UopKt88VyQPt4= github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg= +github.com/Azure/go-autorest/autorest v0.5.0 h1:Mlm9qy2fpQ9MvfyI41G2Zf5B4CsgjjNbLOWszfK6KrY= github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw= github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= +github.com/Azure/go-autorest/autorest/adal v0.2.0 h1:7IBDu1jgh+ADHXnEYExkV9RE/ztOOlxdACkkPRthGKw= github.com/Azure/go-autorest/autorest/adal v0.2.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= +github.com/Azure/go-autorest/autorest/azure/auth v0.1.0 h1:YgO/vSnJEc76NLw2ecIXvXa8bDWiqf1pOJzARAoZsYU= github.com/Azure/go-autorest/autorest/azure/auth v0.1.0/go.mod h1:Gf7/i2FUpyb/sGBLIFxTBzrNzBo7aPXXE3ZVeDRwdpM= +github.com/Azure/go-autorest/autorest/azure/cli v0.1.0 h1:YTtBrcb6mhA+PoSW8WxFDoIIyjp13XqJeX80ssQtri4= github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U= +github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/to v0.2.0 h1:nQOZzFCudTh+TvquAtCRjM01VEYx85e9qbwt5ncW4L8= github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= +github.com/Azure/go-autorest/autorest/validation v0.1.0 h1:ISSNzGUh+ZSzizJWOWzs8bwpXIePbGLW4z/AmUFGH5A= github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc= github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/WICG/webpackage v0.0.0-20190215052515-70386c3750f2 h1:IJIQQSysq7xk5oO0/6fbYZY0ZLz/KMM+k63ZrJphef8= github.com/WICG/webpackage v0.0.0-20190215052515-70386c3750f2/go.mod h1:RmCSqjSsrBtTrYiO+OKMBfMgztnTnFXVSapi/mNB7IA= +github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.0 h1:rXPPPxDA4GCPN0YWwyVHMzcxVpVg8gai2uGhJ3VqOSs= github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.0/go.mod h1:zpDJeKyp9ScW4NNrbdr+Eyxvry3ilGPewKoXw3XGN1k= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee h1:NYqDBPkhVYt68W3yoGoRRi32i3MLx2ey7SFkJ1v/UI0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/ampproject/amphtml v0.0.0-20180912232012-d3df64d07ae9 h1:0Du3+SEeaZ0yE4G1clQf8npsZUpf2ySFekYfoq2uNZM= github.com/ampproject/amphtml v0.0.0-20180912232012-d3df64d07ae9/go.mod h1:VdGPUI5OhDH1JDFyOSvCz3x2Ap3YmdLvJ0QboKqoc1c= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/aws/aws-sdk-go v1.23.0 h1:ilfJN/vJtFo1XDFxB2YMBYGeOvGZl6Qow17oyD4+Z9A= github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cloudflare-go v0.10.0 h1:wJPNqfrQO0w3fCiQcf/2T4lR2y6Q2fAwRszllljgb8I= github.com/cloudflare/cloudflare-go v0.10.0/go.mod h1:fOESqHl/jzAmCtEyjceLkw3v0rVjzl8V9iehxZPynXY= +github.com/cpu/goacmedns v0.0.1 h1:GeIU5chKys9zmHgOAgP+bstRaLqcGQ6HJh/hLw9hrus= github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decker502/dnspod-go v0.2.0 h1:6dwhUFCYbC5bgpebLKn7PrI43e/5mn9tpUL9YcYCdTU= github.com/decker502/dnspod-go v0.2.0/go.mod h1:qsurYu1FgxcDwfSwXJdLt4kRsBLZeosEb9uq4Sy+08g= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2 h1:G9/PqfhOrt8JXnw0DGTfVoOkKHDhOlEZqhE/cu+NvQM= github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/dnsimple/dnsimple-go v0.30.0 h1:IBIrn9jMKRMwporIRwdFyKdnHXVmwy6obnguB+ZMDIY= github.com/dnsimple/dnsimple-go v0.30.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/exoscale/egoscale v0.18.1 h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9EZaI= github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-acme/lego/v3 v3.0.2 h1:cnS+URiPzkt2pd7I2WlZtFyt2ihQ762nouBybY4djjw= github.com/go-acme/lego/v3 v3.0.2/go.mod h1:sMoLjf8BUo4Jexg+6Xw5KeFx98KVZ7Nfczh9tzLyhJU= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-ini/ini v1.44.0 h1:8+SRbfpRFlIunpSum4BEf1ClTtVjOgKzgBv9pHFkI6w= github.com/go-ini/ini v1.44.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -78,32 +109,46 @@ github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gophercloud/gophercloud v0.3.0 h1:6sjpKIpVwRIIwmcEGp+WwNovNsem+c+2vm6oxshRpL8= github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df h1:MZf03xP9WdakyXhOWuAD5uPK3wHh96wCsqe3hCMKh8E= github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4= github.com/influxdata/influxdb v1.6.3/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181 h1:TrxPzApUukas24OMMVDUMlCs1XCExJtnGaDEiIAR4oQ= github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -111,8 +156,11 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/labbsr0x/bindman-dns-webhook v1.0.0 h1:gooRvyQtVOCtV/l9ZCI4CManZeVN/kUWG/vugRqHqv4= github.com/labbsr0x/bindman-dns-webhook v1.0.0/go.mod h1:pn4jcNjxSywRWDPDyGkFzgSnwty18OFdiUFc6S6fpgc= +github.com/labbsr0x/goh v0.0.0-20190417202808-8b16b4848295 h1:5hXo89CXm3J5yyggBT3FJL4dN2gcfwxWwg0vXKiErSk= github.com/labbsr0x/goh v0.0.0-20190417202808-8b16b4848295/go.mod h1:RBxeaayaaMmp7GxwHiKANjkg9e+rxjOm4mB5vD5rt/I= +github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM= github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -121,24 +169,35 @@ github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4f github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.15 h1:CSSIDtllwGLMoA6zjdKnaE6Tx6eVUxQ29LUgGetiDCI= github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mrichman/hargo v0.1.2-0.20190117125451-162adce4527e/go.mod h1:ycD51zRGXcO6ak4DnFPjHv4xzbgRU5tYyWDzbMzFYKw= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g= github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= +github.com/nrdcg/auroradns v1.0.0 h1:b+NpSqNG6HzMqX2ohGQe4Q/G0WQq8pduWCiZ19vdLY8= github.com/nrdcg/auroradns v1.0.0/go.mod h1:6JPXKzIRzZzMqtTDgueIhTi6rFf1QvYE/HzqidhOhjw= +github.com/nrdcg/goinwx v0.6.1 h1:AJnjoWPELyCtofhGcmzzcEMFd9YdF2JB/LgutWsWt/s= github.com/nrdcg/goinwx v0.6.1/go.mod h1:XPiut7enlbEdntAqalBIqcYcTEVhpv/dKWgDCX2SwKQ= +github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg= github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/oracle/oci-go-sdk v7.0.0+incompatible h1:oj5ESjXwwkFRdhZSnPlShvLWYdt/IZ65RQxveYM3maA= github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 h1:37VE5TYj2m/FLA9SNr4z0+A0JefvTmR60Zwf8XSEV7c= github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ= github.com/pelletier/go-toml v1.1.0 h1:cmiOvKzEunMsAxyhXSzpL5Q1CRKpVv0KQsnAIcSEVYM= github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -161,31 +220,43 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/sacloud/libsacloud v1.26.1 h1:td3Kd7lvpSAxxHEVpnaZ9goHmmhi0D/RfP0Rqqf/kek= github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8= github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY= +github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f h1:clyOmELPZd2LuFEyuo1mP6RXpbAW75PwD+RfDj4kBm0= github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY= +github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 h1:EICbibRW4JNKMcY+LsWmuwob+CRS1BmdRdjphAm9mH4= github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= +github.com/vultr/govultr v0.1.4 h1:UnNMixYFVO0p80itc8PcweoVENyo1PasfvwKhoasR9U= github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277 h1:d9qaMM+ODpCq+9We41//fu/sHsTnXcrqd1en3x+GKy4= go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y= golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac h1:7d7lG9fHOLdL6jZPtnV4LpI41SbohIJ1Atq7U991dMg= golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -199,6 +270,7 @@ golang.org/x/net v0.0.0-20180808004115-f9ce57c11b24 h1:mEsFm194MmS9vCwxFy+zwu0EU golang.org/x/net v0.0.0-20180808004115-f9ce57c11b24/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -221,6 +293,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -231,17 +304,21 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -249,11 +326,15 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0= gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.44.0 h1:YRJzTUp0kSYWUVFF5XAbDFfyiqwsl0Vb9R8TVP5eRi0= gopkg.in/ini.v1 v1.44.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc h1:GAcf+t0o8gdJAdSFYdE9wChu4bIyguMVqz0RHiFL5VY= gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc/go.mod h1:VV+3haRsgDiVLxyifmMBrBIuCWFBPYKbRssXB9z67Hw= gopkg.in/resty.v1 v1.9.1/go.mod h1:vo52Hzryw9PnPHcJfPsBiFW62XhNx5OczbV9y+IMpgc= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.3.1 h1:SK5KegNXmKmqE342YYN2qPHEnUYeoMiXXl1poUlI+o4= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= diff --git a/packager/certcache/certcache.go b/packager/certcache/certcache.go index 7d675e85e..36dcb75ef 100644 --- a/packager/certcache/certcache.go +++ b/packager/certcache/certcache.go @@ -276,6 +276,7 @@ func (this *CertCache) isHealthy(ocspResp []byte) bool { log.Println("Cannot find issuer certificate in CertFile.") return false } +log.Println("ocspResp = ", ocspResp) resp, err := ocsp.ParseResponseForCert(ocspResp, this.getCert(), issuer) if err != nil { log.Println("Error parsing OCSP response:", err) @@ -384,9 +385,11 @@ func (this *CertCache) shouldUpdateOCSP(bytes []byte) bool { // chain). func (this *CertCache) findIssuer() *x509.Certificate { if !this.hasCert() { +log.Println("Issuer was nil") return nil } issuerName := this.certs[0].Issuer +log.Println("Issuer name is ", issuerName) for _, cert := range this.certs { // The subject name is guaranteed to match the issuer name per // https://tools.ietf.org/html/rfc3280#section-4.1.2.4 and @@ -402,9 +405,11 @@ func (this *CertCache) findIssuer() *x509.Certificate { // https://tools.ietf.org/html/rfc1779 which has many forms), // such that comparing the two strings should be sufficient. if cert.Subject.String() == issuerName.String() { +log.Println("Found issuer cert.") return cert } } +log.Println("NOT Found issuer cert.") return nil } @@ -423,12 +428,14 @@ func (this *CertCache) fetchOCSP(orig []byte, ocspUpdateAfter *time.Time) []byte log.Println("Error creating OCSP request:", err) return orig } +log.Println("req = ", req) ocspServer, err := this.extractOCSPServer(this.getCert()) if err != nil { log.Println("Error extracting OCSP server:", err) return orig } +log.Println("ocspServer = ", ocspServer) // Conform to the Lightweight OCSP Profile, by preferring GET over POST // if the request is small enough (sleevi #4, see above). @@ -438,6 +445,8 @@ func (this *CertCache) fetchOCSP(orig []byte, ocspUpdateAfter *time.Time) []byte // the base64 encoding includes '/' and '=' (and therefore should be // StdEncoding). getURL := ocspServer + "/" + url.PathEscape(base64.StdEncoding.EncodeToString(req)) +log.Println("getURL = ", getURL) + var httpReq *http.Request if len(getURL) <= 255 { httpReq, err = http.NewRequest("GET", getURL, nil) @@ -469,6 +478,7 @@ func (this *CertCache) fetchOCSP(orig []byte, ocspUpdateAfter *time.Time) []byte *ocspUpdateAfter = this.httpExpiry(httpReq, httpResp) respBytes, err := ioutil.ReadAll(io.LimitReader(httpResp.Body, 1024*1024)) +log.Println("respBytes = ", respBytes) if err != nil { log.Println("Error reading OCSP response:", err) return orig @@ -478,6 +488,7 @@ func (this *CertCache) fetchOCSP(orig []byte, ocspUpdateAfter *time.Time) []byte // and also per sleevi #4 (see above), as required by // https://tools.ietf.org/html/rfc5019#section-2.2.2. resp, err := ocsp.ParseResponseForCert(respBytes, this.getCert(), issuer) +log.Println("resp = ", resp) if err != nil { log.Println("Error parsing OCSP response:", err) return orig @@ -539,6 +550,7 @@ func (this *CertCache) setCerts(certs []*x509.Certificate) { this.certsMu.Lock() defer this.certsMu.Unlock() this.certs = certs + this.certName = util.CertName(certs[0]) } // Set new cert with mutex protection. diff --git a/packager/certfetcher/certfetcher.go b/packager/certfetcher/certfetcher.go index 3a3181724..279e6032d 100644 --- a/packager/certfetcher/certfetcher.go +++ b/packager/certfetcher/certfetcher.go @@ -17,14 +17,17 @@ package certfetcher import ( "crypto" "crypto/x509" + "encoding/pem" + "io/ioutil" "strconv" "github.com/WICG/webpackage/go/signedexchange" "github.com/go-acme/lego/v3/certcrypto" - "github.com/go-acme/lego/v3/certificate" "github.com/go-acme/lego/v3/challenge/http01" "github.com/go-acme/lego/v3/challenge/tlsalpn01" "github.com/go-acme/lego/v3/lego" + "github.com/go-acme/lego/v3/providers/dns" + "github.com/go-acme/lego/v3/providers/http/webroot" "github.com/go-acme/lego/v3/registration" "github.com/pkg/errors" ) @@ -55,8 +58,9 @@ func (u *AcmeUser) GetPrivateKey() crypto.PrivateKey { } // Initializes the cert fetcher with information it needs to fetch new certificates in the future. -func NewFetcher(email string, privateKey crypto.PrivateKey, acmeDiscoURL string, - domains []string, acmeChallengePort int, shouldRegister bool) (*CertFetcher, error) { +func NewFetcher(email string, privateKey crypto.PrivateKey, acmeDiscoURL string, domains []string, + httpChallengePort int, httpChallengeWebRoot string, tlsChallengePort int, dnsProvider string, + shouldRegister bool) (*CertFetcher, error) { acmeUser := AcmeUser{ Email: email, key: privateKey, @@ -72,18 +76,44 @@ func NewFetcher(email string, privateKey crypto.PrivateKey, acmeDiscoURL string, return nil, errors.Wrap(err, "Obtaining LEGO client.") } - // We specify an http port of `acmeChallengePort` + // We specify an http port of `httpChallengePort` // because we aren't running as root and can't bind a listener to port 80 and 443 // (used later when we attempt to pass challenges). Keep in mind that you still // need to proxy challenge traffic to port `acmeChallengePort`. - err = client.Challenge.SetHTTP01Provider( - http01.NewProviderServer("", strconv.Itoa(acmeChallengePort))) - if err != nil { - return nil, errors.Wrap(err, "Setting up HTTP01 challenge provider.") + if httpChallengePort != 0 { + err = client.Challenge.SetHTTP01Provider( + http01.NewProviderServer("", strconv.Itoa(httpChallengePort))) + if err != nil { + return nil, errors.Wrap(err, "Setting up HTTP01 challenge provider.") + } } - err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "5001")) - if err != nil { - return nil, errors.Wrap(err, "Setting up TLSALPN01 challenge provider.") + if httpChallengeWebRoot != "" { + httpProvider, err := webroot.NewHTTPProvider(httpChallengeWebRoot) + if err != nil { + return nil, errors.Wrap(err, "Getting HTTP01 challenge provider.") + } + err = client.Challenge.SetHTTP01Provider(httpProvider) + if err != nil { + return nil, errors.Wrap(err, "Setting up HTTP01 challenge provider.") + } + } + + if tlsChallengePort != 0 { + err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", strconv.Itoa(tlsChallengePort))) + if err != nil { + return nil, errors.Wrap(err, "Setting up TLSALPN01 challenge provider.") + } + } + + if dnsProvider != "" { + provider, err := dns.NewDNSChallengeProviderByName(dnsProvider) + if err != nil { + return nil, errors.Wrap(err, "Getting DNS01 challenge provider.") + } + err = client.Challenge.SetDNS01Provider(provider) + if err != nil { + return nil, errors.Wrap(err, "Setting up DNS01 challenge provider.") + } } // Theoretically, this should always be set to false as users should have pre-registered for access @@ -112,14 +142,19 @@ func NewFetcher(email string, privateKey crypto.PrivateKey, acmeDiscoURL string, } func (f *CertFetcher) FetchNewCert() ([]*x509.Certificate, error) { - request := certificate.ObtainRequest{ - Domains: f.Domains, - Bundle: true, + data, err := ioutil.ReadFile("/usr/local/google/home/banaag/go/cert/server.csr") + if err != nil { + return nil, err + } + block, _ := pem.Decode(data) + if block == nil { + return nil, errors.New("pem decode: no key found") } + csr, _ := x509.ParseCertificateRequest(block.Bytes) // Each resource comes back with the cert bytes, the bytes of the client's // private key, and a certificate URL. - resource, err := f.legoClient.Certificate.Obtain(request) + resource, err := f.legoClient.Certificate.ObtainForCSR(*csr, true) if err != nil { return nil, err } diff --git a/packager/certfetcher/certfetcher_test.go b/packager/certfetcher/certfetcher_test.go index 2fc6450f5..189b2503a 100644 --- a/packager/certfetcher/certfetcher_test.go +++ b/packager/certfetcher/certfetcher_test.go @@ -80,7 +80,7 @@ func TestNewFetcher(t *testing.T) { require.NoError(t, err, "Could not generate test key") fetcher, err := NewFetcher("test@test.com", privateKey, apiURL+"/dir", - []string{"example.com"}, 5002, false) + []string{"example.com"}, 5002, "", 0, "", false) assert.Nil(t, err) assert.NotNil(t, fetcher.legoClient) assert.Equal(t, "test@test.com", fetcher.AcmeUser.Email) @@ -103,7 +103,7 @@ func TestFetchCertSuccess(t *testing.T) { }) fetcher, err := NewFetcher("test@test.com", privateKey, apiURL+"/dir", - []string{"example.com"}, 5002, false) + []string{"example.com"}, 5002, "", 0, "", false) assert.Nil(t, err) assert.NotNil(t, fetcher) @@ -126,7 +126,7 @@ func TestFetchCertFail(t *testing.T) { }) fetcher, err := NewFetcher("test@test.com", privateKey, apiURL+"/dir", - []string{"example.com"}, 5002, false) + []string{"example.com"}, 5002, "", 0, "", false) assert.Nil(t, err) assert.NotNil(t, fetcher) diff --git a/packager/certloader/certloader.go b/packager/certloader/certloader.go index c35f169e3..266787da8 100644 --- a/packager/certloader/certloader.go +++ b/packager/certloader/certloader.go @@ -49,7 +49,17 @@ func PopulateCertCache(config *util.Config, key crypto.PrivateKey, } } - certFetcher := (*certfetcher.CertFetcher)(nil) + certFetcher, err := createCertFetcher(config, key, domain, developmentMode, autoRenewCert) + if err != nil { + return nil, errors.Wrap(err, "creating cert fetcher from config.") + } + certCache := certcache.New(certs, certFetcher, config.OCSPCache) + + return certCache, nil +} + +func createCertFetcher(config *util.Config, key crypto.PrivateKey, domain string, + developmentMode bool, autoRenewCert bool) (*certfetcher.CertFetcher, error) { if autoRenewCert { if config.ACMEConfig == nil { return nil, errors.New("missing ACMEConfig") @@ -65,10 +75,16 @@ func PopulateCertCache(config *util.Config, key crypto.PrivateKey, return nil, errors.New("missing acme disco url") } acmeDiscoveryURL := config.ACMEConfig.Production.DiscoURL - if config.ACMEConfig.Production.ChallengePort == 0 { - return nil, errors.New("missing challenge port") + if (config.ACMEConfig.Production.HttpChallengePort == 0 && + config.ACMEConfig.Production.HttpWebRootDir == "" && + config.ACMEConfig.Production.TlsChallengePort == 0 && + config.ACMEConfig.Production.DnsProvider == "") { + return nil, errors.New("One of HttpChallengePort, HttpWebRootDir, TlsChallengePort and DnsProvider must be present.") } - challengePort := config.ACMEConfig.Production.ChallengePort + httpChallengePort := config.ACMEConfig.Production.HttpChallengePort + httpWebRootDir := config.ACMEConfig.Production.HttpWebRootDir + tlsChallengePort := config.ACMEConfig.Production.TlsChallengePort + dnsProvider := config.ACMEConfig.Production.DnsProvider if developmentMode { if config.ACMEConfig.Development == nil { return nil, errors.New("missing ACMEConfig.Development") @@ -83,24 +99,29 @@ func PopulateCertCache(config *util.Config, key crypto.PrivateKey, } acmeDiscoveryURL = config.ACMEConfig.Development.DiscoURL - if config.ACMEConfig.Development.ChallengePort == 0 { - return nil, errors.New("missing challenge port") + if (config.ACMEConfig.Development.HttpChallengePort == 0 && + config.ACMEConfig.Development.HttpWebRootDir == "" && + config.ACMEConfig.Development.TlsChallengePort == 0 && + config.ACMEConfig.Development.DnsProvider == "") { + return nil, errors.New("One of HttpChallengePort, HttpWebRootDir, TlsChallengePort and DnsProvider must be present.") } - challengePort = config.ACMEConfig.Development.ChallengePort + httpChallengePort = config.ACMEConfig.Development.HttpChallengePort + httpWebRootDir = config.ACMEConfig.Development.HttpWebRootDir + tlsChallengePort = config.ACMEConfig.Development.TlsChallengePort + dnsProvider = config.ACMEConfig.Development.DnsProvider } // Create the cert fetcher that will auto-renew the cert. - certFetcher, err = certfetcher.NewFetcher(emailAddress, key, acmeDiscoveryURL, - []string{domain}, challengePort, true) + certFetcher, err := certfetcher.NewFetcher(emailAddress, key, acmeDiscoveryURL, + []string{domain}, httpChallengePort, httpWebRootDir, tlsChallengePort, dnsProvider, true) if err != nil { return nil, errors.Wrap(err, "creating certfetcher") } log.Println("Certfetcher created successfully.") + return certFetcher, nil } - - certCache := certcache.New(certs, certFetcher, config.OCSPCache) - - return certCache, nil + // Certfetcher can be nil, if auto renew is off. + return nil, nil } // Loads X509 certificates from disk. diff --git a/packager/util/config.go b/packager/util/config.go index 8cb3e26f9..4c8086cb9 100644 --- a/packager/util/config.go +++ b/packager/util/config.go @@ -69,7 +69,19 @@ type ACMEServerConfig struct { AccountURL string // ACME Account URL. If non-empty, we // will auto-renew cert via ACME. EmailAddress string // Email address registered with ACME CA. - ChallengePort int // ACME challenge port. + + // See: https://letsencrypt.org/docs/challenge-types/ + // For non-wildcard domains, only one of HttpChallengePort, HttpWebRootDir or + // TlsChallengePort needs to be present. + // HttpChallengePort means AmpPackager will respond to HTTP challenges via this port. + // HttpWebRootDir means AmpPackager will deposit challenge token in this directory. + // TlsChallengePort means AmpPackager will respond to TLS challenges via this port. + // For wildcard domains, DnsProvider must be set to one of the support LEGO configs: + // https://go-acme.github.io/lego/dns/ + HttpChallengePort int // ACME HTTP challenge port. + HttpWebRootDir string // ACME HTTP web root directory where challenge token will be deposited. + TlsChallengePort int // ACME TLS challenge port. + DnsProvider string // ACME DNS Provider used for challenge. } // TODO(twifkak): Extract default values into a function separate from the one diff --git a/packager/util/config_test.go b/packager/util/config_test.go index 08f79717e..49012b513 100644 --- a/packager/util/config_test.go +++ b/packager/util/config_test.go @@ -215,12 +215,18 @@ func TestOptionalACMEConfig(t *testing.T) { DiscoURL = "prod.disco.url" AccountURL = "prod.account.url" EmailAddress = "prodtest@test.com" - ChallengePort = 777 + HttpChallengePort = 777 + HttpWebRootDir = "web.root.dir" + TlsChallengePort = 333 + DnsProvider = "gcloud" [ACMEConfig.Development] DiscoURL = "dev.disco.url" AccountURL = "dev.account.url" EmailAddress = "devtest@test.com" - ChallengePort = 888 + HttpChallengePort = 888 + HttpWebRootDir = "web.root.dir" + TlsChallengePort = 444 + DnsProvider = "gcloud" `)) require.NoError(t, err) assert.Equal(t, Config{ @@ -233,13 +239,19 @@ func TestOptionalACMEConfig(t *testing.T) { DiscoURL: "prod.disco.url", AccountURL: "prod.account.url", EmailAddress: "prodtest@test.com", - ChallengePort: 777, + HttpChallengePort: 777, + HttpWebRootDir: "web.root.dir", + TlsChallengePort: 333, + DnsProvider: "gcloud", }, Development: &ACMEServerConfig{ DiscoURL: "dev.disco.url", AccountURL: "dev.account.url", EmailAddress: "devtest@test.com", - ChallengePort: 888, + HttpChallengePort: 888, + HttpWebRootDir: "web.root.dir", + TlsChallengePort: 444, + DnsProvider: "gcloud", }, }, URLSet: []URLSet{{ diff --git a/vendor/github.com/go-acme/lego/v3/certificate/certificates.go b/vendor/github.com/go-acme/lego/v3/certificate/certificates.go index 5269ef7d2..8f54a58ca 100644 --- a/vendor/github.com/go-acme/lego/v3/certificate/certificates.go +++ b/vendor/github.com/go-acme/lego/v3/certificate/certificates.go @@ -120,12 +120,9 @@ func (c *Certifier) Obtain(request ObtainRequest) (*Resource, error) { log.Infof("[%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", ")) - log.Infof("acme: order = ", order) - failures := make(obtainError) cert, err := c.getForOrder(domains, order, request.Bundle, request.PrivateKey, request.MustStaple) if err != nil { - log.Infof("acme: error = ", err) for _, auth := range authz { failures[challenge.GetTargetedDomain(auth)] = err } diff --git a/vendor/modules.txt b/vendor/modules.txt index f7c1e880d..de19e5f45 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,3 +1,31 @@ +# cloud.google.com/go v0.38.0 +cloud.google.com/go/compute/metadata +# contrib.go.opencensus.io/exporter/ocagent v0.4.12 +contrib.go.opencensus.io/exporter/ocagent +# github.com/Azure/azure-sdk-for-go v32.4.0+incompatible +github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns +github.com/Azure/azure-sdk-for-go/version +# github.com/Azure/go-autorest/autorest v0.5.0 +github.com/Azure/go-autorest/autorest +github.com/Azure/go-autorest/autorest/azure +# github.com/Azure/go-autorest/autorest/adal v0.2.0 +github.com/Azure/go-autorest/autorest/adal +# github.com/Azure/go-autorest/autorest/azure/auth v0.1.0 +github.com/Azure/go-autorest/autorest/azure/auth +# github.com/Azure/go-autorest/autorest/azure/cli v0.1.0 +github.com/Azure/go-autorest/autorest/azure/cli +# github.com/Azure/go-autorest/autorest/date v0.1.0 +github.com/Azure/go-autorest/autorest/date +# github.com/Azure/go-autorest/autorest/to v0.2.0 +github.com/Azure/go-autorest/autorest/to +# github.com/Azure/go-autorest/autorest/validation v0.1.0 +github.com/Azure/go-autorest/autorest/validation +# github.com/Azure/go-autorest/logger v0.1.0 +github.com/Azure/go-autorest/logger +# github.com/Azure/go-autorest/tracing v0.1.0 +github.com/Azure/go-autorest/tracing +# github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 +github.com/OpenDNS/vegadns2client # github.com/WICG/webpackage v0.0.0-20190215052515-70386c3750f2 github.com/WICG/webpackage/go/signedexchange github.com/WICG/webpackage/go/signedexchange/cbor @@ -7,12 +35,88 @@ github.com/WICG/webpackage/go/signedexchange/internal/signingalgorithm github.com/WICG/webpackage/go/signedexchange/mice github.com/WICG/webpackage/go/signedexchange/structuredheader github.com/WICG/webpackage/go/signedexchange/version +# github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.0 +github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1 +github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1 +github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid +github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1 +# github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee +github.com/aliyun/alibaba-cloud-sdk-go/sdk +github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth +github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials +github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider +github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers +github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints +github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors +github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests +github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses +github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils +github.com/aliyun/alibaba-cloud-sdk-go/services/alidns # github.com/ampproject/amphtml v0.0.0-20180912232012-d3df64d07ae9 github.com/ampproject/amphtml/validator +# github.com/aws/aws-sdk-go v1.23.0 +github.com/aws/aws-sdk-go/aws +github.com/aws/aws-sdk-go/aws/awserr +github.com/aws/aws-sdk-go/aws/awsutil +github.com/aws/aws-sdk-go/aws/client +github.com/aws/aws-sdk-go/aws/client/metadata +github.com/aws/aws-sdk-go/aws/corehandlers +github.com/aws/aws-sdk-go/aws/credentials +github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds +github.com/aws/aws-sdk-go/aws/credentials/endpointcreds +github.com/aws/aws-sdk-go/aws/credentials/processcreds +github.com/aws/aws-sdk-go/aws/credentials/stscreds +github.com/aws/aws-sdk-go/aws/csm +github.com/aws/aws-sdk-go/aws/defaults +github.com/aws/aws-sdk-go/aws/ec2metadata +github.com/aws/aws-sdk-go/aws/endpoints +github.com/aws/aws-sdk-go/aws/request +github.com/aws/aws-sdk-go/aws/session +github.com/aws/aws-sdk-go/aws/signer/v4 +github.com/aws/aws-sdk-go/internal/ini +github.com/aws/aws-sdk-go/internal/sdkio +github.com/aws/aws-sdk-go/internal/sdkrand +github.com/aws/aws-sdk-go/internal/sdkuri +github.com/aws/aws-sdk-go/internal/shareddefaults +github.com/aws/aws-sdk-go/private/protocol +github.com/aws/aws-sdk-go/private/protocol/json/jsonutil +github.com/aws/aws-sdk-go/private/protocol/jsonrpc +github.com/aws/aws-sdk-go/private/protocol/query +github.com/aws/aws-sdk-go/private/protocol/query/queryutil +github.com/aws/aws-sdk-go/private/protocol/rest +github.com/aws/aws-sdk-go/private/protocol/restxml +github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil +github.com/aws/aws-sdk-go/service/lightsail +github.com/aws/aws-sdk-go/service/route53 +github.com/aws/aws-sdk-go/service/sts +github.com/aws/aws-sdk-go/service/sts/stsiface # github.com/cenkalti/backoff/v3 v3.0.0 github.com/cenkalti/backoff/v3 +# github.com/census-instrumentation/opencensus-proto v0.2.0 +github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1 +github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1 +github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1 +github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1 +github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1 +github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1 +# github.com/cloudflare/cloudflare-go v0.10.0 +github.com/cloudflare/cloudflare-go +# github.com/cpu/goacmedns v0.0.1 +github.com/cpu/goacmedns # github.com/davecgh/go-spew v1.1.1 => github.com/davecgh/go-spew v1.1.0 github.com/davecgh/go-spew/spew +# github.com/decker502/dnspod-go v0.2.0 +github.com/decker502/dnspod-go +# github.com/dgrijalva/jwt-go v3.2.0+incompatible +github.com/dgrijalva/jwt-go +# github.com/dimchansky/utfbom v1.1.0 +github.com/dimchansky/utfbom +# github.com/dnsimple/dnsimple-go v0.30.0 +github.com/dnsimple/dnsimple-go/dnsimple +# github.com/exoscale/egoscale v0.18.1 +github.com/exoscale/egoscale +# github.com/fatih/structs v1.1.0 +github.com/fatih/structs # github.com/go-acme/lego/v3 v3.0.2 github.com/go-acme/lego/v3/acme github.com/go-acme/lego/v3/acme/api @@ -28,13 +132,100 @@ github.com/go-acme/lego/v3/challenge/resolver github.com/go-acme/lego/v3/challenge/tlsalpn01 github.com/go-acme/lego/v3/lego github.com/go-acme/lego/v3/log +github.com/go-acme/lego/v3/platform/config/env github.com/go-acme/lego/v3/platform/tester github.com/go-acme/lego/v3/platform/wait +github.com/go-acme/lego/v3/providers/dns +github.com/go-acme/lego/v3/providers/dns/acmedns +github.com/go-acme/lego/v3/providers/dns/alidns +github.com/go-acme/lego/v3/providers/dns/auroradns +github.com/go-acme/lego/v3/providers/dns/azure +github.com/go-acme/lego/v3/providers/dns/bindman +github.com/go-acme/lego/v3/providers/dns/bluecat +github.com/go-acme/lego/v3/providers/dns/cloudflare +github.com/go-acme/lego/v3/providers/dns/cloudns +github.com/go-acme/lego/v3/providers/dns/cloudns/internal +github.com/go-acme/lego/v3/providers/dns/cloudxns +github.com/go-acme/lego/v3/providers/dns/cloudxns/internal +github.com/go-acme/lego/v3/providers/dns/conoha +github.com/go-acme/lego/v3/providers/dns/conoha/internal +github.com/go-acme/lego/v3/providers/dns/designate +github.com/go-acme/lego/v3/providers/dns/digitalocean +github.com/go-acme/lego/v3/providers/dns/dnsimple +github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy +github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/internal +github.com/go-acme/lego/v3/providers/dns/dnspod +github.com/go-acme/lego/v3/providers/dns/dode +github.com/go-acme/lego/v3/providers/dns/dreamhost +github.com/go-acme/lego/v3/providers/dns/duckdns +github.com/go-acme/lego/v3/providers/dns/dyn +github.com/go-acme/lego/v3/providers/dns/easydns +github.com/go-acme/lego/v3/providers/dns/exec +github.com/go-acme/lego/v3/providers/dns/exoscale +github.com/go-acme/lego/v3/providers/dns/fastdns +github.com/go-acme/lego/v3/providers/dns/gandi +github.com/go-acme/lego/v3/providers/dns/gandiv5 +github.com/go-acme/lego/v3/providers/dns/gcloud +github.com/go-acme/lego/v3/providers/dns/glesys +github.com/go-acme/lego/v3/providers/dns/godaddy +github.com/go-acme/lego/v3/providers/dns/hostingde +github.com/go-acme/lego/v3/providers/dns/httpreq +github.com/go-acme/lego/v3/providers/dns/iij +github.com/go-acme/lego/v3/providers/dns/inwx +github.com/go-acme/lego/v3/providers/dns/joker +github.com/go-acme/lego/v3/providers/dns/lightsail +github.com/go-acme/lego/v3/providers/dns/linode +github.com/go-acme/lego/v3/providers/dns/linodev4 +github.com/go-acme/lego/v3/providers/dns/mydnsjp +github.com/go-acme/lego/v3/providers/dns/namecheap +github.com/go-acme/lego/v3/providers/dns/namedotcom +github.com/go-acme/lego/v3/providers/dns/namesilo +github.com/go-acme/lego/v3/providers/dns/netcup +github.com/go-acme/lego/v3/providers/dns/netcup/internal +github.com/go-acme/lego/v3/providers/dns/nifcloud +github.com/go-acme/lego/v3/providers/dns/nifcloud/internal +github.com/go-acme/lego/v3/providers/dns/ns1 +github.com/go-acme/lego/v3/providers/dns/oraclecloud +github.com/go-acme/lego/v3/providers/dns/otc +github.com/go-acme/lego/v3/providers/dns/ovh +github.com/go-acme/lego/v3/providers/dns/pdns +github.com/go-acme/lego/v3/providers/dns/rackspace +github.com/go-acme/lego/v3/providers/dns/rfc2136 +github.com/go-acme/lego/v3/providers/dns/route53 +github.com/go-acme/lego/v3/providers/dns/sakuracloud +github.com/go-acme/lego/v3/providers/dns/selectel +github.com/go-acme/lego/v3/providers/dns/selectel/internal +github.com/go-acme/lego/v3/providers/dns/stackpath +github.com/go-acme/lego/v3/providers/dns/transip +github.com/go-acme/lego/v3/providers/dns/vegadns +github.com/go-acme/lego/v3/providers/dns/versio +github.com/go-acme/lego/v3/providers/dns/vscale +github.com/go-acme/lego/v3/providers/dns/vscale/internal +github.com/go-acme/lego/v3/providers/dns/vultr +github.com/go-acme/lego/v3/providers/dns/zoneee +github.com/go-acme/lego/v3/providers/http/webroot github.com/go-acme/lego/v3/registration +# github.com/go-errors/errors v1.0.1 +github.com/go-errors/errors +# github.com/go-ini/ini v1.44.0 +github.com/go-ini/ini # github.com/gofrs/flock v0.7.1 github.com/gofrs/flock +# github.com/gofrs/uuid v3.2.0+incompatible +github.com/gofrs/uuid # github.com/golang/protobuf v1.3.1 +github.com/golang/protobuf/jsonpb github.com/golang/protobuf/proto +github.com/golang/protobuf/protoc-gen-go/descriptor +github.com/golang/protobuf/protoc-gen-go/generator +github.com/golang/protobuf/protoc-gen-go/generator/internal/remap +github.com/golang/protobuf/protoc-gen-go/plugin +github.com/golang/protobuf/ptypes +github.com/golang/protobuf/ptypes/any +github.com/golang/protobuf/ptypes/duration +github.com/golang/protobuf/ptypes/struct +github.com/golang/protobuf/ptypes/timestamp +github.com/golang/protobuf/ptypes/wrappers # github.com/google/go-cmp v0.3.0 github.com/google/go-cmp/cmp github.com/google/go-cmp/cmp/cmpopts @@ -42,8 +233,69 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value +# github.com/google/go-querystring v1.0.0 +github.com/google/go-querystring/query +# github.com/google/uuid v1.1.1 +github.com/google/uuid +# github.com/googleapis/gax-go/v2 v2.0.5 +github.com/googleapis/gax-go/v2 +# github.com/gophercloud/gophercloud v0.3.0 +github.com/gophercloud/gophercloud +github.com/gophercloud/gophercloud/openstack +github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets +github.com/gophercloud/gophercloud/openstack/dns/v2/zones +github.com/gophercloud/gophercloud/openstack/identity/v2/tenants +github.com/gophercloud/gophercloud/openstack/identity/v2/tokens +github.com/gophercloud/gophercloud/openstack/identity/v3/tokens +github.com/gophercloud/gophercloud/openstack/utils +github.com/gophercloud/gophercloud/pagination +# github.com/grpc-ecosystem/grpc-gateway v1.8.5 +github.com/grpc-ecosystem/grpc-gateway/internal +github.com/grpc-ecosystem/grpc-gateway/runtime +github.com/grpc-ecosystem/grpc-gateway/utilities +# github.com/hashicorp/golang-lru v0.5.3 +github.com/hashicorp/golang-lru/simplelru +# github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df +github.com/iij/doapi +github.com/iij/doapi/protocol +# github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af +github.com/jmespath/go-jmespath +# github.com/json-iterator/go v1.1.5 +github.com/json-iterator/go +# github.com/kolo/xmlrpc v0.0.0-20190717152603-07c4ee3fd181 +github.com/kolo/xmlrpc +# github.com/konsorten/go-windows-terminal-sequences v1.0.2 +github.com/konsorten/go-windows-terminal-sequences +# github.com/labbsr0x/bindman-dns-webhook v1.0.0 +github.com/labbsr0x/bindman-dns-webhook/src/client +github.com/labbsr0x/bindman-dns-webhook/src/types +# github.com/labbsr0x/goh v0.0.0-20190417202808-8b16b4848295 +github.com/labbsr0x/goh/gohclient +# github.com/linode/linodego v0.10.0 +github.com/linode/linodego # github.com/miekg/dns v1.1.15 github.com/miekg/dns +# github.com/mitchellh/go-homedir v1.1.0 +github.com/mitchellh/go-homedir +# github.com/mitchellh/mapstructure v1.1.2 +github.com/mitchellh/mapstructure +# github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd +github.com/modern-go/concurrent +# github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 +github.com/modern-go/reflect2 +# github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 +github.com/namedotcom/go/namecom +# github.com/nrdcg/auroradns v1.0.0 +github.com/nrdcg/auroradns +# github.com/nrdcg/goinwx v0.6.1 +github.com/nrdcg/goinwx +# github.com/nrdcg/namesilo v0.2.1 +github.com/nrdcg/namesilo +# github.com/oracle/oci-go-sdk v7.0.0+incompatible +github.com/oracle/oci-go-sdk/common +github.com/oracle/oci-go-sdk/dns +# github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 +github.com/ovh/go-ovh/ovh # github.com/pelletier/go-toml v1.1.0 github.com/pelletier/go-toml # github.com/pkg/errors v0.8.1 @@ -53,24 +305,82 @@ github.com/pmezard/go-difflib/difflib # github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d github.com/pquerna/cachecontrol github.com/pquerna/cachecontrol/cacheobject +# github.com/sacloud/libsacloud v1.26.1 +github.com/sacloud/libsacloud +github.com/sacloud/libsacloud/api +github.com/sacloud/libsacloud/sacloud +github.com/sacloud/libsacloud/sacloud/ostype +github.com/sacloud/libsacloud/utils/mutexkv +# github.com/sirupsen/logrus v1.4.2 +github.com/sirupsen/logrus # github.com/stretchr/testify v1.3.0 => github.com/stretchr/testify v1.2.1 github.com/stretchr/testify/assert github.com/stretchr/testify/require github.com/stretchr/testify/suite +# github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 +github.com/timewasted/linode +github.com/timewasted/linode/dns +# github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f +github.com/transip/gotransip +github.com/transip/gotransip/domain +github.com/transip/gotransip/util +# github.com/vultr/govultr v0.1.4 +github.com/vultr/govultr +# go.opencensus.io v0.21.0 +go.opencensus.io +go.opencensus.io/internal +go.opencensus.io/internal/tagencoding +go.opencensus.io/metric/metricdata +go.opencensus.io/metric/metricproducer +go.opencensus.io/plugin/ocgrpc +go.opencensus.io/plugin/ochttp +go.opencensus.io/plugin/ochttp/propagation/b3 +go.opencensus.io/plugin/ochttp/propagation/tracecontext +go.opencensus.io/resource +go.opencensus.io/stats +go.opencensus.io/stats/internal +go.opencensus.io/stats/view +go.opencensus.io/tag +go.opencensus.io/trace +go.opencensus.io/trace/internal +go.opencensus.io/trace/propagation +go.opencensus.io/trace/tracestate +# go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277 +go.uber.org/ratelimit +go.uber.org/ratelimit/internal/clock # golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 => golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac golang.org/x/crypto/ed25519 golang.org/x/crypto/ed25519/internal/edwards25519 golang.org/x/crypto/ocsp golang.org/x/crypto/pbkdf2 +golang.org/x/crypto/pkcs12 +golang.org/x/crypto/pkcs12/internal/rc2 # golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c => golang.org/x/net v0.0.0-20180808004115-f9ce57c11b24 golang.org/x/net/bpf +golang.org/x/net/context +golang.org/x/net/context/ctxhttp golang.org/x/net/html golang.org/x/net/html/atom +golang.org/x/net/http/httpguts +golang.org/x/net/http2 +golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/internal/iana golang.org/x/net/internal/socket +golang.org/x/net/internal/timeseries golang.org/x/net/ipv4 golang.org/x/net/ipv6 +golang.org/x/net/publicsuffix +golang.org/x/net/trace +# golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 +golang.org/x/oauth2 +golang.org/x/oauth2/clientcredentials +golang.org/x/oauth2/google +golang.org/x/oauth2/internal +golang.org/x/oauth2/jws +golang.org/x/oauth2/jwt +# golang.org/x/sync v0.0.0-20190423024810-112230192c58 +golang.org/x/sync/semaphore # golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b golang.org/x/sys/unix # golang.org/x/text v0.3.2 => golang.org/x/text v0.3.0 @@ -78,6 +388,78 @@ golang.org/x/text/secure/bidirule golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm +# golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 +golang.org/x/time/rate +# google.golang.org/api v0.8.0 +google.golang.org/api/dns/v1 +google.golang.org/api/gensupport +google.golang.org/api/googleapi +google.golang.org/api/googleapi/internal/uritemplates +google.golang.org/api/googleapi/transport +google.golang.org/api/internal +google.golang.org/api/option +google.golang.org/api/support/bundler +google.golang.org/api/transport/http +google.golang.org/api/transport/http/internal/propagation +# google.golang.org/appengine v1.5.0 +google.golang.org/appengine +google.golang.org/appengine/internal +google.golang.org/appengine/internal/app_identity +google.golang.org/appengine/internal/base +google.golang.org/appengine/internal/datastore +google.golang.org/appengine/internal/log +google.golang.org/appengine/internal/modules +google.golang.org/appengine/internal/remote_api +google.golang.org/appengine/internal/urlfetch +google.golang.org/appengine/urlfetch +# google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 +google.golang.org/genproto/googleapis/api/httpbody +google.golang.org/genproto/googleapis/rpc/status +google.golang.org/genproto/protobuf/field_mask +# google.golang.org/grpc v1.20.1 +google.golang.org/grpc +google.golang.org/grpc/balancer +google.golang.org/grpc/balancer/base +google.golang.org/grpc/balancer/roundrobin +google.golang.org/grpc/binarylog/grpc_binarylog_v1 +google.golang.org/grpc/codes +google.golang.org/grpc/connectivity +google.golang.org/grpc/credentials +google.golang.org/grpc/credentials/internal +google.golang.org/grpc/encoding +google.golang.org/grpc/encoding/proto +google.golang.org/grpc/grpclog +google.golang.org/grpc/internal +google.golang.org/grpc/internal/backoff +google.golang.org/grpc/internal/balancerload +google.golang.org/grpc/internal/binarylog +google.golang.org/grpc/internal/channelz +google.golang.org/grpc/internal/envconfig +google.golang.org/grpc/internal/grpcrand +google.golang.org/grpc/internal/grpcsync +google.golang.org/grpc/internal/syscall +google.golang.org/grpc/internal/transport +google.golang.org/grpc/keepalive +google.golang.org/grpc/metadata +google.golang.org/grpc/naming +google.golang.org/grpc/peer +google.golang.org/grpc/resolver +google.golang.org/grpc/resolver/dns +google.golang.org/grpc/resolver/passthrough +google.golang.org/grpc/stats +google.golang.org/grpc/status +google.golang.org/grpc/tap +# gopkg.in/ini.v1 v1.44.0 +gopkg.in/ini.v1 +# gopkg.in/ns1/ns1-go.v2 v2.0.0-20190730140822-b51389932cbc +gopkg.in/ns1/ns1-go.v2/rest +gopkg.in/ns1/ns1-go.v2/rest/model/account +gopkg.in/ns1/ns1-go.v2/rest/model/data +gopkg.in/ns1/ns1-go.v2/rest/model/dns +gopkg.in/ns1/ns1-go.v2/rest/model/filter +gopkg.in/ns1/ns1-go.v2/rest/model/monitor +# gopkg.in/resty.v1 v1.12.0 +gopkg.in/resty.v1 # gopkg.in/square/go-jose.v2 v2.3.1 gopkg.in/square/go-jose.v2 gopkg.in/square/go-jose.v2/cipher From 5d0800d7beceec83c04a33b2fd5412c66aaac088 Mon Sep 17 00:00:00 2001 From: Allan Banaag Date: Fri, 27 Sep 2019 10:42:23 -0700 Subject: [PATCH 08/22] go mod tidy, go mod vendor updates --- vendor/cloud.google.com/go/LICENSE | 202 + .../go/compute/metadata/metadata.go | 513 + .../exporter/ocagent/.travis.yml | 18 + .../exporter/ocagent/CONTRIBUTING.md | 24 + .../exporter/ocagent/LICENSE | 201 + .../exporter/ocagent/README.md | 61 + .../exporter/ocagent/common.go | 38 + .../exporter/ocagent/connection.go | 97 + .../exporter/ocagent/go.mod | 10 + .../exporter/ocagent/go.sum | 130 + .../exporter/ocagent/nodeinfo.go | 46 + .../exporter/ocagent/ocagent.go | 496 + .../exporter/ocagent/options.go | 128 + .../exporter/ocagent/transform_spans.go | 248 + .../ocagent/transform_stats_to_metrics.go | 274 + .../exporter/ocagent/version.go | 17 + .../github.com/Azure/azure-sdk-for-go/LICENSE | 202 + .../github.com/Azure/azure-sdk-for-go/NOTICE | 5 + .../dns/mgmt/2017-09-01/dns/client.go | 51 + .../dns/mgmt/2017-09-01/dns/models.go | 833 + .../dns/mgmt/2017-09-01/dns/recordsets.go | 715 + .../dns/mgmt/2017-09-01/dns/version.go | 30 + .../services/dns/mgmt/2017-09-01/dns/zones.go | 572 + .../Azure/azure-sdk-for-go/version/version.go | 21 + .../Azure/go-autorest/autorest/LICENSE | 191 + .../Azure/go-autorest/autorest/adal/LICENSE | 191 + .../Azure/go-autorest/autorest/adal/README.md | 292 + .../Azure/go-autorest/autorest/adal/config.go | 151 + .../go-autorest/autorest/adal/devicetoken.go | 242 + .../Azure/go-autorest/autorest/adal/go.mod | 11 + .../Azure/go-autorest/autorest/adal/go.sum | 139 + .../go-autorest/autorest/adal/persist.go | 73 + .../Azure/go-autorest/autorest/adal/sender.go | 60 + .../Azure/go-autorest/autorest/adal/token.go | 1055 + .../go-autorest/autorest/adal/version.go | 45 + .../go-autorest/autorest/authorization.go | 336 + .../Azure/go-autorest/autorest/autorest.go | 150 + .../Azure/go-autorest/autorest/azure/async.go | 919 + .../go-autorest/autorest/azure/auth/LICENSE | 191 + .../go-autorest/autorest/azure/auth/auth.go | 712 + .../go-autorest/autorest/azure/auth/go.mod | 11 + .../go-autorest/autorest/azure/auth/go.sum | 153 + .../Azure/go-autorest/autorest/azure/azure.go | 326 + .../go-autorest/autorest/azure/cli/LICENSE | 191 + .../go-autorest/autorest/azure/cli/go.mod | 10 + .../go-autorest/autorest/azure/cli/go.sum | 144 + .../go-autorest/autorest/azure/cli/profile.go | 79 + .../go-autorest/autorest/azure/cli/token.go | 170 + .../autorest/azure/environments.go | 244 + .../autorest/azure/metadata_environment.go | 245 + .../Azure/go-autorest/autorest/azure/rp.go | 200 + .../Azure/go-autorest/autorest/client.go | 324 + .../Azure/go-autorest/autorest/date/LICENSE | 191 + .../Azure/go-autorest/autorest/date/date.go | 96 + .../Azure/go-autorest/autorest/date/go.mod | 3 + .../Azure/go-autorest/autorest/date/time.go | 103 + .../go-autorest/autorest/date/timerfc1123.go | 100 + .../go-autorest/autorest/date/unixtime.go | 123 + .../go-autorest/autorest/date/utility.go | 25 + .../Azure/go-autorest/autorest/error.go | 98 + .../Azure/go-autorest/autorest/go.mod | 12 + .../Azure/go-autorest/autorest/go.sum | 143 + .../Azure/go-autorest/autorest/preparer.go | 526 + .../Azure/go-autorest/autorest/responder.go | 269 + .../go-autorest/autorest/retriablerequest.go | 52 + .../autorest/retriablerequest_1.7.go | 54 + .../autorest/retriablerequest_1.8.go | 66 + .../Azure/go-autorest/autorest/sender.go | 382 + .../Azure/go-autorest/autorest/to/LICENSE | 191 + .../Azure/go-autorest/autorest/to/convert.go | 152 + .../Azure/go-autorest/autorest/to/go.mod | 3 + .../Azure/go-autorest/autorest/utility.go | 228 + .../go-autorest/autorest/validation/LICENSE | 191 + .../go-autorest/autorest/validation/error.go | 48 + .../go-autorest/autorest/validation/go.mod | 5 + .../go-autorest/autorest/validation/go.sum | 7 + .../autorest/validation/validation.go | 400 + .../Azure/go-autorest/autorest/version.go | 41 + .../Azure/go-autorest/logger/LICENSE | 191 + .../Azure/go-autorest/logger/go.mod | 3 + .../Azure/go-autorest/logger/logger.go | 328 + .../Azure/go-autorest/tracing/LICENSE | 191 + .../Azure/go-autorest/tracing/go.mod | 8 + .../Azure/go-autorest/tracing/go.sum | 130 + .../Azure/go-autorest/tracing/tracing.go | 195 + .../OpenDNS/vegadns2client/.gitignore | 4 + .../github.com/OpenDNS/vegadns2client/LICENSE | 13 + .../OpenDNS/vegadns2client/Makefile | 13 + .../OpenDNS/vegadns2client/README.md | 76 + .../OpenDNS/vegadns2client/client.go | 71 + .../OpenDNS/vegadns2client/domains.go | 80 + .../github.com/OpenDNS/vegadns2client/main.go | 19 + .../OpenDNS/vegadns2client/records.go | 113 + .../OpenDNS/vegadns2client/tokens.go | 74 + .../akamai/AkamaiOPEN-edgegrid-golang/LICENSE | 201 + .../client-v1/README.md | 3 + .../client-v1/api.go | 36 + .../client-v1/client.go | 154 + .../client-v1/errors.go | 107 + .../configdns-v1/README.md | 2 + .../configdns-v1/errors.go | 125 + .../configdns-v1/record.go | 1739 ++ .../configdns-v1/service.go | 16 + .../configdns-v1/zone.go | 1566 + .../edgegrid/README.md | 2 + .../edgegrid/config.go | 182 + .../edgegrid/errors.go | 22 + .../edgegrid/log.go | 73 + .../edgegrid/signer.go | 216 + .../jsonhooks-v1/README.md | 1 + .../jsonhooks-v1/errors.go | 1 + .../jsonhooks-v1/jsonhooks.go | 69 + .../aliyun/alibaba-cloud-sdk-go/LICENSE | 201 + .../alibaba-cloud-sdk-go/sdk/api_timeout.go | 249 + .../sdk/auth/credential.go | 18 + .../auth/credentials/access_key_credential.go | 34 + .../credentials/bearer_token_credential.go | 12 + .../sdk/auth/credentials/ecs_ram_role.go | 29 + .../sdk/auth/credentials/provider/env.go | 30 + .../provider/instance_credentials.go | 92 + .../provider/profile_credentials.go | 158 + .../sdk/auth/credentials/provider/provider.go | 19 + .../credentials/provider/provider_chain.go | 34 + .../credentials/rsa_key_pair_credential.go | 15 + .../sdk/auth/credentials/sts_credential.go | 15 + .../credentials/sts_role_arn_credential.go | 61 + .../sdk/auth/roa_signature_composer.go | 136 + .../sdk/auth/rpc_signature_composer.go | 94 + .../alibaba-cloud-sdk-go/sdk/auth/signer.go | 98 + .../sdk/auth/signers/algorithms.go | 57 + .../sdk/auth/signers/credential_updater.go | 54 + .../sdk/auth/signers/session_credential.go | 7 + .../sdk/auth/signers/signer_access_key.go | 54 + .../sdk/auth/signers/signer_bearer_token.go | 35 + .../sdk/auth/signers/signer_ecs_ram_role.go | 167 + .../sdk/auth/signers/signer_key_pair.go | 148 + .../sdk/auth/signers/signer_ram_role_arn.go | 175 + .../sdk/auth/signers/signer_sts_token.go | 54 + .../sdk/auth/signers/signer_v2.go | 54 + .../aliyun/alibaba-cloud-sdk-go/sdk/client.go | 766 + .../aliyun/alibaba-cloud-sdk-go/sdk/config.go | 91 + .../sdk/endpoints/endpoints_config.go | 4126 +++ .../sdk/endpoints/local_global_resolver.go | 43 + .../sdk/endpoints/local_regional_resolver.go | 48 + .../sdk/endpoints/location_resolver.go | 176 + .../sdk/endpoints/mapping_resolver.go | 48 + .../sdk/endpoints/resolver.go | 98 + .../sdk/endpoints/simple_host_resolver.go | 33 + .../sdk/errors/client_error.go | 92 + .../alibaba-cloud-sdk-go/sdk/errors/error.go | 23 + .../sdk/errors/server_error.go | 123 + .../signature_does_not_match_wrapper.go | 45 + .../aliyun/alibaba-cloud-sdk-go/sdk/logger.go | 116 + .../sdk/requests/acs_request.go | 410 + .../sdk/requests/common_request.go | 108 + .../sdk/requests/roa_request.go | 152 + .../sdk/requests/rpc_request.go | 79 + .../sdk/requests/types.go | 53 + .../sdk/responses/json_parser.go | 328 + .../sdk/responses/response.go | 144 + .../alibaba-cloud-sdk-go/sdk/utils/debug.go | 36 + .../alibaba-cloud-sdk-go/sdk/utils/utils.go | 141 + .../services/alidns/add_domain.go | 113 + .../services/alidns/add_domain_group.go | 107 + .../services/alidns/add_domain_record.go | 112 + .../alidns/add_gtm_access_strategy.go | 110 + .../services/alidns/add_gtm_address_pool.go | 117 + .../services/alidns/add_gtm_monitor.go | 119 + .../services/alidns/change_domain_group.go | 108 + .../alidns/change_domain_of_dns_product.go | 108 + .../services/alidns/check_domain_record.go | 109 + .../services/alidns/client.go | 104 + .../services/alidns/create_instance.go | 111 + .../services/alidns/delete_domain.go | 106 + .../services/alidns/delete_domain_group.go | 106 + .../services/alidns/delete_domain_record.go | 106 + .../alidns/delete_gtm_access_strategy.go | 105 + .../alidns/delete_gtm_address_pool.go | 105 + .../alidns/delete_sub_domain_records.go | 109 + .../alidns/describe_batch_result_count.go | 113 + .../alidns/describe_batch_result_detail.go | 112 + .../alidns/describe_dns_product_instance.go | 137 + .../alidns/describe_dns_product_instances.go | 111 + .../alidns/describe_dnsslb_sub_domains.go | 111 + .../alidns/describe_domain_dns_statistics.go | 108 + .../services/alidns/describe_domain_groups.go | 111 + .../services/alidns/describe_domain_info.go | 126 + .../services/alidns/describe_domain_logs.go | 115 + .../services/alidns/describe_domain_ns.go | 109 + .../alidns/describe_domain_record_info.go | 119 + .../alidns/describe_domain_records.go | 122 + .../alidns/describe_domain_statistics.go | 108 + .../describe_domain_statistics_summary.go | 118 + .../services/alidns/describe_domains.go | 114 + .../alidns/describe_gtm_access_strategies.go | 112 + .../alidns/describe_gtm_access_strategy.go | 116 + ...be_gtm_access_strategy_available_config.go | 107 + .../describe_gtm_available_alert_group.go | 105 + .../services/alidns/describe_gtm_instance.go | 118 + .../describe_gtm_instance_address_pool.go | 118 + .../describe_gtm_instance_address_pools.go | 112 + .../alidns/describe_gtm_instance_status.go | 107 + .../describe_gtm_instance_system_cname.go | 106 + .../services/alidns/describe_gtm_instances.go | 113 + .../services/alidns/describe_gtm_logs.go | 115 + .../describe_gtm_monitor_available_config.go | 105 + .../alidns/describe_gtm_monitor_config.go | 117 + .../services/alidns/describe_record_logs.go | 114 + .../alidns/describe_record_statistics.go | 109 + .../describe_record_statistics_history.go | 109 + .../describe_record_statistics_summary.go | 119 + .../alidns/describe_sub_domain_records.go | 113 + .../services/alidns/describe_support_lines.go | 106 + .../services/alidns/get_main_domain_name.go | 108 + .../alidns/modify_hichina_domain_dns.go | 107 + .../services/alidns/operate_batch_domain.go | 121 + .../alidns/query_create_instance_price.go | 112 + .../services/alidns/set_dnsslb_status.go | 108 + .../alidns/set_domain_record_status.go | 108 + .../services/alidns/set_gtm_access_mode.go | 106 + .../services/alidns/set_gtm_monitor_status.go | 106 + .../services/alidns/struct_addr.go | 29 + .../services/alidns/struct_addr_pool.go | 33 + ...be_gtm_access_strategy_available_config.go | 21 + ..._in_describe_gtm_instance_address_pools.go | 21 + .../services/alidns/struct_addrs.go | 21 + .../services/alidns/struct_available_ttls.go | 21 + .../alidns/struct_batch_result_detail.go | 36 + .../alidns/struct_batch_result_details.go | 21 + .../services/alidns/struct_dns_product.go | 51 + .../services/alidns/struct_dns_products.go | 21 + .../struct_dns_servers_in_add_domain.go | 21 + ...ervers_in_describe_dns_product_instance.go | 21 + ...uct_dns_servers_in_describe_domain_info.go | 21 + ...truct_dns_servers_in_describe_domain_ns.go | 21 + .../struct_dns_servers_in_describe_domains.go | 21 + .../services/alidns/struct_domain.go | 35 + .../services/alidns/struct_domain_group.go | 23 + .../services/alidns/struct_domain_groups.go | 21 + .../services/alidns/struct_domain_log.go | 27 + .../services/alidns/struct_domain_logs.go | 21 + ...main_records_in_describe_domain_records.go | 21 + ..._records_in_describe_sub_domain_records.go | 21 + .../services/alidns/struct_domains.go | 21 + .../alidns/struct_expect_dns_servers.go | 21 + .../services/alidns/struct_gtm_instance.go | 33 + .../services/alidns/struct_gtm_instances.go | 21 + .../services/alidns/struct_isp_city_node.go | 28 + ...n_describe_gtm_monitor_available_config.go | 21 + ...ty_nodes_in_describe_gtm_monitor_config.go | 21 + .../services/alidns/struct_line.go | 25 + ...lines_in_describe_gtm_access_strategies.go | 21 + ...t_lines_in_describe_gtm_access_strategy.go | 21 + ...be_gtm_access_strategy_available_config.go | 21 + .../services/alidns/struct_log.go | 29 + .../services/alidns/struct_logs.go | 21 + .../services/alidns/struct_new_dns_servers.go | 21 + .../alidns/struct_original_dns_servers.go | 21 + .../services/alidns/struct_record.go | 32 + .../services/alidns/struct_record_line.go | 24 + ...ct_record_lines_in_describe_domain_info.go | 21 + ..._record_lines_in_describe_support_lines.go | 21 + .../services/alidns/struct_record_log.go | 25 + .../services/alidns/struct_record_logs.go | 21 + .../services/alidns/struct_rule.go | 23 + .../services/alidns/struct_rules.go | 21 + .../services/alidns/struct_slb_sub_domain.go | 24 + .../services/alidns/struct_slb_sub_domains.go | 21 + .../services/alidns/struct_statistic.go | 24 + ...stics_in_describe_domain_dns_statistics.go | 21 + ...tatistics_in_describe_domain_statistics.go | 21 + ...s_in_describe_domain_statistics_summary.go | 21 + ...tatistics_in_describe_record_statistics.go | 21 + ...s_in_describe_record_statistics_history.go | 21 + ...s_in_describe_record_statistics_summary.go | 21 + .../services/alidns/struct_strategies.go | 21 + .../services/alidns/struct_strategy.go | 33 + .../services/alidns/update_dnsslb_weight.go | 108 + .../services/alidns/update_domain_group.go | 108 + .../services/alidns/update_domain_record.go | 112 + .../alidns/update_gtm_access_strategy.go | 109 + .../alidns/update_gtm_address_pool.go | 116 + .../update_gtm_instance_global_config.go | 112 + .../services/alidns/update_gtm_monitor.go | 118 + vendor/github.com/aws/aws-sdk-go/LICENSE.txt | 202 + vendor/github.com/aws/aws-sdk-go/NOTICE.txt | 3 + .../aws/aws-sdk-go/aws/awserr/error.go | 164 + .../aws/aws-sdk-go/aws/awserr/types.go | 221 + .../aws/aws-sdk-go/aws/awsutil/copy.go | 108 + .../aws/aws-sdk-go/aws/awsutil/equal.go | 27 + .../aws/aws-sdk-go/aws/awsutil/path_value.go | 221 + .../aws/aws-sdk-go/aws/awsutil/prettify.go | 113 + .../aws-sdk-go/aws/awsutil/string_value.go | 88 + .../aws/aws-sdk-go/aws/client/client.go | 96 + .../aws-sdk-go/aws/client/default_retryer.go | 103 + .../aws/aws-sdk-go/aws/client/logger.go | 194 + .../aws/client/metadata/client_info.go | 13 + .../github.com/aws/aws-sdk-go/aws/config.go | 536 + .../aws/aws-sdk-go/aws/context_1_5.go | 37 + .../aws/aws-sdk-go/aws/context_1_9.go | 11 + .../aws-sdk-go/aws/context_background_1_5.go | 56 + .../aws-sdk-go/aws/context_background_1_7.go | 20 + .../aws/aws-sdk-go/aws/context_sleep.go | 24 + .../aws/aws-sdk-go/aws/convert_types.go | 387 + .../aws-sdk-go/aws/corehandlers/handlers.go | 230 + .../aws/corehandlers/param_validator.go | 17 + .../aws-sdk-go/aws/corehandlers/user_agent.go | 37 + .../aws/credentials/chain_provider.go | 100 + .../aws-sdk-go/aws/credentials/credentials.go | 299 + .../ec2rolecreds/ec2_role_provider.go | 180 + .../aws/credentials/endpointcreds/provider.go | 203 + .../aws/credentials/env_provider.go | 74 + .../aws-sdk-go/aws/credentials/example.ini | 12 + .../aws/credentials/processcreds/provider.go | 425 + .../shared_credentials_provider.go | 150 + .../aws/credentials/static_provider.go | 55 + .../stscreds/assume_role_provider.go | 312 + .../stscreds/web_identity_provider.go | 97 + .../github.com/aws/aws-sdk-go/aws/csm/doc.go | 69 + .../aws/aws-sdk-go/aws/csm/enable.go | 89 + .../aws/aws-sdk-go/aws/csm/metric.go | 109 + .../aws/aws-sdk-go/aws/csm/metric_chan.go | 54 + .../aws-sdk-go/aws/csm/metric_exception.go | 26 + .../aws/aws-sdk-go/aws/csm/reporter.go | 265 + .../aws/aws-sdk-go/aws/defaults/defaults.go | 207 + .../aws-sdk-go/aws/defaults/shared_config.go | 27 + vendor/github.com/aws/aws-sdk-go/aws/doc.go | 56 + .../aws/aws-sdk-go/aws/ec2metadata/api.go | 169 + .../aws/aws-sdk-go/aws/ec2metadata/service.go | 152 + .../aws/aws-sdk-go/aws/endpoints/decode.go | 188 + .../aws/aws-sdk-go/aws/endpoints/defaults.go | 4888 ++++ .../aws/endpoints/dep_service_ids.go | 141 + .../aws/aws-sdk-go/aws/endpoints/doc.go | 66 + .../aws/aws-sdk-go/aws/endpoints/endpoints.go | 452 + .../aws/aws-sdk-go/aws/endpoints/v3model.go | 308 + .../aws/endpoints/v3model_codegen.go | 351 + .../github.com/aws/aws-sdk-go/aws/errors.go | 13 + .../aws/aws-sdk-go/aws/jsonvalue.go | 12 + .../github.com/aws/aws-sdk-go/aws/logger.go | 118 + .../aws/request/connection_reset_error.go | 18 + .../aws/aws-sdk-go/aws/request/handlers.go | 322 + .../aws-sdk-go/aws/request/http_request.go | 24 + .../aws-sdk-go/aws/request/offset_reader.go | 65 + .../aws/aws-sdk-go/aws/request/request.go | 670 + .../aws/aws-sdk-go/aws/request/request_1_7.go | 39 + .../aws/aws-sdk-go/aws/request/request_1_8.go | 36 + .../aws-sdk-go/aws/request/request_context.go | 14 + .../aws/request/request_context_1_6.go | 14 + .../aws/request/request_pagination.go | 264 + .../aws/aws-sdk-go/aws/request/retryer.go | 266 + .../aws/request/timeout_read_closer.go | 94 + .../aws/aws-sdk-go/aws/request/validation.go | 286 + .../aws/aws-sdk-go/aws/request/waiter.go | 295 + .../aws/session/cabundle_transport.go | 26 + .../aws/session/cabundle_transport_1_5.go | 22 + .../aws/session/cabundle_transport_1_6.go | 23 + .../aws/aws-sdk-go/aws/session/credentials.go | 259 + .../aws/aws-sdk-go/aws/session/doc.go | 245 + .../aws/aws-sdk-go/aws/session/env_config.go | 273 + .../aws/aws-sdk-go/aws/session/session.go | 609 + .../aws-sdk-go/aws/session/shared_config.go | 466 + .../aws-sdk-go/aws/signer/v4/header_rules.go | 82 + .../aws/aws-sdk-go/aws/signer/v4/options.go | 7 + .../aws/aws-sdk-go/aws/signer/v4/uri_path.go | 24 + .../aws/aws-sdk-go/aws/signer/v4/v4.go | 806 + vendor/github.com/aws/aws-sdk-go/aws/types.go | 207 + vendor/github.com/aws/aws-sdk-go/aws/url.go | 12 + .../github.com/aws/aws-sdk-go/aws/url_1_7.go | 29 + .../github.com/aws/aws-sdk-go/aws/version.go | 8 + .../aws/aws-sdk-go/internal/ini/ast.go | 120 + .../aws-sdk-go/internal/ini/comma_token.go | 11 + .../aws-sdk-go/internal/ini/comment_token.go | 35 + .../aws/aws-sdk-go/internal/ini/doc.go | 29 + .../aws-sdk-go/internal/ini/empty_token.go | 4 + .../aws/aws-sdk-go/internal/ini/expression.go | 24 + .../aws/aws-sdk-go/internal/ini/fuzz.go | 17 + .../aws/aws-sdk-go/internal/ini/ini.go | 51 + .../aws/aws-sdk-go/internal/ini/ini_lexer.go | 165 + .../aws/aws-sdk-go/internal/ini/ini_parser.go | 349 + .../aws-sdk-go/internal/ini/literal_tokens.go | 324 + .../aws-sdk-go/internal/ini/newline_token.go | 30 + .../aws-sdk-go/internal/ini/number_helper.go | 152 + .../aws/aws-sdk-go/internal/ini/op_tokens.go | 39 + .../aws-sdk-go/internal/ini/parse_error.go | 43 + .../aws-sdk-go/internal/ini/parse_stack.go | 60 + .../aws/aws-sdk-go/internal/ini/sep_tokens.go | 41 + .../aws/aws-sdk-go/internal/ini/skipper.go | 45 + .../aws/aws-sdk-go/internal/ini/statement.go | 35 + .../aws/aws-sdk-go/internal/ini/value_util.go | 284 + .../aws/aws-sdk-go/internal/ini/visitor.go | 166 + .../aws/aws-sdk-go/internal/ini/walker.go | 25 + .../aws/aws-sdk-go/internal/ini/ws_token.go | 24 + .../aws/aws-sdk-go/internal/sdkio/io_go1.6.go | 10 + .../aws/aws-sdk-go/internal/sdkio/io_go1.7.go | 12 + .../internal/sdkrand/locked_source.go | 29 + .../aws/aws-sdk-go/internal/sdkuri/path.go | 23 + .../internal/shareddefaults/ecs_container.go | 12 + .../internal/shareddefaults/shared_config.go | 40 + .../aws/aws-sdk-go/private/protocol/host.go | 68 + .../private/protocol/host_prefix.go | 54 + .../private/protocol/idempotency.go | 75 + .../private/protocol/json/jsonutil/build.go | 296 + .../protocol/json/jsonutil/unmarshal.go | 250 + .../private/protocol/jsonrpc/jsonrpc.go | 110 + .../aws-sdk-go/private/protocol/jsonvalue.go | 76 + .../aws-sdk-go/private/protocol/payload.go | 81 + .../private/protocol/query/build.go | 36 + .../protocol/query/queryutil/queryutil.go | 246 + .../private/protocol/query/unmarshal.go | 39 + .../private/protocol/query/unmarshal_error.go | 69 + .../aws-sdk-go/private/protocol/rest/build.go | 310 + .../private/protocol/rest/payload.go | 45 + .../private/protocol/rest/unmarshal.go | 225 + .../private/protocol/restxml/restxml.go | 79 + .../aws-sdk-go/private/protocol/timestamp.go | 72 + .../aws-sdk-go/private/protocol/unmarshal.go | 21 + .../private/protocol/xml/xmlutil/build.go | 306 + .../private/protocol/xml/xmlutil/unmarshal.go | 291 + .../protocol/xml/xmlutil/xml_to_struct.go | 148 + .../aws/aws-sdk-go/service/lightsail/api.go | 24271 ++++++++++++++++ .../aws/aws-sdk-go/service/lightsail/doc.go | 40 + .../aws-sdk-go/service/lightsail/errors.go | 55 + .../aws-sdk-go/service/lightsail/service.go | 97 + .../aws/aws-sdk-go/service/route53/api.go | 15360 ++++++++++ .../service/route53/customizations.go | 42 + .../aws/aws-sdk-go/service/route53/doc.go | 29 + .../aws/aws-sdk-go/service/route53/errors.go | 438 + .../aws/aws-sdk-go/service/route53/service.go | 95 + .../service/route53/unmarshal_error.go | 106 + .../aws/aws-sdk-go/service/route53/waiters.go | 56 + .../aws/aws-sdk-go/service/sts/api.go | 2750 ++ .../aws/aws-sdk-go/service/sts/doc.go | 108 + .../aws/aws-sdk-go/service/sts/errors.go | 73 + .../aws/aws-sdk-go/service/sts/service.go | 95 + .../service/sts/stsiface/interface.go | 96 + .../opencensus-proto/AUTHORS | 1 + .../opencensus-proto/LICENSE | 202 + .../gen-go/agent/common/v1/common.pb.go | 356 + .../agent/metrics/v1/metrics_service.pb.go | 264 + .../gen-go/agent/trace/v1/trace_service.pb.go | 443 + .../agent/trace/v1/trace_service.pb.gw.go | 154 + .../gen-go/metrics/v1/metrics.pb.go | 1126 + .../gen-go/resource/v1/resource.pb.go | 99 + .../gen-go/trace/v1/trace.pb.go | 1543 + .../gen-go/trace/v1/trace_config.pb.go | 358 + .../cloudflare/cloudflare-go/.gitignore | 2 + .../cloudflare/cloudflare-go/.travis.yml | 52 + .../cloudflare-go/CODE_OF_CONDUCT.md | 77 + .../cloudflare/cloudflare-go/LICENSE | 26 + .../cloudflare/cloudflare-go/README.md | 107 + .../cloudflare-go/access_application.go | 180 + .../cloudflare/cloudflare-go/access_policy.go | 221 + .../cloudflare-go/account_members.go | 186 + .../cloudflare/cloudflare-go/account_roles.go | 80 + .../cloudflare/cloudflare-go/accounts.go | 114 + .../cloudflare/cloudflare-go/argo.go | 120 + .../cloudflare/cloudflare-go/auditlogs.go | 143 + .../cloudflare/cloudflare-go/cloudflare.go | 435 + .../cloudflare-go/custom_hostname.go | 160 + .../cloudflare/cloudflare-go/custom_pages.go | 176 + .../cloudflare/cloudflare-go/dns.go | 174 + .../cloudflare/cloudflare-go/duration.go | 40 + .../cloudflare/cloudflare-go/errors.go | 50 + .../cloudflare/cloudflare-go/filter.go | 241 + .../cloudflare/cloudflare-go/firewall.go | 280 + .../cloudflare-go/firewall_rules.go | 196 + .../cloudflare/cloudflare-go/go.mod | 13 + .../cloudflare/cloudflare-go/go.sum | 21 + .../cloudflare/cloudflare-go/ips.go | 44 + .../cloudflare/cloudflare-go/keyless.go | 52 + .../cloudflare-go/load_balancing.go | 387 + .../cloudflare/cloudflare-go/lockdown.go | 151 + .../cloudflare/cloudflare-go/logpush.go | 224 + .../cloudflare/cloudflare-go/options.go | 101 + .../cloudflare/cloudflare-go/origin_ca.go | 169 + .../cloudflare/cloudflare-go/page_rules.go | 235 + .../cloudflare/cloudflare-go/railgun.go | 297 + .../cloudflare/cloudflare-go/rate_limiting.go | 210 + .../cloudflare/cloudflare-go/registrar.go | 175 + .../cloudflare/cloudflare-go/renovate.json | 5 + .../cloudflare/cloudflare-go/spectrum.go | 158 + .../cloudflare/cloudflare-go/ssl.go | 157 + .../cloudflare/cloudflare-go/universal_ssl.go | 88 + .../cloudflare/cloudflare-go/user.go | 113 + .../cloudflare/cloudflare-go/user_agent.go | 149 + .../cloudflare/cloudflare-go/virtualdns.go | 192 + .../cloudflare/cloudflare-go/waf.go | 255 + .../cloudflare/cloudflare-go/workers.go | 314 + .../cloudflare/cloudflare-go/workers_kv.go | 192 + .../cloudflare/cloudflare-go/zone.go | 690 + .../cpu/goacmedns/.errcheck_exclude | 1 + vendor/github.com/cpu/goacmedns/.gitignore | 12 + vendor/github.com/cpu/goacmedns/.travis.yml | 18 + vendor/github.com/cpu/goacmedns/LICENSE | 21 + vendor/github.com/cpu/goacmedns/README.md | 93 + vendor/github.com/cpu/goacmedns/account.go | 11 + vendor/github.com/cpu/goacmedns/client.go | 191 + vendor/github.com/cpu/goacmedns/storage.go | 89 + vendor/github.com/decker502/dnspod-go/LICENSE | 21 + .../github.com/decker502/dnspod-go/README.md | 59 + .../github.com/decker502/dnspod-go/dnspod.go | 233 + .../decker502/dnspod-go/domain_records.go | 237 + .../github.com/decker502/dnspod-go/domains.go | 162 + vendor/github.com/decker502/dnspod-go/go.mod | 3 + vendor/github.com/decker502/dnspod-go/go.sum | 0 vendor/github.com/dgrijalva/jwt-go/.gitignore | 4 + .../github.com/dgrijalva/jwt-go/.travis.yml | 13 + vendor/github.com/dgrijalva/jwt-go/LICENSE | 8 + .../dgrijalva/jwt-go/MIGRATION_GUIDE.md | 97 + vendor/github.com/dgrijalva/jwt-go/README.md | 100 + .../dgrijalva/jwt-go/VERSION_HISTORY.md | 118 + vendor/github.com/dgrijalva/jwt-go/claims.go | 134 + vendor/github.com/dgrijalva/jwt-go/doc.go | 4 + vendor/github.com/dgrijalva/jwt-go/ecdsa.go | 148 + .../dgrijalva/jwt-go/ecdsa_utils.go | 67 + vendor/github.com/dgrijalva/jwt-go/errors.go | 59 + vendor/github.com/dgrijalva/jwt-go/hmac.go | 95 + .../github.com/dgrijalva/jwt-go/map_claims.go | 94 + vendor/github.com/dgrijalva/jwt-go/none.go | 52 + vendor/github.com/dgrijalva/jwt-go/parser.go | 148 + vendor/github.com/dgrijalva/jwt-go/rsa.go | 101 + vendor/github.com/dgrijalva/jwt-go/rsa_pss.go | 126 + .../github.com/dgrijalva/jwt-go/rsa_utils.go | 101 + .../dgrijalva/jwt-go/signing_method.go | 35 + vendor/github.com/dgrijalva/jwt-go/token.go | 108 + .../github.com/dimchansky/utfbom/.gitignore | 37 + .../github.com/dimchansky/utfbom/.travis.yml | 18 + vendor/github.com/dimchansky/utfbom/LICENSE | 201 + vendor/github.com/dimchansky/utfbom/README.md | 66 + vendor/github.com/dimchansky/utfbom/go.mod | 1 + vendor/github.com/dimchansky/utfbom/utfbom.go | 192 + .../dnsimple/dnsimple-go/LICENSE.txt | 21 + .../dnsimple/dnsimple-go/dnsimple/accounts.go | 41 + .../dnsimple-go/dnsimple/authentication.go | 52 + .../dnsimple-go/dnsimple/certificates.go | 249 + .../dnsimple/dnsimple-go/dnsimple/contacts.go | 140 + .../dnsimple/dnsimple-go/dnsimple/dnsimple.go | 338 + .../dnsimple/dnsimple-go/dnsimple/domains.go | 138 + .../dnsimple/domains_collaborators.go | 96 + .../domains_delegation_signer_records.go | 105 + .../dnsimple-go/dnsimple/domains_dnssec.go | 70 + .../dnsimple/domains_email_forwards.go | 104 + .../dnsimple-go/dnsimple/domains_pushes.go | 111 + .../dnsimple/dnsimple-go/dnsimple/identity.go | 48 + .../dnsimple/dnsimple-go/dnsimple/oauth.go | 113 + .../dnsimple-go/dnsimple/registrar.go | 261 + .../dnsimple/registrar_auto_renewal.go | 37 + .../dnsimple/registrar_delegation.go | 84 + .../dnsimple/registrar_whois_privacy.go | 103 + .../dnsimple/dnsimple-go/dnsimple/services.go | 94 + .../dnsimple-go/dnsimple/services_domains.go | 70 + .../dnsimple-go/dnsimple/templates.go | 129 + .../dnsimple-go/dnsimple/templates_domains.go | 21 + .../dnsimple-go/dnsimple/templates_records.go | 107 + .../dnsimple/dnsimple-go/dnsimple/tlds.go | 117 + .../dnsimple/dnsimple-go/dnsimple/users.go | 7 + .../dnsimple/vanity_name_server.go | 65 + .../dnsimple/dnsimple-go/dnsimple/webhooks.go | 103 + .../dnsimple/zone_distributions.go | 46 + .../dnsimple/dnsimple-go/dnsimple/zones.go | 108 + .../dnsimple-go/dnsimple/zones_records.go | 142 + .../exoscale/egoscale/.codeclimate.yml | 31 + .../github.com/exoscale/egoscale/.gitignore | 5 + .../exoscale/egoscale/.golangci.yml | 27 + .../exoscale/egoscale/.gometalinter.json | 25 + .../github.com/exoscale/egoscale/.travis.yml | 49 + vendor/github.com/exoscale/egoscale/AUTHORS | 9 + .../github.com/exoscale/egoscale/CHANGELOG.md | 457 + vendor/github.com/exoscale/egoscale/LICENSE | 201 + vendor/github.com/exoscale/egoscale/README.md | 27 + .../github.com/exoscale/egoscale/accounts.go | 80 + .../exoscale/egoscale/accounts_response.go | 43 + .../github.com/exoscale/egoscale/addresses.go | 179 + .../exoscale/egoscale/affinity_groups.go | 158 + .../egoscale/affinitygroups_response.go | 43 + vendor/github.com/exoscale/egoscale/apis.go | 48 + .../exoscale/egoscale/async_jobs.go | 138 + .../exoscale/egoscale/asyncjobs_response.go | 43 + vendor/github.com/exoscale/egoscale/cidr.go | 62 + vendor/github.com/exoscale/egoscale/client.go | 418 + .../exoscale/egoscale/cserrorcode_string.go | 47 + vendor/github.com/exoscale/egoscale/dns.go | 364 + vendor/github.com/exoscale/egoscale/doc.go | 180 + .../exoscale/egoscale/errorcode_string.go | 37 + vendor/github.com/exoscale/egoscale/events.go | 76 + .../exoscale/egoscale/events_response.go | 43 + .../exoscale/egoscale/eventtypes_response.go | 43 + vendor/github.com/exoscale/egoscale/go.mod | 3 + vendor/github.com/exoscale/egoscale/go.sum | 2 + .../github.com/exoscale/egoscale/gopher.png | Bin 0 -> 63065 bytes .../exoscale/egoscale/instance_groups.go | 71 + .../egoscale/instancegroups_response.go | 43 + vendor/github.com/exoscale/egoscale/isos.go | 94 + .../exoscale/egoscale/isos_response.go | 43 + .../exoscale/egoscale/jobstatustype_string.go | 16 + .../exoscale/egoscale/macaddress.go | 63 + .../exoscale/egoscale/network_offerings.go | 91 + .../egoscale/networkofferings_response.go | 43 + .../github.com/exoscale/egoscale/networks.go | 229 + .../exoscale/egoscale/networks_response.go | 43 + vendor/github.com/exoscale/egoscale/nics.go | 120 + .../exoscale/egoscale/nics_response.go | 43 + .../egoscale/oscategories_response.go | 43 + .../egoscale/publicipaddresses_response.go | 43 + .../exoscale/egoscale/record_string.go | 16 + .../github.com/exoscale/egoscale/request.go | 405 + .../exoscale/egoscale/request_type.go | 184 + .../exoscale/egoscale/resource_limits.go | 100 + .../exoscale/egoscale/resource_metadata.go | 41 + .../egoscale/resourcedetails_response.go | 43 + .../egoscale/resourcelimits_response.go | 43 + .../exoscale/egoscale/reversedns.go | 83 + .../github.com/exoscale/egoscale/runstatus.go | 131 + .../exoscale/egoscale/runstatus_event.go | 37 + .../exoscale/egoscale/runstatus_incident.go | 175 + .../egoscale/runstatus_maintenance.go | 208 + .../exoscale/egoscale/runstatus_page.go | 168 + .../exoscale/egoscale/runstatus_service.go | 201 + .../exoscale/egoscale/security_groups.go | 226 + .../egoscale/securitygroups_response.go | 43 + .../exoscale/egoscale/serialization.go | 402 + .../exoscale/egoscale/service_offerings.go | 77 + .../egoscale/serviceofferings_response.go | 43 + .../github.com/exoscale/egoscale/snapshots.go | 139 + .../exoscale/egoscale/snapshots_response.go | 43 + .../exoscale/egoscale/ssh_keypairs.go | 105 + .../exoscale/egoscale/sshkeypairs_response.go | 43 + vendor/github.com/exoscale/egoscale/tags.go | 84 + .../exoscale/egoscale/tags_response.go | 43 + .../github.com/exoscale/egoscale/templates.go | 163 + .../exoscale/egoscale/templates_response.go | 43 + vendor/github.com/exoscale/egoscale/users.go | 63 + .../exoscale/egoscale/users_response.go | 43 + vendor/github.com/exoscale/egoscale/uuid.go | 79 + .../github.com/exoscale/egoscale/version.go | 4 + .../exoscale/egoscale/virtual_machines.go | 613 + .../egoscale/virtualmachines_response.go | 43 + .../github.com/exoscale/egoscale/volumes.go | 113 + .../exoscale/egoscale/volumes_response.go | 43 + vendor/github.com/exoscale/egoscale/zones.go | 62 + .../exoscale/egoscale/zones_response.go | 43 + vendor/github.com/fatih/structs/.gitignore | 23 + vendor/github.com/fatih/structs/.travis.yml | 13 + vendor/github.com/fatih/structs/LICENSE | 21 + vendor/github.com/fatih/structs/README.md | 163 + vendor/github.com/fatih/structs/field.go | 141 + vendor/github.com/fatih/structs/structs.go | 584 + vendor/github.com/fatih/structs/tags.go | 32 + .../lego/v3/platform/config/env/env.go | 163 + .../lego/v3/providers/dns/acmedns/acmedns.go | 162 + .../v3/providers/dns/acmedns/acmedns.toml | 16 + .../lego/v3/providers/dns/alidns/alidns.go | 220 + .../lego/v3/providers/dns/alidns/alidns.toml | 21 + .../v3/providers/dns/auroradns/auroradns.go | 191 + .../v3/providers/dns/auroradns/auroradns.toml | 21 + .../lego/v3/providers/dns/azure/azure.go | 274 + .../lego/v3/providers/dns/azure/azure.toml | 25 + .../lego/v3/providers/dns/bindman/bindman.go | 99 + .../v3/providers/dns/bindman/bindman.toml | 22 + .../lego/v3/providers/dns/bluecat/bluecat.go | 201 + .../v3/providers/dns/bluecat/bluecat.toml | 20 + .../lego/v3/providers/dns/bluecat/client.go | 249 + .../v3/providers/dns/cloudflare/cloudflare.go | 157 + .../providers/dns/cloudflare/cloudflare.toml | 31 + .../lego/v3/providers/dns/cloudns/cloudns.go | 121 + .../v3/providers/dns/cloudns/cloudns.toml | 20 + .../providers/dns/cloudns/internal/client.go | 271 + .../v3/providers/dns/cloudxns/cloudxns.go | 108 + .../v3/providers/dns/cloudxns/cloudxns.toml | 20 + .../providers/dns/cloudxns/internal/client.go | 208 + .../lego/v3/providers/dns/conoha/conoha.go | 148 + .../lego/v3/providers/dns/conoha/conoha.toml | 22 + .../providers/dns/conoha/internal/client.go | 205 + .../v3/providers/dns/designate/designate.go | 249 + .../v3/providers/dns/designate/designate.toml | 25 + .../v3/providers/dns/digitalocean/client.go | 132 + .../dns/digitalocean/digitalocean.go | 131 + .../dns/digitalocean/digitalocean.toml | 19 + .../lego/v3/providers/dns/dns_providers.go | 195 + .../v3/providers/dns/dnsimple/dnsimple.go | 211 + .../v3/providers/dns/dnsimple/dnsimple.toml | 20 + .../providers/dns/dnsmadeeasy/dnsmadeeasy.go | 163 + .../dns/dnsmadeeasy/dnsmadeeasy.toml | 21 + .../dns/dnsmadeeasy/internal/client.go | 173 + .../lego/v3/providers/dns/dnspod/dnspod.go | 188 + .../lego/v3/providers/dns/dnspod/dnspod.toml | 20 + .../lego/v3/providers/dns/dode/client.go | 57 + .../lego/v3/providers/dns/dode/dode.go | 89 + .../lego/v3/providers/dns/dode/dode.toml | 20 + .../lego/v3/providers/dns/dreamhost/client.go | 73 + .../v3/providers/dns/dreamhost/dreamhost.go | 111 + .../v3/providers/dns/dreamhost/dreamhost.toml | 19 + .../lego/v3/providers/dns/duckdns/client.go | 68 + .../lego/v3/providers/dns/duckdns/duckdns.go | 89 + .../v3/providers/dns/duckdns/duckdns.toml | 20 + .../lego/v3/providers/dns/dyn/client.go | 146 + .../go-acme/lego/v3/providers/dns/dyn/dyn.go | 157 + .../lego/v3/providers/dns/dyn/dyn.toml | 21 + .../lego/v3/providers/dns/easydns/client.go | 97 + .../lego/v3/providers/dns/easydns/easydns.go | 165 + .../v3/providers/dns/easydns/easydns.toml | 30 + .../lego/v3/providers/dns/exec/exec.go | 113 + .../lego/v3/providers/dns/exec/exec.toml | 111 + .../v3/providers/dns/exoscale/exoscale.go | 184 + .../v3/providers/dns/exoscale/exoscale.toml | 22 + .../lego/v3/providers/dns/fastdns/fastdns.go | 158 + .../v3/providers/dns/fastdns/fastdns.toml | 24 + .../lego/v3/providers/dns/gandi/client.go | 316 + .../lego/v3/providers/dns/gandi/gandi.go | 214 + .../lego/v3/providers/dns/gandi/gandi.toml | 19 + .../lego/v3/providers/dns/gandiv5/client.go | 199 + .../lego/v3/providers/dns/gandiv5/gandiv5.go | 167 + .../v3/providers/dns/gandiv5/gandiv5.toml | 19 + .../lego/v3/providers/dns/gcloud/gcloud.toml | 22 + .../v3/providers/dns/gcloud/googlecloud.go | 337 + .../lego/v3/providers/dns/glesys/client.go | 91 + .../lego/v3/providers/dns/glesys/glesys.go | 146 + .../lego/v3/providers/dns/glesys/glesys.toml | 20 + .../lego/v3/providers/dns/godaddy/client.go | 53 + .../lego/v3/providers/dns/godaddy/godaddy.go | 151 + .../v3/providers/dns/godaddy/godaddy.toml | 19 + .../lego/v3/providers/dns/hostingde/client.go | 127 + .../v3/providers/dns/hostingde/hostingde.go | 183 + .../v3/providers/dns/hostingde/hostingde.toml | 20 + .../lego/v3/providers/dns/hostingde/model.go | 139 + .../lego/v3/providers/dns/httpreq/httpreq.go | 195 + .../v3/providers/dns/httpreq/httpreq.toml | 61 + .../go-acme/lego/v3/providers/dns/iij/iij.go | 239 + .../lego/v3/providers/dns/iij/iij.toml | 21 + .../lego/v3/providers/dns/inwx/inwx.go | 166 + .../lego/v3/providers/dns/inwx/inwx.toml | 21 + .../lego/v3/providers/dns/joker/client.go | 210 + .../lego/v3/providers/dns/joker/joker.go | 184 + .../lego/v3/providers/dns/joker/joker.toml | 28 + .../v3/providers/dns/lightsail/lightsail.go | 153 + .../v3/providers/dns/lightsail/lightsail.toml | 19 + .../lego/v3/providers/dns/linode/linode.go | 164 + .../lego/v3/providers/dns/linode/linode.toml | 19 + .../v3/providers/dns/linodev4/linodev4.go | 190 + .../v3/providers/dns/linodev4/linodev4.toml | 19 + .../lego/v3/providers/dns/mydnsjp/client.go | 52 + .../lego/v3/providers/dns/mydnsjp/mydnsjp.go | 93 + .../v3/providers/dns/mydnsjp/mydnsjp.toml | 20 + .../lego/v3/providers/dns/namecheap/client.go | 225 + .../v3/providers/dns/namecheap/namecheap.go | 260 + .../v3/providers/dns/namecheap/namecheap.toml | 20 + .../v3/providers/dns/namedotcom/namedotcom.go | 170 + .../providers/dns/namedotcom/namedotcom.toml | 22 + .../v3/providers/dns/namesilo/namesilo.go | 142 + .../v3/providers/dns/namesilo/namesilo.toml | 22 + .../providers/dns/netcup/internal/client.go | 327 + .../lego/v3/providers/dns/netcup/netcup.go | 182 + .../lego/v3/providers/dns/netcup/netcup.toml | 21 + .../providers/dns/nifcloud/internal/client.go | 234 + .../v3/providers/dns/nifcloud/nifcloud.go | 156 + .../v3/providers/dns/nifcloud/nifcloud.toml | 20 + .../go-acme/lego/v3/providers/dns/ns1/ns1.go | 162 + .../lego/v3/providers/dns/ns1/ns1.toml | 20 + .../dns/oraclecloud/configprovider.go | 101 + .../providers/dns/oraclecloud/oraclecloud.go | 175 + .../dns/oraclecloud/oraclecloud.toml | 35 + .../lego/v3/providers/dns/otc/client.go | 267 + .../go-acme/lego/v3/providers/dns/otc/otc.go | 179 + .../lego/v3/providers/dns/otc/otc.toml | 24 + .../go-acme/lego/v3/providers/dns/ovh/ovh.go | 203 + .../lego/v3/providers/dns/ovh/ovh.toml | 23 + .../lego/v3/providers/dns/pdns/client.go | 220 + .../lego/v3/providers/dns/pdns/pdns.go | 198 + .../lego/v3/providers/dns/pdns/pdns.toml | 30 + .../lego/v3/providers/dns/rackspace/client.go | 205 + .../v3/providers/dns/rackspace/rackspace.go | 159 + .../v3/providers/dns/rackspace/rackspace.toml | 20 + .../lego/v3/providers/dns/rfc2136/rfc2136.go | 183 + .../v3/providers/dns/rfc2136/rfc2136.toml | 23 + .../lego/v3/providers/dns/route53/route53.go | 279 + .../v3/providers/dns/route53/route53.toml | 69 + .../v3/providers/dns/sakuracloud/client.go | 106 + .../providers/dns/sakuracloud/sakuracloud.go | 101 + .../dns/sakuracloud/sakuracloud.toml | 21 + .../providers/dns/selectel/internal/client.go | 221 + .../v3/providers/dns/selectel/selectel.go | 154 + .../v3/providers/dns/selectel/selectel.toml | 20 + .../lego/v3/providers/dns/stackpath/client.go | 217 + .../v3/providers/dns/stackpath/stackpath.go | 150 + .../v3/providers/dns/stackpath/stackpath.toml | 20 + .../lego/v3/providers/dns/transip/transip.go | 160 + .../v3/providers/dns/transip/transip.toml | 21 + .../lego/v3/providers/dns/vegadns/vegadns.go | 113 + .../v3/providers/dns/vegadns/vegadns.toml | 22 + .../lego/v3/providers/dns/versio/client.go | 127 + .../lego/v3/providers/dns/versio/versio.go | 155 + .../lego/v3/providers/dns/versio/versio.toml | 30 + .../providers/dns/vscale/internal/client.go | 221 + .../lego/v3/providers/dns/vscale/vscale.go | 155 + .../lego/v3/providers/dns/vscale/vscale.toml | 20 + .../lego/v3/providers/dns/vultr/vultr.go | 182 + .../lego/v3/providers/dns/vultr/vultr.toml | 20 + .../lego/v3/providers/dns/zoneee/client.go | 132 + .../lego/v3/providers/dns/zoneee/zoneee.go | 134 + .../lego/v3/providers/dns/zoneee/zoneee.toml | 21 + .../lego/v3/providers/http/webroot/webroot.go | 53 + .../github.com/go-errors/errors/.travis.yml | 5 + .../github.com/go-errors/errors/LICENSE.MIT | 7 + vendor/github.com/go-errors/errors/README.md | 66 + vendor/github.com/go-errors/errors/cover.out | 89 + vendor/github.com/go-errors/errors/error.go | 217 + .../go-errors/errors/parse_panic.go | 127 + .../github.com/go-errors/errors/stackframe.go | 102 + vendor/github.com/go-ini/ini/.gitignore | 6 + vendor/github.com/go-ini/ini/.travis.yml | 18 + vendor/github.com/go-ini/ini/LICENSE | 191 + vendor/github.com/go-ini/ini/Makefile | 15 + vendor/github.com/go-ini/ini/README.md | 46 + vendor/github.com/go-ini/ini/error.go | 34 + vendor/github.com/go-ini/ini/file.go | 418 + vendor/github.com/go-ini/ini/ini.go | 223 + vendor/github.com/go-ini/ini/key.go | 753 + vendor/github.com/go-ini/ini/parser.go | 487 + vendor/github.com/go-ini/ini/section.go | 256 + vendor/github.com/go-ini/ini/struct.go | 548 + vendor/github.com/gofrs/uuid/.gitignore | 15 + vendor/github.com/gofrs/uuid/.travis.yml | 23 + vendor/github.com/gofrs/uuid/LICENSE | 20 + vendor/github.com/gofrs/uuid/README.md | 109 + vendor/github.com/gofrs/uuid/codec.go | 212 + vendor/github.com/gofrs/uuid/fuzz.go | 47 + vendor/github.com/gofrs/uuid/generator.go | 299 + vendor/github.com/gofrs/uuid/sql.go | 109 + vendor/github.com/gofrs/uuid/uuid.go | 189 + .../golang/protobuf/jsonpb/jsonpb.go | 1271 + .../protoc-gen-go/descriptor/descriptor.pb.go | 2887 ++ .../protoc-gen-go/descriptor/descriptor.proto | 883 + .../protoc-gen-go/generator/generator.go | 2806 ++ .../generator/internal/remap/remap.go | 117 + .../protoc-gen-go/plugin/plugin.pb.go | 369 + .../protoc-gen-go/plugin/plugin.pb.golden | 83 + .../protoc-gen-go/plugin/plugin.proto | 167 + .../github.com/golang/protobuf/ptypes/any.go | 141 + .../golang/protobuf/ptypes/any/any.pb.go | 200 + .../golang/protobuf/ptypes/any/any.proto | 154 + .../github.com/golang/protobuf/ptypes/doc.go | 35 + .../golang/protobuf/ptypes/duration.go | 102 + .../protobuf/ptypes/duration/duration.pb.go | 161 + .../protobuf/ptypes/duration/duration.proto | 117 + .../protobuf/ptypes/struct/struct.pb.go | 336 + .../protobuf/ptypes/struct/struct.proto | 96 + .../golang/protobuf/ptypes/timestamp.go | 132 + .../protobuf/ptypes/timestamp/timestamp.pb.go | 179 + .../protobuf/ptypes/timestamp/timestamp.proto | 135 + .../protobuf/ptypes/wrappers/wrappers.pb.go | 461 + .../protobuf/ptypes/wrappers/wrappers.proto | 118 + .../github.com/google/go-querystring/LICENSE | 27 + .../google/go-querystring/query/encode.go | 320 + vendor/github.com/google/uuid/.travis.yml | 9 + vendor/github.com/google/uuid/CONTRIBUTING.md | 10 + vendor/github.com/google/uuid/CONTRIBUTORS | 9 + vendor/github.com/google/uuid/LICENSE | 27 + vendor/github.com/google/uuid/README.md | 19 + vendor/github.com/google/uuid/dce.go | 80 + vendor/github.com/google/uuid/doc.go | 12 + vendor/github.com/google/uuid/go.mod | 1 + vendor/github.com/google/uuid/hash.go | 53 + vendor/github.com/google/uuid/marshal.go | 37 + vendor/github.com/google/uuid/node.go | 90 + vendor/github.com/google/uuid/node_js.go | 12 + vendor/github.com/google/uuid/node_net.go | 33 + vendor/github.com/google/uuid/sql.go | 59 + vendor/github.com/google/uuid/time.go | 123 + vendor/github.com/google/uuid/util.go | 43 + vendor/github.com/google/uuid/uuid.go | 245 + vendor/github.com/google/uuid/version1.go | 44 + vendor/github.com/google/uuid/version4.go | 38 + .../github.com/googleapis/gax-go/v2/LICENSE | 27 + .../googleapis/gax-go/v2/call_option.go | 161 + vendor/github.com/googleapis/gax-go/v2/gax.go | 39 + vendor/github.com/googleapis/gax-go/v2/go.mod | 3 + vendor/github.com/googleapis/gax-go/v2/go.sum | 25 + .../github.com/googleapis/gax-go/v2/header.go | 53 + .../github.com/googleapis/gax-go/v2/invoke.go | 99 + .../gophercloud/gophercloud/.gitignore | 3 + .../gophercloud/gophercloud/.travis.yml | 25 + .../gophercloud/gophercloud/.zuul.yaml | 114 + .../gophercloud/gophercloud/CHANGELOG.md | 69 + .../gophercloud/gophercloud/LICENSE | 191 + .../gophercloud/gophercloud/README.md | 159 + .../gophercloud/gophercloud/auth_options.go | 437 + .../gophercloud/gophercloud/auth_result.go | 52 + .../github.com/gophercloud/gophercloud/doc.go | 110 + .../gophercloud/endpoint_search.go | 76 + .../gophercloud/gophercloud/errors.go | 471 + .../github.com/gophercloud/gophercloud/go.mod | 7 + .../github.com/gophercloud/gophercloud/go.sum | 8 + .../gophercloud/openstack/auth_env.go | 125 + .../gophercloud/openstack/client.go | 438 + .../openstack/dns/v2/recordsets/doc.go | 54 + .../openstack/dns/v2/recordsets/requests.go | 173 + .../openstack/dns/v2/recordsets/results.go | 147 + .../openstack/dns/v2/recordsets/urls.go | 11 + .../gophercloud/openstack/dns/v2/zones/doc.go | 48 + .../openstack/dns/v2/zones/requests.go | 174 + .../openstack/dns/v2/zones/results.go | 166 + .../openstack/dns/v2/zones/urls.go | 11 + .../gophercloud/gophercloud/openstack/doc.go | 14 + .../openstack/endpoint_location.go | 107 + .../gophercloud/openstack/errors.go | 71 + .../openstack/identity/v2/tenants/doc.go | 65 + .../openstack/identity/v2/tenants/requests.go | 116 + .../openstack/identity/v2/tenants/results.go | 91 + .../openstack/identity/v2/tenants/urls.go | 23 + .../openstack/identity/v2/tokens/doc.go | 46 + .../openstack/identity/v2/tokens/requests.go | 103 + .../openstack/identity/v2/tokens/results.go | 174 + .../openstack/identity/v2/tokens/urls.go | 13 + .../openstack/identity/v3/tokens/doc.go | 108 + .../openstack/identity/v3/tokens/requests.go | 162 + .../openstack/identity/v3/tokens/results.go | 178 + .../openstack/identity/v3/tokens/urls.go | 7 + .../openstack/utils/base_endpoint.go | 28 + .../openstack/utils/choose_version.go | 111 + .../gophercloud/pagination/http.go | 60 + .../gophercloud/pagination/linked.go | 92 + .../gophercloud/pagination/marker.go | 58 + .../gophercloud/pagination/pager.go | 251 + .../gophercloud/gophercloud/pagination/pkg.go | 4 + .../gophercloud/pagination/single.go | 33 + .../gophercloud/gophercloud/params.go | 491 + .../gophercloud/provider_client.go | 501 + .../gophercloud/gophercloud/results.go | 448 + .../gophercloud/gophercloud/service_client.go | 154 + .../gophercloud/gophercloud/util.go | 102 + .../grpc-ecosystem/grpc-gateway/LICENSE.txt | 27 + .../grpc-gateway/internal/BUILD.bazel | 22 + .../grpc-gateway/internal/stream_chunk.pb.go | 118 + .../grpc-gateway/internal/stream_chunk.proto | 15 + .../grpc-gateway/runtime/BUILD.bazel | 80 + .../grpc-gateway/runtime/context.go | 210 + .../grpc-gateway/runtime/convert.go | 312 + .../grpc-gateway/runtime/doc.go | 5 + .../grpc-gateway/runtime/errors.go | 145 + .../grpc-gateway/runtime/fieldmask.go | 70 + .../grpc-gateway/runtime/handler.go | 215 + .../runtime/marshal_httpbodyproto.go | 43 + .../grpc-gateway/runtime/marshal_json.go | 45 + .../grpc-gateway/runtime/marshal_jsonpb.go | 242 + .../grpc-gateway/runtime/marshal_proto.go | 62 + .../grpc-gateway/runtime/marshaler.go | 48 + .../runtime/marshaler_registry.go | 91 + .../grpc-gateway/runtime/mux.go | 268 + .../grpc-gateway/runtime/pattern.go | 227 + .../grpc-gateway/runtime/proto2_convert.go | 80 + .../grpc-gateway/runtime/proto_errors.go | 70 + .../grpc-gateway/runtime/query.go | 392 + .../grpc-gateway/utilities/BUILD.bazel | 21 + .../grpc-gateway/utilities/doc.go | 2 + .../grpc-gateway/utilities/pattern.go | 22 + .../grpc-gateway/utilities/readerfactory.go | 20 + .../grpc-gateway/utilities/trie.go | 177 + .../github.com/hashicorp/golang-lru/LICENSE | 362 + .../hashicorp/golang-lru/simplelru/lru.go | 177 + .../golang-lru/simplelru/lru_interface.go | 39 + vendor/github.com/iij/doapi/LICENSE.md | 201 + vendor/github.com/iij/doapi/README.md | 39 + vendor/github.com/iij/doapi/api.go | 170 + vendor/github.com/iij/doapi/parse.go | 267 + .../github.com/iij/doapi/protocol/Commit.go | 44 + .../iij/doapi/protocol/RecordAdd.go | 51 + .../iij/doapi/protocol/RecordDelete.go | 47 + .../iij/doapi/protocol/RecordGet.go | 48 + .../iij/doapi/protocol/RecordListGet.go | 47 + vendor/github.com/iij/doapi/protocol/Reset.go | 45 + .../iij/doapi/protocol/ZoneListGet.go | 45 + .../github.com/iij/doapi/protocol/common.go | 53 + .../jmespath/go-jmespath/.gitignore | 4 + .../jmespath/go-jmespath/.travis.yml | 9 + .../github.com/jmespath/go-jmespath/LICENSE | 13 + .../github.com/jmespath/go-jmespath/Makefile | 44 + .../github.com/jmespath/go-jmespath/README.md | 7 + vendor/github.com/jmespath/go-jmespath/api.go | 49 + .../go-jmespath/astnodetype_string.go | 16 + .../jmespath/go-jmespath/functions.go | 842 + .../jmespath/go-jmespath/interpreter.go | 418 + .../github.com/jmespath/go-jmespath/lexer.go | 420 + .../github.com/jmespath/go-jmespath/parser.go | 603 + .../jmespath/go-jmespath/toktype_string.go | 16 + .../github.com/jmespath/go-jmespath/util.go | 185 + .../github.com/json-iterator/go/.codecov.yml | 3 + vendor/github.com/json-iterator/go/.gitignore | 4 + .../github.com/json-iterator/go/.travis.yml | 14 + vendor/github.com/json-iterator/go/Gopkg.lock | 21 + vendor/github.com/json-iterator/go/Gopkg.toml | 26 + vendor/github.com/json-iterator/go/LICENSE | 21 + vendor/github.com/json-iterator/go/README.md | 91 + vendor/github.com/json-iterator/go/adapter.go | 150 + vendor/github.com/json-iterator/go/any.go | 321 + .../github.com/json-iterator/go/any_array.go | 278 + .../github.com/json-iterator/go/any_bool.go | 137 + .../github.com/json-iterator/go/any_float.go | 83 + .../github.com/json-iterator/go/any_int32.go | 74 + .../github.com/json-iterator/go/any_int64.go | 74 + .../json-iterator/go/any_invalid.go | 82 + vendor/github.com/json-iterator/go/any_nil.go | 69 + .../github.com/json-iterator/go/any_number.go | 123 + .../github.com/json-iterator/go/any_object.go | 374 + vendor/github.com/json-iterator/go/any_str.go | 166 + .../github.com/json-iterator/go/any_uint32.go | 74 + .../github.com/json-iterator/go/any_uint64.go | 74 + vendor/github.com/json-iterator/go/build.sh | 12 + vendor/github.com/json-iterator/go/config.go | 375 + .../go/fuzzy_mode_convert_table.md | 7 + vendor/github.com/json-iterator/go/iter.go | 322 + .../github.com/json-iterator/go/iter_array.go | 58 + .../github.com/json-iterator/go/iter_float.go | 347 + .../github.com/json-iterator/go/iter_int.go | 345 + .../json-iterator/go/iter_object.go | 251 + .../github.com/json-iterator/go/iter_skip.go | 129 + .../json-iterator/go/iter_skip_sloppy.go | 144 + .../json-iterator/go/iter_skip_strict.go | 89 + .../github.com/json-iterator/go/iter_str.go | 215 + .../github.com/json-iterator/go/jsoniter.go | 18 + vendor/github.com/json-iterator/go/pool.go | 42 + vendor/github.com/json-iterator/go/reflect.go | 332 + .../json-iterator/go/reflect_array.go | 104 + .../json-iterator/go/reflect_dynamic.go | 70 + .../json-iterator/go/reflect_extension.go | 483 + .../json-iterator/go/reflect_json_number.go | 112 + .../go/reflect_json_raw_message.go | 60 + .../json-iterator/go/reflect_map.go | 326 + .../json-iterator/go/reflect_marshaler.go | 218 + .../json-iterator/go/reflect_native.go | 451 + .../json-iterator/go/reflect_optional.go | 133 + .../json-iterator/go/reflect_slice.go | 99 + .../go/reflect_struct_decoder.go | 1048 + .../go/reflect_struct_encoder.go | 210 + vendor/github.com/json-iterator/go/stream.go | 211 + .../json-iterator/go/stream_float.go | 94 + .../github.com/json-iterator/go/stream_int.go | 190 + .../github.com/json-iterator/go/stream_str.go | 372 + vendor/github.com/json-iterator/go/test.sh | 12 + vendor/github.com/kolo/xmlrpc/LICENSE | 19 + vendor/github.com/kolo/xmlrpc/README.md | 89 + vendor/github.com/kolo/xmlrpc/client.go | 161 + vendor/github.com/kolo/xmlrpc/decoder.go | 473 + vendor/github.com/kolo/xmlrpc/encoder.go | 174 + vendor/github.com/kolo/xmlrpc/request.go | 57 + vendor/github.com/kolo/xmlrpc/response.go | 42 + vendor/github.com/kolo/xmlrpc/test_server.rb | 25 + .../go-windows-terminal-sequences/LICENSE | 9 + .../go-windows-terminal-sequences/README.md | 41 + .../go-windows-terminal-sequences/go.mod | 1 + .../sequences.go | 36 + .../sequences_dummy.go | 11 + .../labbsr0x/bindman-dns-webhook/LICENSE | 21 + .../bindman-dns-webhook/src/client/client.go | 113 + .../src/types/dnsmanager.go | 20 + .../src/types/dnsrecord.go | 40 + .../bindman-dns-webhook/src/types/error.go | 51 + vendor/github.com/labbsr0x/goh/LICENSE | 21 + .../labbsr0x/goh/gohclient/gohclient.go | 114 + vendor/github.com/linode/linodego/.gitignore | 19 + vendor/github.com/linode/linodego/.travis.yml | 23 + .../github.com/linode/linodego/API_SUPPORT.md | 393 + .../github.com/linode/linodego/CHANGELOG.md | 303 + vendor/github.com/linode/linodego/LICENSE | 21 + vendor/github.com/linode/linodego/Makefile | 54 + vendor/github.com/linode/linodego/README.md | 178 + vendor/github.com/linode/linodego/account.go | 45 + .../linode/linodego/account_events.go | 300 + .../linode/linodego/account_invoices.go | 125 + .../linode/linodego/account_notifications.go | 101 + .../linode/linodego/account_oauth_client.go | 190 + .../linode/linodego/account_payments.go | 115 + .../linode/linodego/account_settings.go | 72 + .../linode/linodego/account_users.go | 164 + vendor/github.com/linode/linodego/client.go | 304 + .../linode/linodego/domain_records.go | 195 + vendor/github.com/linode/linodego/domains.go | 295 + vendor/github.com/linode/linodego/env.sample | 2 + vendor/github.com/linode/linodego/errors.go | 109 + vendor/github.com/linode/linodego/go.mod | 14 + vendor/github.com/linode/linodego/go.sum | 27 + vendor/github.com/linode/linodego/images.go | 168 + .../linode/linodego/instance_configs.go | 246 + .../linode/linodego/instance_disks.go | 251 + .../linode/linodego/instance_ips.go | 146 + .../linode/linodego/instance_snapshots.go | 188 + .../linode/linodego/instance_stats.go | 68 + .../linode/linodego/instance_volumes.go | 38 + .../github.com/linode/linodego/instances.go | 493 + vendor/github.com/linode/linodego/kernels.go | 61 + vendor/github.com/linode/linodego/longview.go | 67 + .../linode/linodego/longview_subscriptions.go | 70 + vendor/github.com/linode/linodego/managed.go | 1 + .../github.com/linode/linodego/network_ips.go | 90 + .../linode/linodego/network_pools.go | 50 + .../linode/linodego/network_ranges.go | 50 + .../linode/linodego/nodebalancer.go | 199 + .../linodego/nodebalancer_config_nodes.go | 186 + .../linode/linodego/nodebalancer_configs.go | 334 + .../github.com/linode/linodego/pagination.go | 440 + vendor/github.com/linode/linodego/profile.go | 117 + .../linode/linodego/profile_sshkeys.go | 160 + .../linode/linodego/profile_tokens.go | 195 + vendor/github.com/linode/linodego/regions.go | 64 + .../github.com/linode/linodego/resources.go | 170 + .../linode/linodego/stackscripts.go | 210 + vendor/github.com/linode/linodego/support.go | 88 + vendor/github.com/linode/linodego/tags.go | 219 + vendor/github.com/linode/linodego/types.go | 90 + vendor/github.com/linode/linodego/util.go | 15 + vendor/github.com/linode/linodego/volumes.go | 301 + vendor/github.com/linode/linodego/waitfor.go | 312 + .../github.com/mitchellh/go-homedir/LICENSE | 21 + .../github.com/mitchellh/go-homedir/README.md | 14 + vendor/github.com/mitchellh/go-homedir/go.mod | 1 + .../mitchellh/go-homedir/homedir.go | 167 + .../mitchellh/mapstructure/.travis.yml | 8 + .../mitchellh/mapstructure/CHANGELOG.md | 21 + .../github.com/mitchellh/mapstructure/LICENSE | 21 + .../mitchellh/mapstructure/README.md | 46 + .../mitchellh/mapstructure/decode_hooks.go | 217 + .../mitchellh/mapstructure/error.go | 50 + .../github.com/mitchellh/mapstructure/go.mod | 1 + .../mitchellh/mapstructure/mapstructure.go | 1149 + .../modern-go/concurrent/.gitignore | 1 + .../modern-go/concurrent/.travis.yml | 14 + .../github.com/modern-go/concurrent/LICENSE | 201 + .../github.com/modern-go/concurrent/README.md | 49 + .../modern-go/concurrent/executor.go | 14 + .../modern-go/concurrent/go_above_19.go | 15 + .../modern-go/concurrent/go_below_19.go | 33 + vendor/github.com/modern-go/concurrent/log.go | 13 + .../github.com/modern-go/concurrent/test.sh | 12 + .../concurrent/unbounded_executor.go | 119 + .../github.com/modern-go/reflect2/.gitignore | 2 + .../github.com/modern-go/reflect2/.travis.yml | 15 + .../github.com/modern-go/reflect2/Gopkg.lock | 15 + .../github.com/modern-go/reflect2/Gopkg.toml | 35 + vendor/github.com/modern-go/reflect2/LICENSE | 201 + .../github.com/modern-go/reflect2/README.md | 71 + .../modern-go/reflect2/go_above_17.go | 8 + .../modern-go/reflect2/go_above_19.go | 14 + .../modern-go/reflect2/go_below_17.go | 9 + .../modern-go/reflect2/go_below_19.go | 14 + .../github.com/modern-go/reflect2/reflect2.go | 298 + .../modern-go/reflect2/reflect2_amd64.s | 0 .../modern-go/reflect2/reflect2_kind.go | 30 + .../modern-go/reflect2/relfect2_386.s | 0 .../modern-go/reflect2/relfect2_amd64p32.s | 0 .../modern-go/reflect2/relfect2_arm.s | 0 .../modern-go/reflect2/relfect2_arm64.s | 0 .../modern-go/reflect2/relfect2_mips64x.s | 0 .../modern-go/reflect2/relfect2_mipsx.s | 0 .../modern-go/reflect2/relfect2_ppc64x.s | 0 .../modern-go/reflect2/relfect2_s390x.s | 0 .../modern-go/reflect2/safe_field.go | 58 + .../github.com/modern-go/reflect2/safe_map.go | 101 + .../modern-go/reflect2/safe_slice.go | 92 + .../modern-go/reflect2/safe_struct.go | 29 + .../modern-go/reflect2/safe_type.go | 78 + vendor/github.com/modern-go/reflect2/test.sh | 12 + .../github.com/modern-go/reflect2/type_map.go | 103 + .../modern-go/reflect2/unsafe_array.go | 65 + .../modern-go/reflect2/unsafe_eface.go | 59 + .../modern-go/reflect2/unsafe_field.go | 74 + .../modern-go/reflect2/unsafe_iface.go | 64 + .../modern-go/reflect2/unsafe_link.go | 70 + .../modern-go/reflect2/unsafe_map.go | 138 + .../modern-go/reflect2/unsafe_ptr.go | 46 + .../modern-go/reflect2/unsafe_slice.go | 177 + .../modern-go/reflect2/unsafe_struct.go | 59 + .../modern-go/reflect2/unsafe_type.go | 85 + vendor/github.com/namedotcom/go/LICENSE | 21 + .../github.com/namedotcom/go/namecom/dns.go | 133 + .../namedotcom/go/namecom/dnssecs.go | 102 + .../namedotcom/go/namecom/domains.go | 382 + .../namedotcom/go/namecom/emailforwardings.go | 133 + .../github.com/namedotcom/go/namecom/hello.go | 31 + .../namedotcom/go/namecom/namecom.go | 729 + .../namedotcom/go/namecom/transfers.go | 108 + .../namedotcom/go/namecom/urlforwardings.go | 133 + .../go/namecom/vanitynameservers.go | 133 + vendor/github.com/nrdcg/auroradns/.gitignore | 2 + .../github.com/nrdcg/auroradns/.golangci.toml | 37 + vendor/github.com/nrdcg/auroradns/.travis.yml | 17 + vendor/github.com/nrdcg/auroradns/LICENSE | 373 + vendor/github.com/nrdcg/auroradns/Makefile | 12 + vendor/github.com/nrdcg/auroradns/README.md | 37 + vendor/github.com/nrdcg/auroradns/auth.go | 98 + vendor/github.com/nrdcg/auroradns/client.go | 144 + vendor/github.com/nrdcg/auroradns/go.mod | 1 + vendor/github.com/nrdcg/auroradns/go.sum | 7 + vendor/github.com/nrdcg/auroradns/records.go | 91 + vendor/github.com/nrdcg/auroradns/zones.go | 69 + vendor/github.com/nrdcg/goinwx/.gitignore | 5 + vendor/github.com/nrdcg/goinwx/.golangci.toml | 42 + vendor/github.com/nrdcg/goinwx/.travis.yml | 21 + vendor/github.com/nrdcg/goinwx/LICENSE | 21 + vendor/github.com/nrdcg/goinwx/Makefile | 20 + vendor/github.com/nrdcg/goinwx/README.md | 86 + vendor/github.com/nrdcg/goinwx/account.go | 48 + vendor/github.com/nrdcg/goinwx/contact.go | 148 + vendor/github.com/nrdcg/goinwx/domain.go | 307 + vendor/github.com/nrdcg/goinwx/go.mod | 10 + vendor/github.com/nrdcg/goinwx/go.sum | 9 + vendor/github.com/nrdcg/goinwx/goinwx.go | 112 + vendor/github.com/nrdcg/goinwx/nameserver.go | 283 + vendor/github.com/nrdcg/goinwx/response.go | 28 + vendor/github.com/nrdcg/namesilo/.gitignore | 2 + .../github.com/nrdcg/namesilo/.golangci.toml | 53 + vendor/github.com/nrdcg/namesilo/.travis.yml | 16 + vendor/github.com/nrdcg/namesilo/LICENSE | 373 + vendor/github.com/nrdcg/namesilo/Makefile | 32 + vendor/github.com/nrdcg/namesilo/auth.go | 57 + vendor/github.com/nrdcg/namesilo/go.mod | 8 + vendor/github.com/nrdcg/namesilo/go.sum | 9 + vendor/github.com/nrdcg/namesilo/model.go | 768 + vendor/github.com/nrdcg/namesilo/namesilo.go | 60 + vendor/github.com/nrdcg/namesilo/params.go | 520 + vendor/github.com/nrdcg/namesilo/readme.md | 48 + .../nrdcg/namesilo/zz_gen_client.go | 2192 ++ .../github.com/oracle/oci-go-sdk/LICENSE.txt | 82 + .../oracle/oci-go-sdk/common/client.go | 339 + .../oracle/oci-go-sdk/common/common.go | 156 + .../oracle/oci-go-sdk/common/configuration.go | 535 + .../oracle/oci-go-sdk/common/errors.go | 98 + .../oracle/oci-go-sdk/common/helpers.go | 245 + .../oracle/oci-go-sdk/common/http.go | 971 + .../oracle/oci-go-sdk/common/http_signer.go | 269 + .../oracle/oci-go-sdk/common/log.go | 170 + .../oracle/oci-go-sdk/common/retry.go | 159 + .../oracle/oci-go-sdk/common/version.go | 36 + ...nge_steering_policy_compartment_details.go | 26 + ...ing_policy_compartment_request_response.go | 77 + .../dns/change_zone_compartment_details.go | 26 + ...hange_zone_compartment_request_response.go | 77 + ...eate_steering_policy_attachment_details.go | 38 + ...ring_policy_attachment_request_response.go | 75 + .../dns/create_steering_policy_details.go | 176 + ...create_steering_policy_request_response.go | 75 + .../oci-go-sdk/dns/create_zone_details.go | 71 + .../dns/create_zone_request_response.go | 69 + .../delete_domain_records_request_response.go | 79 + .../dns/delete_r_r_set_request_response.go | 82 + ...ring_policy_attachment_request_response.go | 73 + ...delete_steering_policy_request_response.go | 73 + .../dns/delete_zone_request_response.go | 76 + .../oracle/oci-go-sdk/dns/dns_client.go | 1293 + .../oracle/oci-go-sdk/dns/external_master.go | 31 + .../get_domain_records_request_response.go | 158 + .../dns/get_r_r_set_request_response.go | 105 + ...ring_policy_attachment_request_response.go | 85 + .../get_steering_policy_request_response.go | 85 + .../dns/get_zone_records_request_response.go | 165 + .../dns/get_zone_request_response.go | 81 + ...list_steering_policies_request_response.go | 159 + ...ing_policy_attachments_request_response.go | 163 + .../dns/list_zones_request_response.go | 205 + .../oracle/oci-go-sdk/dns/nameserver.go | 25 + .../dns/patch_domain_records_details.go | 23 + .../patch_domain_records_request_response.go | 98 + .../dns/patch_r_r_set_request_response.go | 101 + .../oci-go-sdk/dns/patch_rr_set_details.go | 23 + .../dns/patch_zone_records_details.go | 23 + .../patch_zone_records_request_response.go | 95 + .../oracle/oci-go-sdk/dns/record.go | 50 + .../oci-go-sdk/dns/record_collection.go | 23 + .../oracle/oci-go-sdk/dns/record_details.go | 49 + .../oracle/oci-go-sdk/dns/record_operation.go | 96 + .../oracle/oci-go-sdk/dns/rr_set.go | 24 + .../oracle/oci-go-sdk/dns/sort_order.go | 33 + .../oracle/oci-go-sdk/dns/steering_policy.go | 224 + .../oci-go-sdk/dns/steering_policy_answer.go | 84 + .../dns/steering_policy_attachment.go | 86 + .../dns/steering_policy_attachment_summary.go | 82 + .../dns/steering_policy_filter_answer_data.go | 28 + .../dns/steering_policy_filter_rule.go | 61 + .../dns/steering_policy_filter_rule_case.go | 33 + .../dns/steering_policy_health_rule.go | 55 + .../dns/steering_policy_health_rule_case.go | 30 + .../dns/steering_policy_limit_rule.go | 61 + .../dns/steering_policy_limit_rule_case.go | 36 + .../steering_policy_priority_answer_data.go | 30 + .../dns/steering_policy_priority_rule.go | 61 + .../dns/steering_policy_priority_rule_case.go | 33 + .../oci-go-sdk/dns/steering_policy_rule.go | 96 + .../oci-go-sdk/dns/steering_policy_summary.go | 160 + .../steering_policy_weighted_answer_data.go | 29 + .../dns/steering_policy_weighted_rule.go | 61 + .../dns/steering_policy_weighted_rule_case.go | 33 + .../github.com/oracle/oci-go-sdk/dns/tsig.go | 34 + .../dns/update_domain_records_details.go | 23 + .../update_domain_records_request_response.go | 98 + .../dns/update_r_r_set_request_response.go | 101 + .../oci-go-sdk/dns/update_rr_set_details.go | 23 + ...date_steering_policy_attachment_details.go | 29 + ...ring_policy_attachment_request_response.go | 84 + .../dns/update_steering_policy_details.go | 173 + ...update_steering_policy_request_response.go | 84 + .../oci-go-sdk/dns/update_zone_details.go | 39 + .../dns/update_zone_records_details.go | 23 + .../update_zone_records_request_response.go | 95 + .../dns/update_zone_request_response.go | 86 + .../github.com/oracle/oci-go-sdk/dns/zone.go | 125 + .../oracle/oci-go-sdk/dns/zone_summary.go | 118 + vendor/github.com/ovh/go-ovh/LICENSE | 26 + .../ovh/go-ovh/ovh/configuration.go | 130 + .../github.com/ovh/go-ovh/ovh/consumer_key.go | 113 + vendor/github.com/ovh/go-ovh/ovh/error.go | 17 + vendor/github.com/ovh/go-ovh/ovh/logger.go | 15 + vendor/github.com/ovh/go-ovh/ovh/ovh.go | 423 + .../github.com/sacloud/libsacloud/.gitignore | 27 + .../github.com/sacloud/libsacloud/.travis.yml | 12 + .../github.com/sacloud/libsacloud/Dockerfile | 14 + .../github.com/sacloud/libsacloud/LICENSE.txt | 207 + vendor/github.com/sacloud/libsacloud/Makefile | 63 + .../github.com/sacloud/libsacloud/README.md | 301 + .../sacloud/libsacloud/api/archive.go | 374 + .../sacloud/libsacloud/api/archive_gen.go | 251 + .../sacloud/libsacloud/api/auth_status.go | 43 + .../sacloud/libsacloud/api/auto_backup.go | 116 + .../sacloud/libsacloud/api/auto_backup_gen.go | 239 + .../sacloud/libsacloud/api/base_api.go | 278 + .../github.com/sacloud/libsacloud/api/bill.go | 186 + .../sacloud/libsacloud/api/bridge.go | 18 + .../sacloud/libsacloud/api/bridge_gen.go | 243 + .../sacloud/libsacloud/api/cdrom.go | 81 + .../sacloud/libsacloud/api/cdrom_gen.go | 250 + .../sacloud/libsacloud/api/client.go | 633 + .../sacloud/libsacloud/api/coupon.go | 59 + .../sacloud/libsacloud/api/database.go | 430 + .../sacloud/libsacloud/api/database_gen.go | 238 + .../github.com/sacloud/libsacloud/api/disk.go | 350 + .../sacloud/libsacloud/api/disk_gen.go | 228 + .../github.com/sacloud/libsacloud/api/dns.go | 207 + .../sacloud/libsacloud/api/dns_gen.go | 238 + .../github.com/sacloud/libsacloud/api/doc.go | 176 + .../sacloud/libsacloud/api/error.go | 80 + .../github.com/sacloud/libsacloud/api/gslb.go | 202 + .../sacloud/libsacloud/api/gslb_gen.go | 238 + .../github.com/sacloud/libsacloud/api/icon.go | 31 + .../sacloud/libsacloud/api/icon_gen.go | 247 + .../sacloud/libsacloud/api/interface.go | 107 + .../sacloud/libsacloud/api/interface_gen.go | 243 + .../sacloud/libsacloud/api/internet.go | 144 + .../sacloud/libsacloud/api/internet_gen.go | 243 + .../sacloud/libsacloud/api/ipaddress.go | 57 + .../sacloud/libsacloud/api/ipaddress_gen.go | 231 + .../sacloud/libsacloud/api/ipv6addr.go | 97 + .../sacloud/libsacloud/api/ipv6addr_gen.go | 232 + .../sacloud/libsacloud/api/ipv6net.go | 18 + .../sacloud/libsacloud/api/ipv6net_gen.go | 229 + .../sacloud/libsacloud/api/license.go | 18 + .../sacloud/libsacloud/api/license_gen.go | 243 + .../sacloud/libsacloud/api/load_balancer.go | 256 + .../libsacloud/api/load_balancer_gen.go | 238 + .../sacloud/libsacloud/api/mobile_gateway.go | 480 + .../libsacloud/api/mobile_gateway_gen.go | 238 + .../sacloud/libsacloud/api/newsfeed.go | 51 + .../github.com/sacloud/libsacloud/api/nfs.go | 288 + .../sacloud/libsacloud/api/nfs_gen.go | 238 + .../github.com/sacloud/libsacloud/api/note.go | 18 + .../sacloud/libsacloud/api/note_gen.go | 247 + .../sacloud/libsacloud/api/packet_filter.go | 18 + .../libsacloud/api/packet_filter_gen.go | 243 + .../sacloud/libsacloud/api/polling.go | 156 + .../sacloud/libsacloud/api/private_host.go | 18 + .../libsacloud/api/private_host_gen.go | 243 + .../sacloud/libsacloud/api/product_disk.go | 18 + .../libsacloud/api/product_disk_gen.go | 239 + .../libsacloud/api/product_internet.go | 18 + .../libsacloud/api/product_internet_gen.go | 239 + .../sacloud/libsacloud/api/product_license.go | 18 + .../libsacloud/api/product_license_gen.go | 235 + .../libsacloud/api/product_private_host.go | 19 + .../api/product_private_host_gen.go | 239 + .../sacloud/libsacloud/api/product_server.go | 78 + .../libsacloud/api/product_server_gen.go | 239 + .../sacloud/libsacloud/api/proxylb.go | 233 + .../sacloud/libsacloud/api/proxylb_gen.go | 238 + .../sacloud/libsacloud/api/public_price.go | 18 + .../libsacloud/api/public_price_gen.go | 236 + .../libsacloud/api/rate_limit_transport.go | 32 + .../sacloud/libsacloud/api/region.go | 18 + .../sacloud/libsacloud/api/region_gen.go | 239 + .../sacloud/libsacloud/api/server.go | 293 + .../sacloud/libsacloud/api/server_gen.go | 243 + .../github.com/sacloud/libsacloud/api/sim.go | 250 + .../sacloud/libsacloud/api/sim_gen.go | 238 + .../sacloud/libsacloud/api/simple_monitor.go | 152 + .../libsacloud/api/simple_monitor_gen.go | 238 + .../sacloud/libsacloud/api/ssh_key.go | 65 + .../sacloud/libsacloud/api/ssh_key_gen.go | 243 + .../sacloud/libsacloud/api/subnet.go | 18 + .../sacloud/libsacloud/api/subnet_gen.go | 229 + .../sacloud/libsacloud/api/switch.go | 56 + .../sacloud/libsacloud/api/switch_gen.go | 243 + .../sacloud/libsacloud/api/vpc_router.go | 438 + .../sacloud/libsacloud/api/vpc_router_gen.go | 238 + .../sacloud/libsacloud/api/webaccel.go | 115 + .../sacloud/libsacloud/api/webaccel_search.go | 86 + .../github.com/sacloud/libsacloud/api/zone.go | 19 + .../sacloud/libsacloud/api/zone_gen.go | 239 + .../sacloud/libsacloud/docker-compose.yml | 25 + vendor/github.com/sacloud/libsacloud/go.mod | 17 + vendor/github.com/sacloud/libsacloud/go.sum | 26 + .../sacloud/libsacloud/libsacloud.go | 5 + .../sacloud/libsacloud/sacloud/account.go | 9 + .../sacloud/libsacloud/sacloud/appliance.go | 57 + .../sacloud/libsacloud/sacloud/archive.go | 27 + .../sacloud/libsacloud/sacloud/auth_status.go | 79 + .../sacloud/libsacloud/sacloud/auto_backup.go | 88 + .../sacloud/libsacloud/sacloud/bill.go | 32 + .../sacloud/libsacloud/sacloud/bridge.go | 30 + .../sacloud/libsacloud/sacloud/cdrom.go | 17 + .../libsacloud/sacloud/common_types.go | 378 + .../sacloud/libsacloud/sacloud/coupon.go | 14 + .../sacloud/libsacloud/sacloud/database.go | 573 + .../libsacloud/sacloud/database_status.go | 128 + .../libsacloud/sacloud/delete_cache_result.go | 8 + .../sacloud/libsacloud/sacloud/disk.go | 203 + .../sacloud/libsacloud/sacloud/dns.go | 193 + .../sacloud/libsacloud/sacloud/doc.go | 3 + .../sacloud/libsacloud/sacloud/feed.go | 36 + .../sacloud/libsacloud/sacloud/ftp_server.go | 15 + .../sacloud/libsacloud/sacloud/gslb.go | 216 + .../sacloud/libsacloud/sacloud/host.go | 6 + .../sacloud/libsacloud/sacloud/icon.go | 33 + .../sacloud/libsacloud/sacloud/instance.go | 35 + .../sacloud/libsacloud/sacloud/interface.go | 61 + .../sacloud/libsacloud/sacloud/internet.go | 50 + .../sacloud/libsacloud/sacloud/ipaddress.go | 10 + .../sacloud/libsacloud/sacloud/ipv6addr.go | 35 + .../sacloud/libsacloud/sacloud/ipv6net.go | 18 + .../sacloud/libsacloud/sacloud/license.go | 27 + .../libsacloud/sacloud/loadbalancer.go | 291 + .../sacloud/libsacloud/sacloud/lock.go | 29 + .../sacloud/libsacloud/sacloud/member.go | 9 + .../libsacloud/sacloud/mobile_gateway.go | 412 + .../sacloud/libsacloud/sacloud/monitor.go | 356 + .../sacloud/libsacloud/sacloud/nfs.go | 248 + .../sacloud/libsacloud/sacloud/note.go | 16 + .../sacloud/ostype/archive_ostype.go | 138 + .../sacloud/ostype/archiveostypes_string.go | 44 + .../libsacloud/sacloud/packet_filter.go | 248 + .../libsacloud/sacloud/private_host.go | 18 + .../libsacloud/sacloud/product_disk.go | 20 + .../libsacloud/sacloud/product_internet.go | 12 + .../libsacloud/sacloud/product_license.go | 11 + .../libsacloud/sacloud/product_privatehost.go | 13 + .../libsacloud/sacloud/product_server.go | 14 + .../libsacloud/sacloud/prop_assigned_cpu.go | 11 + .../sacloud/prop_assigned_memory.go | 19 + .../libsacloud/sacloud/prop_availability.go | 26 + .../libsacloud/sacloud/prop_bundle_info.go | 27 + .../sacloud/libsacloud/sacloud/prop_class.go | 11 + .../sacloud/prop_connected_switches.go | 45 + .../libsacloud/sacloud/prop_copy_source.go | 56 + .../sacloud/libsacloud/sacloud/prop_cpu.go | 11 + .../libsacloud/sacloud/prop_description.go | 16 + .../sacloud/prop_disk_connection.go | 33 + .../libsacloud/sacloud/prop_disk_size.go | 65 + .../sacloud/libsacloud/sacloud/prop_disks.go | 22 + .../libsacloud/sacloud/prop_distant_from.go | 26 + .../sacloud/libsacloud/sacloud/prop_host.go | 19 + .../libsacloud/sacloud/prop_host_name.go | 11 + .../sacloud/libsacloud/sacloud/prop_icon.go | 47 + .../libsacloud/sacloud/prop_instance.go | 59 + .../sacloud/prop_interface_driver.go | 26 + .../libsacloud/sacloud/prop_interfaces.go | 19 + .../libsacloud/sacloud/prop_job_status.go | 11 + .../sacloud/libsacloud/sacloud/prop_memory.go | 24 + .../sacloud/libsacloud/sacloud/prop_name.go | 16 + .../libsacloud/sacloud/prop_note_class.go | 39 + .../sacloud/prop_original_archive_id.go | 22 + .../libsacloud/sacloud/prop_plan_id.go | 22 + .../libsacloud/sacloud/prop_private_host.go | 21 + .../sacloud/prop_private_host_plan.go | 51 + .../sacloud/libsacloud/sacloud/prop_region.go | 44 + .../sacloud/libsacloud/sacloud/prop_scope.go | 42 + .../sacloud/libsacloud/sacloud/prop_server.go | 21 + .../libsacloud/sacloud/prop_server_plan.go | 64 + .../libsacloud/sacloud/prop_service_class.go | 11 + .../libsacloud/sacloud/prop_storage.go | 11 + .../libsacloud/sacloud/prop_storage_class.go | 11 + .../sacloud/libsacloud/sacloud/prop_switch.go | 21 + .../sacloud/libsacloud/sacloud/prop_tags.go | 57 + .../libsacloud/sacloud/prop_timestamp.go | 35 + .../sacloud/prop_wait_disk_migration.go | 16 + .../sacloud/libsacloud/sacloud/prop_zone.go | 118 + .../sacloud/libsacloud/sacloud/proxylb.go | 554 + .../libsacloud/sacloud/public_price.go | 18 + .../sacloud/libsacloud/sacloud/region.go | 18 + .../sacloud/libsacloud/sacloud/server.go | 265 + .../sacloud/libsacloud/sacloud/sim.go | 140 + .../libsacloud/sacloud/simple_monitor.go | 289 + .../sacloud/sitetosite_connection_detail.go | 38 + .../sacloud/libsacloud/sacloud/ssh_key.go | 38 + .../sacloud/libsacloud/sacloud/storage.go | 18 + .../sacloud/libsacloud/sacloud/subnet.go | 18 + .../sacloud/libsacloud/sacloud/switch.go | 85 + .../sacloud/libsacloud/sacloud/vpc_router.go | 369 + .../libsacloud/sacloud/vpc_router_setting.go | 1178 + .../libsacloud/sacloud/vpc_router_status.go | 27 + .../sacloud/libsacloud/sacloud/webaccel.go | 201 + .../sacloud/libsacloud/sacloud/zone.go | 46 + .../libsacloud/utils/mutexkv/mutexkv.go | 43 + vendor/github.com/sirupsen/logrus/.gitignore | 2 + vendor/github.com/sirupsen/logrus/.travis.yml | 25 + .../github.com/sirupsen/logrus/CHANGELOG.md | 200 + vendor/github.com/sirupsen/logrus/LICENSE | 21 + vendor/github.com/sirupsen/logrus/README.md | 495 + vendor/github.com/sirupsen/logrus/alt_exit.go | 76 + .../github.com/sirupsen/logrus/appveyor.yml | 14 + vendor/github.com/sirupsen/logrus/doc.go | 26 + vendor/github.com/sirupsen/logrus/entry.go | 407 + vendor/github.com/sirupsen/logrus/exported.go | 225 + .../github.com/sirupsen/logrus/formatter.go | 78 + vendor/github.com/sirupsen/logrus/go.mod | 10 + vendor/github.com/sirupsen/logrus/go.sum | 16 + vendor/github.com/sirupsen/logrus/hooks.go | 34 + .../sirupsen/logrus/json_formatter.go | 121 + vendor/github.com/sirupsen/logrus/logger.go | 351 + vendor/github.com/sirupsen/logrus/logrus.go | 186 + .../logrus/terminal_check_appengine.go | 11 + .../sirupsen/logrus/terminal_check_bsd.go | 13 + .../logrus/terminal_check_no_terminal.go | 11 + .../logrus/terminal_check_notappengine.go | 17 + .../sirupsen/logrus/terminal_check_solaris.go | 11 + .../sirupsen/logrus/terminal_check_unix.go | 13 + .../sirupsen/logrus/terminal_check_windows.go | 34 + .../sirupsen/logrus/text_formatter.go | 295 + vendor/github.com/sirupsen/logrus/writer.go | 64 + .../github.com/timewasted/linode/.gitignore | 5 + vendor/github.com/timewasted/linode/LICENSE | 22 + vendor/github.com/timewasted/linode/README.md | 34 + .../github.com/timewasted/linode/dns/dns.go | 69 + .../timewasted/linode/dns/domain.go | 63 + .../timewasted/linode/dns/resource.go | 228 + vendor/github.com/timewasted/linode/errors.go | 73 + vendor/github.com/timewasted/linode/linode.go | 197 + .../timewasted/linode/parameters.go | 54 + .../github.com/transip/gotransip/.travis.yml | 16 + .../transip/gotransip/CONTRIBUTING.md | 11 + vendor/github.com/transip/gotransip/LICENSE | 21 + vendor/github.com/transip/gotransip/README.md | 44 + vendor/github.com/transip/gotransip/api.go | 12 + vendor/github.com/transip/gotransip/client.go | 119 + .../transip/gotransip/domain/api.go | 418 + .../transip/gotransip/domain/domain.go | 506 + vendor/github.com/transip/gotransip/go.mod | 3 + vendor/github.com/transip/gotransip/go.sum | 7 + vendor/github.com/transip/gotransip/sign.go | 49 + vendor/github.com/transip/gotransip/soap.go | 442 + .../github.com/transip/gotransip/util/util.go | 37 + vendor/github.com/vultr/govultr/.codecov.yml | 8 + vendor/github.com/vultr/govultr/.gitignore | 19 + vendor/github.com/vultr/govultr/.travis.yml | 17 + vendor/github.com/vultr/govultr/CHANGELOG.md | 57 + .../github.com/vultr/govultr/CONTRIBUTING.md | 64 + vendor/github.com/vultr/govultr/LICENSE | 21 + vendor/github.com/vultr/govultr/README.md | 94 + vendor/github.com/vultr/govultr/account.go | 45 + vendor/github.com/vultr/govultr/api.go | 44 + .../github.com/vultr/govultr/application.go | 51 + vendor/github.com/vultr/govultr/backup.go | 105 + .../vultr/govultr/bare_metal_server.go | 790 + .../github.com/vultr/govultr/block_storage.go | 319 + .../github.com/vultr/govultr/dns_domains.go | 209 + .../github.com/vultr/govultr/dns_records.go | 150 + .../vultr/govultr/firewall_group.go | 163 + .../github.com/vultr/govultr/firewall_rule.go | 265 + vendor/github.com/vultr/govultr/go.mod | 3 + vendor/github.com/vultr/govultr/govultr.go | 222 + vendor/github.com/vultr/govultr/iso.go | 142 + vendor/github.com/vultr/govultr/network.go | 120 + vendor/github.com/vultr/govultr/os.go | 84 + vendor/github.com/vultr/govultr/plans.go | 199 + vendor/github.com/vultr/govultr/regions.go | 154 + .../github.com/vultr/govultr/reserved_ip.go | 273 + vendor/github.com/vultr/govultr/server.go | 1469 + vendor/github.com/vultr/govultr/snapshot.go | 168 + vendor/github.com/vultr/govultr/ssh_key.go | 140 + .../vultr/govultr/startup_script.go | 172 + vendor/github.com/vultr/govultr/user.go | 157 + vendor/go.opencensus.io/.gitignore | 9 + vendor/go.opencensus.io/.travis.yml | 17 + vendor/go.opencensus.io/AUTHORS | 1 + vendor/go.opencensus.io/CONTRIBUTING.md | 63 + vendor/go.opencensus.io/Gopkg.lock | 231 + vendor/go.opencensus.io/Gopkg.toml | 36 + vendor/go.opencensus.io/LICENSE | 202 + vendor/go.opencensus.io/Makefile | 96 + vendor/go.opencensus.io/README.md | 263 + vendor/go.opencensus.io/appveyor.yml | 25 + vendor/go.opencensus.io/go.mod | 10 + vendor/go.opencensus.io/go.sum | 50 + vendor/go.opencensus.io/internal/internal.go | 37 + vendor/go.opencensus.io/internal/sanitize.go | 50 + .../internal/tagencoding/tagencoding.go | 75 + .../internal/traceinternals.go | 53 + .../go.opencensus.io/metric/metricdata/doc.go | 19 + .../metric/metricdata/exemplar.go | 38 + .../metric/metricdata/label.go | 35 + .../metric/metricdata/metric.go | 46 + .../metric/metricdata/point.go | 193 + .../metric/metricdata/type_string.go | 16 + .../metric/metricdata/unit.go | 27 + .../metric/metricproducer/manager.go | 78 + .../metric/metricproducer/producer.go | 28 + vendor/go.opencensus.io/opencensus.go | 21 + .../go.opencensus.io/plugin/ocgrpc/client.go | 56 + .../plugin/ocgrpc/client_metrics.go | 107 + .../plugin/ocgrpc/client_stats_handler.go | 49 + vendor/go.opencensus.io/plugin/ocgrpc/doc.go | 19 + .../go.opencensus.io/plugin/ocgrpc/server.go | 80 + .../plugin/ocgrpc/server_metrics.go | 97 + .../plugin/ocgrpc/server_stats_handler.go | 63 + .../plugin/ocgrpc/stats_common.go | 227 + .../plugin/ocgrpc/trace_common.go | 107 + .../go.opencensus.io/plugin/ochttp/client.go | 117 + .../plugin/ochttp/client_stats.go | 143 + vendor/go.opencensus.io/plugin/ochttp/doc.go | 19 + .../plugin/ochttp/propagation/b3/b3.go | 123 + .../propagation/tracecontext/propagation.go | 187 + .../go.opencensus.io/plugin/ochttp/route.go | 61 + .../go.opencensus.io/plugin/ochttp/server.go | 449 + .../ochttp/span_annotating_client_trace.go | 169 + .../go.opencensus.io/plugin/ochttp/stats.go | 292 + .../go.opencensus.io/plugin/ochttp/trace.go | 239 + .../plugin/ochttp/wrapped_body.go | 44 + vendor/go.opencensus.io/resource/resource.go | 164 + vendor/go.opencensus.io/stats/doc.go | 69 + .../go.opencensus.io/stats/internal/record.go | 25 + vendor/go.opencensus.io/stats/measure.go | 109 + .../go.opencensus.io/stats/measure_float64.go | 55 + .../go.opencensus.io/stats/measure_int64.go | 55 + vendor/go.opencensus.io/stats/record.go | 117 + vendor/go.opencensus.io/stats/units.go | 25 + .../stats/view/aggregation.go | 120 + .../stats/view/aggregation_data.go | 293 + .../go.opencensus.io/stats/view/collector.go | 86 + vendor/go.opencensus.io/stats/view/doc.go | 47 + vendor/go.opencensus.io/stats/view/export.go | 58 + vendor/go.opencensus.io/stats/view/view.go | 221 + .../stats/view/view_to_metric.go | 140 + vendor/go.opencensus.io/stats/view/worker.go | 281 + .../stats/view/worker_commands.go | 186 + vendor/go.opencensus.io/tag/context.go | 43 + vendor/go.opencensus.io/tag/doc.go | 26 + vendor/go.opencensus.io/tag/key.go | 35 + vendor/go.opencensus.io/tag/map.go | 229 + vendor/go.opencensus.io/tag/map_codec.go | 239 + vendor/go.opencensus.io/tag/metadata.go | 52 + vendor/go.opencensus.io/tag/profile_19.go | 31 + vendor/go.opencensus.io/tag/profile_not19.go | 23 + vendor/go.opencensus.io/tag/validate.go | 56 + vendor/go.opencensus.io/trace/basetypes.go | 119 + vendor/go.opencensus.io/trace/config.go | 86 + vendor/go.opencensus.io/trace/doc.go | 53 + vendor/go.opencensus.io/trace/evictedqueue.go | 38 + vendor/go.opencensus.io/trace/export.go | 97 + .../trace/internal/internal.go | 22 + vendor/go.opencensus.io/trace/lrumap.go | 37 + .../trace/propagation/propagation.go | 108 + vendor/go.opencensus.io/trace/sampling.go | 75 + vendor/go.opencensus.io/trace/spanbucket.go | 130 + vendor/go.opencensus.io/trace/spanstore.go | 306 + vendor/go.opencensus.io/trace/status_codes.go | 37 + vendor/go.opencensus.io/trace/trace.go | 598 + vendor/go.opencensus.io/trace/trace_go11.go | 32 + .../go.opencensus.io/trace/trace_nongo11.go | 25 + .../trace/tracestate/tracestate.go | 147 + vendor/go.uber.org/ratelimit/.gitignore | 2 + vendor/go.uber.org/ratelimit/LICENSE | 21 + vendor/go.uber.org/ratelimit/Makefile | 5 + vendor/go.uber.org/ratelimit/README.md | 40 + vendor/go.uber.org/ratelimit/glide.lock | 10 + vendor/go.uber.org/ratelimit/glide.yaml | 7 + .../ratelimit/internal/clock/clock.go | 133 + .../ratelimit/internal/clock/interface.go | 34 + .../ratelimit/internal/clock/real.go | 42 + .../ratelimit/internal/clock/timers.go | 44 + vendor/go.uber.org/ratelimit/ratelimit.go | 140 + .../golang.org/x/crypto/pkcs12/bmp-string.go | 50 + vendor/golang.org/x/crypto/pkcs12/crypto.go | 131 + vendor/golang.org/x/crypto/pkcs12/errors.go | 23 + .../x/crypto/pkcs12/internal/rc2/rc2.go | 271 + vendor/golang.org/x/crypto/pkcs12/mac.go | 45 + vendor/golang.org/x/crypto/pkcs12/pbkdf.go | 170 + vendor/golang.org/x/crypto/pkcs12/pkcs12.go | 346 + vendor/golang.org/x/crypto/pkcs12/safebags.go | 57 + vendor/golang.org/x/net/context/context.go | 56 + .../x/net/context/ctxhttp/ctxhttp.go | 74 + .../x/net/context/ctxhttp/ctxhttp_pre17.go | 147 + vendor/golang.org/x/net/context/go17.go | 72 + vendor/golang.org/x/net/context/go19.go | 20 + vendor/golang.org/x/net/context/pre_go17.go | 300 + vendor/golang.org/x/net/context/pre_go19.go | 109 + vendor/golang.org/x/net/http/httpguts/guts.go | 50 + .../golang.org/x/net/http/httpguts/httplex.go | 346 + vendor/golang.org/x/net/http2/.gitignore | 2 + vendor/golang.org/x/net/http2/Dockerfile | 51 + vendor/golang.org/x/net/http2/Makefile | 3 + vendor/golang.org/x/net/http2/README | 20 + vendor/golang.org/x/net/http2/ciphers.go | 641 + .../x/net/http2/client_conn_pool.go | 282 + .../x/net/http2/configure_transport.go | 82 + vendor/golang.org/x/net/http2/databuffer.go | 146 + vendor/golang.org/x/net/http2/errors.go | 133 + vendor/golang.org/x/net/http2/flow.go | 50 + vendor/golang.org/x/net/http2/frame.go | 1614 + vendor/golang.org/x/net/http2/go111.go | 26 + vendor/golang.org/x/net/http2/go16.go | 16 + vendor/golang.org/x/net/http2/go17.go | 121 + vendor/golang.org/x/net/http2/go17_not18.go | 36 + vendor/golang.org/x/net/http2/go18.go | 56 + vendor/golang.org/x/net/http2/go19.go | 16 + vendor/golang.org/x/net/http2/gotrack.go | 170 + vendor/golang.org/x/net/http2/headermap.go | 78 + vendor/golang.org/x/net/http2/hpack/encode.go | 240 + vendor/golang.org/x/net/http2/hpack/hpack.go | 496 + .../golang.org/x/net/http2/hpack/huffman.go | 222 + vendor/golang.org/x/net/http2/hpack/tables.go | 479 + vendor/golang.org/x/net/http2/http2.go | 391 + vendor/golang.org/x/net/http2/not_go111.go | 17 + vendor/golang.org/x/net/http2/not_go16.go | 21 + vendor/golang.org/x/net/http2/not_go17.go | 95 + vendor/golang.org/x/net/http2/not_go18.go | 29 + vendor/golang.org/x/net/http2/not_go19.go | 16 + vendor/golang.org/x/net/http2/pipe.go | 163 + vendor/golang.org/x/net/http2/server.go | 2889 ++ vendor/golang.org/x/net/http2/transport.go | 2453 ++ vendor/golang.org/x/net/http2/write.go | 365 + vendor/golang.org/x/net/http2/writesched.go | 242 + .../x/net/http2/writesched_priority.go | 452 + .../x/net/http2/writesched_random.go | 72 + .../x/net/internal/timeseries/timeseries.go | 525 + vendor/golang.org/x/net/publicsuffix/list.go | 170 + vendor/golang.org/x/net/publicsuffix/table.go | 9748 +++++++ vendor/golang.org/x/net/trace/events.go | 532 + vendor/golang.org/x/net/trace/histogram.go | 365 + vendor/golang.org/x/net/trace/trace.go | 1111 + vendor/golang.org/x/net/trace/trace_go16.go | 21 + vendor/golang.org/x/net/trace/trace_go17.go | 21 + vendor/golang.org/x/oauth2/.travis.yml | 13 + vendor/golang.org/x/oauth2/AUTHORS | 3 + vendor/golang.org/x/oauth2/CONTRIBUTING.md | 26 + vendor/golang.org/x/oauth2/CONTRIBUTORS | 3 + vendor/golang.org/x/oauth2/LICENSE | 27 + vendor/golang.org/x/oauth2/README.md | 35 + .../clientcredentials/clientcredentials.go | 120 + vendor/golang.org/x/oauth2/go.mod | 10 + vendor/golang.org/x/oauth2/go.sum | 12 + .../golang.org/x/oauth2/google/appengine.go | 38 + .../x/oauth2/google/appengine_gen1.go | 77 + .../x/oauth2/google/appengine_gen2_flex.go | 27 + vendor/golang.org/x/oauth2/google/default.go | 154 + vendor/golang.org/x/oauth2/google/doc.go | 40 + vendor/golang.org/x/oauth2/google/google.go | 209 + vendor/golang.org/x/oauth2/google/jwt.go | 74 + vendor/golang.org/x/oauth2/google/sdk.go | 201 + .../x/oauth2/internal/client_appengine.go | 13 + vendor/golang.org/x/oauth2/internal/doc.go | 6 + vendor/golang.org/x/oauth2/internal/oauth2.go | 37 + vendor/golang.org/x/oauth2/internal/token.go | 294 + .../golang.org/x/oauth2/internal/transport.go | 33 + vendor/golang.org/x/oauth2/jws/jws.go | 182 + vendor/golang.org/x/oauth2/jwt/jwt.go | 185 + vendor/golang.org/x/oauth2/oauth2.go | 381 + vendor/golang.org/x/oauth2/token.go | 178 + vendor/golang.org/x/oauth2/transport.go | 144 + vendor/golang.org/x/sync/AUTHORS | 3 + vendor/golang.org/x/sync/CONTRIBUTORS | 3 + vendor/golang.org/x/sync/LICENSE | 27 + vendor/golang.org/x/sync/PATENTS | 22 + .../golang.org/x/sync/semaphore/semaphore.go | 127 + vendor/golang.org/x/time/AUTHORS | 3 + vendor/golang.org/x/time/CONTRIBUTORS | 3 + vendor/golang.org/x/time/LICENSE | 27 + vendor/golang.org/x/time/PATENTS | 22 + vendor/golang.org/x/time/rate/rate.go | 374 + vendor/google.golang.org/api/AUTHORS | 10 + vendor/google.golang.org/api/CONTRIBUTORS | 55 + vendor/google.golang.org/api/LICENSE | 27 + .../google.golang.org/api/dns/v1/dns-api.json | 1460 + .../google.golang.org/api/dns/v1/dns-gen.go | 4012 +++ .../api/gensupport/buffer.go | 79 + .../google.golang.org/api/gensupport/doc.go | 10 + .../google.golang.org/api/gensupport/json.go | 211 + .../api/gensupport/jsonfloat.go | 57 + .../google.golang.org/api/gensupport/media.go | 363 + .../api/gensupport/params.go | 51 + .../api/gensupport/resumable.go | 236 + .../google.golang.org/api/gensupport/send.go | 87 + .../api/googleapi/googleapi.go | 403 + .../googleapi/internal/uritemplates/LICENSE | 18 + .../internal/uritemplates/uritemplates.go | 248 + .../googleapi/internal/uritemplates/utils.go | 17 + .../api/googleapi/transport/apikey.go | 38 + .../google.golang.org/api/googleapi/types.go | 202 + .../google.golang.org/api/internal/creds.go | 102 + vendor/google.golang.org/api/internal/pool.go | 61 + .../api/internal/service-account.json | 12 + .../api/internal/settings.go | 96 + .../api/option/credentials_go19.go | 33 + .../api/option/credentials_notgo19.go | 32 + vendor/google.golang.org/api/option/option.go | 235 + .../api/support/bundler/bundler.go | 349 + .../api/transport/http/dial.go | 161 + .../api/transport/http/dial_appengine.go | 30 + .../http/internal/propagation/http.go | 96 + .../google.golang.org/appengine/.travis.yml | 20 + .../appengine/CONTRIBUTING.md | 90 + vendor/google.golang.org/appengine/LICENSE | 202 + vendor/google.golang.org/appengine/README.md | 73 + .../google.golang.org/appengine/appengine.go | 135 + .../appengine/appengine_vm.go | 20 + vendor/google.golang.org/appengine/errors.go | 46 + vendor/google.golang.org/appengine/go.mod | 7 + vendor/google.golang.org/appengine/go.sum | 6 + .../google.golang.org/appengine/identity.go | 142 + .../appengine/internal/api.go | 675 + .../appengine/internal/api_classic.go | 169 + .../appengine/internal/api_common.go | 123 + .../appengine/internal/app_id.go | 28 + .../app_identity/app_identity_service.pb.go | 611 + .../app_identity/app_identity_service.proto | 64 + .../appengine/internal/base/api_base.pb.go | 308 + .../appengine/internal/base/api_base.proto | 33 + .../internal/datastore/datastore_v3.pb.go | 4367 +++ .../internal/datastore/datastore_v3.proto | 551 + .../appengine/internal/identity.go | 55 + .../appengine/internal/identity_classic.go | 61 + .../appengine/internal/identity_flex.go | 11 + .../appengine/internal/identity_vm.go | 134 + .../appengine/internal/internal.go | 110 + .../appengine/internal/log/log_service.pb.go | 1313 + .../appengine/internal/log/log_service.proto | 150 + .../appengine/internal/main.go | 16 + .../appengine/internal/main_common.go | 7 + .../appengine/internal/main_vm.go | 69 + .../appengine/internal/metadata.go | 60 + .../internal/modules/modules_service.pb.go | 786 + .../internal/modules/modules_service.proto | 80 + .../appengine/internal/net.go | 56 + .../appengine/internal/regen.sh | 40 + .../internal/remote_api/remote_api.pb.go | 361 + .../internal/remote_api/remote_api.proto | 44 + .../appengine/internal/transaction.go | 115 + .../internal/urlfetch/urlfetch_service.pb.go | 527 + .../internal/urlfetch/urlfetch_service.proto | 64 + .../google.golang.org/appengine/namespace.go | 25 + vendor/google.golang.org/appengine/timeout.go | 20 + .../appengine/travis_install.sh | 18 + .../appengine/travis_test.sh | 12 + .../appengine/urlfetch/urlfetch.go | 210 + vendor/google.golang.org/genproto/LICENSE | 202 + .../googleapis/api/httpbody/httpbody.pb.go | 142 + .../googleapis/rpc/status/status.pb.go | 159 + .../protobuf/field_mask/field_mask.pb.go | 280 + vendor/google.golang.org/grpc/.travis.yml | 39 + vendor/google.golang.org/grpc/AUTHORS | 1 + vendor/google.golang.org/grpc/CONTRIBUTING.md | 37 + vendor/google.golang.org/grpc/LICENSE | 202 + vendor/google.golang.org/grpc/Makefile | 60 + vendor/google.golang.org/grpc/README.md | 67 + vendor/google.golang.org/grpc/backoff.go | 38 + vendor/google.golang.org/grpc/balancer.go | 391 + .../grpc/balancer/balancer.go | 336 + .../grpc/balancer/base/balancer.go | 178 + .../grpc/balancer/base/base.go | 64 + .../grpc/balancer/roundrobin/roundrobin.go | 83 + .../grpc/balancer_conn_wrappers.go | 315 + .../grpc/balancer_v1_wrapper.go | 341 + .../grpc_binarylog_v1/binarylog.pb.go | 900 + vendor/google.golang.org/grpc/call.go | 74 + vendor/google.golang.org/grpc/clientconn.go | 1356 + vendor/google.golang.org/grpc/codec.go | 50 + vendor/google.golang.org/grpc/codegen.sh | 17 + .../grpc/codes/code_string.go | 62 + vendor/google.golang.org/grpc/codes/codes.go | 197 + .../grpc/connectivity/connectivity.go | 73 + .../grpc/credentials/credentials.go | 338 + .../grpc/credentials/internal/syscallconn.go | 61 + .../internal/syscallconn_appengine.go | 30 + .../grpc/credentials/tls13.go | 30 + vendor/google.golang.org/grpc/dialoptions.go | 532 + vendor/google.golang.org/grpc/doc.go | 24 + .../grpc/encoding/encoding.go | 118 + .../grpc/encoding/proto/proto.go | 110 + vendor/google.golang.org/grpc/go.mod | 19 + vendor/google.golang.org/grpc/go.sum | 33 + .../google.golang.org/grpc/grpclog/grpclog.go | 126 + .../google.golang.org/grpc/grpclog/logger.go | 85 + .../grpc/grpclog/loggerv2.go | 195 + vendor/google.golang.org/grpc/install_gae.sh | 6 + vendor/google.golang.org/grpc/interceptor.go | 77 + .../grpc/internal/backoff/backoff.go | 78 + .../grpc/internal/balancerload/load.go | 46 + .../grpc/internal/binarylog/binarylog.go | 167 + .../internal/binarylog/binarylog_testutil.go | 42 + .../grpc/internal/binarylog/env_config.go | 210 + .../grpc/internal/binarylog/method_logger.go | 423 + .../grpc/internal/binarylog/regenerate.sh | 33 + .../grpc/internal/binarylog/sink.go | 162 + .../grpc/internal/binarylog/util.go | 41 + .../grpc/internal/channelz/funcs.go | 699 + .../grpc/internal/channelz/types.go | 702 + .../grpc/internal/channelz/types_linux.go | 53 + .../grpc/internal/channelz/types_nonlinux.go | 44 + .../grpc/internal/channelz/util_linux.go | 39 + .../grpc/internal/channelz/util_nonlinux.go | 26 + .../grpc/internal/envconfig/envconfig.go | 64 + .../grpc/internal/grpcrand/grpcrand.go | 56 + .../grpc/internal/grpcsync/event.go | 61 + .../grpc/internal/internal.go | 54 + .../grpc/internal/syscall/syscall_linux.go | 114 + .../grpc/internal/syscall/syscall_nonlinux.go | 73 + .../grpc/internal/transport/bdp_estimator.go | 141 + .../grpc/internal/transport/controlbuf.go | 852 + .../grpc/internal/transport/defaults.go | 49 + .../grpc/internal/transport/flowcontrol.go | 218 + .../grpc/internal/transport/handler_server.go | 430 + .../grpc/internal/transport/http2_client.go | 1397 + .../grpc/internal/transport/http2_server.go | 1214 + .../grpc/internal/transport/http_util.go | 676 + .../grpc/internal/transport/log.go | 44 + .../grpc/internal/transport/transport.go | 760 + .../grpc/keepalive/keepalive.go | 85 + .../grpc/metadata/metadata.go | 209 + .../grpc/naming/dns_resolver.go | 293 + .../google.golang.org/grpc/naming/naming.go | 69 + vendor/google.golang.org/grpc/peer/peer.go | 51 + .../google.golang.org/grpc/picker_wrapper.go | 189 + vendor/google.golang.org/grpc/pickfirst.go | 110 + vendor/google.golang.org/grpc/proxy.go | 152 + .../grpc/resolver/dns/dns_resolver.go | 438 + .../grpc/resolver/passthrough/passthrough.go | 57 + .../grpc/resolver/resolver.go | 173 + .../grpc/resolver_conn_wrapper.go | 165 + vendor/google.golang.org/grpc/rpc_util.go | 843 + vendor/google.golang.org/grpc/server.go | 1498 + .../google.golang.org/grpc/service_config.go | 373 + .../google.golang.org/grpc/stats/handlers.go | 63 + vendor/google.golang.org/grpc/stats/stats.go | 300 + .../google.golang.org/grpc/status/status.go | 210 + vendor/google.golang.org/grpc/stream.go | 1498 + vendor/google.golang.org/grpc/tap/tap.go | 51 + vendor/google.golang.org/grpc/trace.go | 126 + vendor/google.golang.org/grpc/version.go | 22 + vendor/google.golang.org/grpc/vet.sh | 129 + vendor/gopkg.in/ini.v1/.gitignore | 6 + vendor/gopkg.in/ini.v1/.travis.yml | 18 + vendor/gopkg.in/ini.v1/LICENSE | 191 + vendor/gopkg.in/ini.v1/Makefile | 15 + vendor/gopkg.in/ini.v1/README.md | 46 + vendor/gopkg.in/ini.v1/error.go | 34 + vendor/gopkg.in/ini.v1/file.go | 418 + vendor/gopkg.in/ini.v1/ini.go | 223 + vendor/gopkg.in/ini.v1/key.go | 753 + vendor/gopkg.in/ini.v1/parser.go | 487 + vendor/gopkg.in/ini.v1/section.go | 256 + vendor/gopkg.in/ini.v1/struct.go | 548 + vendor/gopkg.in/ns1/ns1-go.v2/LICENSE.txt | 678 + .../ns1/ns1-go.v2/rest/account_apikey.go | 140 + .../ns1/ns1-go.v2/rest/account_setting.go | 46 + .../ns1/ns1-go.v2/rest/account_team.go | 138 + .../ns1/ns1-go.v2/rest/account_user.go | 138 + .../ns1/ns1-go.v2/rest/account_warning.go | 47 + vendor/gopkg.in/ns1/ns1-go.v2/rest/client.go | 295 + .../gopkg.in/ns1/ns1-go.v2/rest/data_feed.go | 116 + .../ns1/ns1-go.v2/rest/data_source.go | 126 + vendor/gopkg.in/ns1/ns1-go.v2/rest/doc.go | 2 + .../ns1-go.v2/rest/model/account/apikey.go | 13 + .../ns1/ns1-go.v2/rest/model/account/doc.go | 2 + .../rest/model/account/permissions.go | 44 + .../ns1-go.v2/rest/model/account/settings.go | 21 + .../ns1/ns1-go.v2/rest/model/account/team.go | 8 + .../ns1/ns1-go.v2/rest/model/account/user.go | 19 + .../ns1-go.v2/rest/model/account/warning.go | 17 + .../ns1/ns1-go.v2/rest/model/data/doc.go | 2 + .../ns1/ns1-go.v2/rest/model/data/feed.go | 38 + .../ns1/ns1-go.v2/rest/model/data/meta.go | 524 + .../ns1/ns1-go.v2/rest/model/data/region.go | 10 + .../ns1/ns1-go.v2/rest/model/data/source.go | 28 + .../ns1/ns1-go.v2/rest/model/data/string.go | 48 + .../ns1/ns1-go.v2/rest/model/dns/answer.go | 103 + .../ns1/ns1-go.v2/rest/model/dns/doc.go | 2 + .../ns1/ns1-go.v2/rest/model/dns/record.go | 77 + .../ns1/ns1-go.v2/rest/model/dns/zone.go | 161 + .../ns1/ns1-go.v2/rest/model/filter/doc.go | 2 + .../ns1/ns1-go.v2/rest/model/filter/filter.go | 182 + .../ns1-go.v2/rest/model/monitor/config.go | 4 + .../ns1/ns1-go.v2/rest/model/monitor/doc.go | 2 + .../ns1/ns1-go.v2/rest/model/monitor/job.go | 181 + .../ns1-go.v2/rest/model/monitor/notify.go | 72 + .../ns1/ns1-go.v2/rest/monitor_job.go | 134 + .../ns1/ns1-go.v2/rest/monitor_notify.go | 126 + vendor/gopkg.in/ns1/ns1-go.v2/rest/record.go | 132 + vendor/gopkg.in/ns1/ns1-go.v2/rest/stat.go | 63 + vendor/gopkg.in/ns1/ns1-go.v2/rest/util.go | 42 + vendor/gopkg.in/ns1/ns1-go.v2/rest/zone.go | 140 + vendor/gopkg.in/resty.v1/.gitignore | 28 + vendor/gopkg.in/resty.v1/.travis.yml | 28 + vendor/gopkg.in/resty.v1/BUILD.bazel | 36 + vendor/gopkg.in/resty.v1/LICENSE | 21 + vendor/gopkg.in/resty.v1/README.md | 741 + vendor/gopkg.in/resty.v1/WORKSPACE | 27 + vendor/gopkg.in/resty.v1/client.go | 926 + vendor/gopkg.in/resty.v1/default.go | 327 + vendor/gopkg.in/resty.v1/go.mod | 3 + vendor/gopkg.in/resty.v1/middleware.go | 469 + vendor/gopkg.in/resty.v1/redirect.go | 99 + vendor/gopkg.in/resty.v1/request.go | 586 + vendor/gopkg.in/resty.v1/request16.go | 63 + vendor/gopkg.in/resty.v1/request17.go | 96 + vendor/gopkg.in/resty.v1/response.go | 150 + vendor/gopkg.in/resty.v1/resty.go | 9 + vendor/gopkg.in/resty.v1/retry.go | 118 + vendor/gopkg.in/resty.v1/util.go | 281 + 2020 files changed, 355127 insertions(+) create mode 100644 vendor/cloud.google.com/go/LICENSE create mode 100644 vendor/cloud.google.com/go/compute/metadata/metadata.go create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/.travis.yml create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/CONTRIBUTING.md create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/LICENSE create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/README.md create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/common.go create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/connection.go create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/go.mod create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/go.sum create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/nodeinfo.go create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/ocagent.go create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/options.go create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/transform_spans.go create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/transform_stats_to_metrics.go create mode 100644 vendor/contrib.go.opencensus.io/exporter/ocagent/version.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/LICENSE create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/NOTICE create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/models.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/recordsets.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/version.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/zones.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/version/version.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/README.md create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/config.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/go.sum create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/persist.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/sender.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/token.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/version.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/authorization.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/autorest.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/async.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/auth/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/auth/auth.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/auth/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/auth/go.sum create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/azure.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.sum create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/profile.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/token.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/environments.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/rp.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/client.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/date.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/time.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/utility.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/error.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/autorest/go.sum create mode 100644 vendor/github.com/Azure/go-autorest/autorest/preparer.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/responder.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/sender.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/to/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/autorest/to/convert.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/to/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/autorest/utility.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/validation/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/autorest/validation/error.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/validation/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/autorest/validation/go.sum create mode 100644 vendor/github.com/Azure/go-autorest/autorest/validation/validation.go create mode 100644 vendor/github.com/Azure/go-autorest/autorest/version.go create mode 100644 vendor/github.com/Azure/go-autorest/logger/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/logger/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/logger/logger.go create mode 100644 vendor/github.com/Azure/go-autorest/tracing/LICENSE create mode 100644 vendor/github.com/Azure/go-autorest/tracing/go.mod create mode 100644 vendor/github.com/Azure/go-autorest/tracing/go.sum create mode 100644 vendor/github.com/Azure/go-autorest/tracing/tracing.go create mode 100644 vendor/github.com/OpenDNS/vegadns2client/.gitignore create mode 100644 vendor/github.com/OpenDNS/vegadns2client/LICENSE create mode 100644 vendor/github.com/OpenDNS/vegadns2client/Makefile create mode 100644 vendor/github.com/OpenDNS/vegadns2client/README.md create mode 100644 vendor/github.com/OpenDNS/vegadns2client/client.go create mode 100644 vendor/github.com/OpenDNS/vegadns2client/domains.go create mode 100644 vendor/github.com/OpenDNS/vegadns2client/main.go create mode 100644 vendor/github.com/OpenDNS/vegadns2client/records.go create mode 100644 vendor/github.com/OpenDNS/vegadns2client/tokens.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/LICENSE create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/README.md create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/api.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/client.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/errors.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/README.md create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/errors.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/record.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/service.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/zone.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/README.md create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/config.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/errors.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/log.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/signer.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/README.md create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/errors.go create mode 100644 vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/jsonhooks.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/api_timeout.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/logger.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/debug.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain_group.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain_record.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_access_strategy.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_address_pool.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_monitor.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/change_domain_group.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/change_domain_of_dns_product.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/check_domain_record.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/client.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/create_instance.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain_group.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain_record.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_gtm_access_strategy.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_gtm_address_pool.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_sub_domain_records.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_batch_result_count.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_batch_result_detail.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dns_product_instance.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dns_product_instances.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dnsslb_sub_domains.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_dns_statistics.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_groups.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_info.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_logs.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_ns.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_record_info.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_records.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_statistics.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_statistics_summary.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domains.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategies.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategy.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategy_available_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_available_alert_group.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_address_pool.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_address_pools.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_status.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_system_cname.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instances.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_logs.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_monitor_available_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_monitor_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_logs.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics_history.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics_summary.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_sub_domain_records.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_support_lines.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/get_main_domain_name.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/modify_hichina_domain_dns.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/operate_batch_domain.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/query_create_instance_price.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_dnsslb_status.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_domain_record_status.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_gtm_access_mode.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_gtm_monitor_status.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pool.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pools_in_describe_gtm_access_strategy_available_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pools_in_describe_gtm_instance_address_pools.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addrs.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_available_ttls.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_batch_result_detail.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_batch_result_details.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_product.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_products.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_add_domain.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_dns_product_instance.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domain_info.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domain_ns.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domains.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_group.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_groups.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_log.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_logs.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_records_in_describe_domain_records.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_records_in_describe_sub_domain_records.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domains.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_expect_dns_servers.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_gtm_instance.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_gtm_instances.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_node.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_nodes_in_describe_gtm_monitor_available_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_nodes_in_describe_gtm_monitor_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_line.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategies.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategy.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategy_available_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_log.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_logs.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_new_dns_servers.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_original_dns_servers.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_line.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_lines_in_describe_domain_info.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_lines_in_describe_support_lines.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_log.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_logs.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_rule.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_rules.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_slb_sub_domain.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_slb_sub_domains.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistic.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_dns_statistics.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_statistics.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_statistics_summary.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics_history.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics_summary.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_strategies.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_strategy.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_dnsslb_weight.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_domain_group.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_domain_record.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_access_strategy.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_address_pool.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_instance_global_config.go create mode 100644 vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_monitor.go create mode 100644 vendor/github.com/aws/aws-sdk-go/LICENSE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go/NOTICE.txt create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/client.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/logger.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/convert_types.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/logger.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/validation.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/credentials.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/session.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/types.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/url.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/version.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkuri/path.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go create mode 100644 vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/host.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lightsail/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lightsail/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lightsail/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lightsail/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/customizations.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/unmarshal_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/waiters.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/AUTHORS create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/LICENSE create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1/common.pb.go create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1/metrics.pb.go create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1/resource.pb.go create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go create mode 100644 vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/.gitignore create mode 100644 vendor/github.com/cloudflare/cloudflare-go/.travis.yml create mode 100644 vendor/github.com/cloudflare/cloudflare-go/CODE_OF_CONDUCT.md create mode 100644 vendor/github.com/cloudflare/cloudflare-go/LICENSE create mode 100644 vendor/github.com/cloudflare/cloudflare-go/README.md create mode 100644 vendor/github.com/cloudflare/cloudflare-go/access_application.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/access_policy.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/account_members.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/account_roles.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/accounts.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/argo.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/auditlogs.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/cloudflare.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/custom_hostname.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/custom_pages.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/dns.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/duration.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/errors.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/filter.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/firewall.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/firewall_rules.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/go.mod create mode 100644 vendor/github.com/cloudflare/cloudflare-go/go.sum create mode 100644 vendor/github.com/cloudflare/cloudflare-go/ips.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/keyless.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/load_balancing.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/lockdown.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/logpush.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/options.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/origin_ca.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/page_rules.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/railgun.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/rate_limiting.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/registrar.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/renovate.json create mode 100644 vendor/github.com/cloudflare/cloudflare-go/spectrum.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/ssl.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/universal_ssl.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/user.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/user_agent.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/virtualdns.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/waf.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/workers.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/workers_kv.go create mode 100644 vendor/github.com/cloudflare/cloudflare-go/zone.go create mode 100644 vendor/github.com/cpu/goacmedns/.errcheck_exclude create mode 100644 vendor/github.com/cpu/goacmedns/.gitignore create mode 100644 vendor/github.com/cpu/goacmedns/.travis.yml create mode 100644 vendor/github.com/cpu/goacmedns/LICENSE create mode 100644 vendor/github.com/cpu/goacmedns/README.md create mode 100644 vendor/github.com/cpu/goacmedns/account.go create mode 100644 vendor/github.com/cpu/goacmedns/client.go create mode 100644 vendor/github.com/cpu/goacmedns/storage.go create mode 100644 vendor/github.com/decker502/dnspod-go/LICENSE create mode 100644 vendor/github.com/decker502/dnspod-go/README.md create mode 100644 vendor/github.com/decker502/dnspod-go/dnspod.go create mode 100644 vendor/github.com/decker502/dnspod-go/domain_records.go create mode 100644 vendor/github.com/decker502/dnspod-go/domains.go create mode 100644 vendor/github.com/decker502/dnspod-go/go.mod create mode 100644 vendor/github.com/decker502/dnspod-go/go.sum create mode 100644 vendor/github.com/dgrijalva/jwt-go/.gitignore create mode 100644 vendor/github.com/dgrijalva/jwt-go/.travis.yml create mode 100644 vendor/github.com/dgrijalva/jwt-go/LICENSE create mode 100644 vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md create mode 100644 vendor/github.com/dgrijalva/jwt-go/README.md create mode 100644 vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md create mode 100644 vendor/github.com/dgrijalva/jwt-go/claims.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/doc.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/ecdsa.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/errors.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/hmac.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/map_claims.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/none.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/parser.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/rsa.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/rsa_pss.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/rsa_utils.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/signing_method.go create mode 100644 vendor/github.com/dgrijalva/jwt-go/token.go create mode 100644 vendor/github.com/dimchansky/utfbom/.gitignore create mode 100644 vendor/github.com/dimchansky/utfbom/.travis.yml create mode 100644 vendor/github.com/dimchansky/utfbom/LICENSE create mode 100644 vendor/github.com/dimchansky/utfbom/README.md create mode 100644 vendor/github.com/dimchansky/utfbom/go.mod create mode 100644 vendor/github.com/dimchansky/utfbom/utfbom.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/LICENSE.txt create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/accounts.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/authentication.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/certificates.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/contacts.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/dnsimple.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_collaborators.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_delegation_signer_records.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_dnssec.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_email_forwards.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_pushes.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/identity.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/oauth.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_auto_renewal.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_delegation.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_whois_privacy.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/services.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/services_domains.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates_domains.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates_records.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/tlds.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/users.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/vanity_name_server.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/webhooks.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/zone_distributions.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/zones.go create mode 100644 vendor/github.com/dnsimple/dnsimple-go/dnsimple/zones_records.go create mode 100644 vendor/github.com/exoscale/egoscale/.codeclimate.yml create mode 100644 vendor/github.com/exoscale/egoscale/.gitignore create mode 100644 vendor/github.com/exoscale/egoscale/.golangci.yml create mode 100644 vendor/github.com/exoscale/egoscale/.gometalinter.json create mode 100644 vendor/github.com/exoscale/egoscale/.travis.yml create mode 100644 vendor/github.com/exoscale/egoscale/AUTHORS create mode 100644 vendor/github.com/exoscale/egoscale/CHANGELOG.md create mode 100644 vendor/github.com/exoscale/egoscale/LICENSE create mode 100644 vendor/github.com/exoscale/egoscale/README.md create mode 100644 vendor/github.com/exoscale/egoscale/accounts.go create mode 100644 vendor/github.com/exoscale/egoscale/accounts_response.go create mode 100644 vendor/github.com/exoscale/egoscale/addresses.go create mode 100644 vendor/github.com/exoscale/egoscale/affinity_groups.go create mode 100644 vendor/github.com/exoscale/egoscale/affinitygroups_response.go create mode 100644 vendor/github.com/exoscale/egoscale/apis.go create mode 100644 vendor/github.com/exoscale/egoscale/async_jobs.go create mode 100644 vendor/github.com/exoscale/egoscale/asyncjobs_response.go create mode 100644 vendor/github.com/exoscale/egoscale/cidr.go create mode 100644 vendor/github.com/exoscale/egoscale/client.go create mode 100644 vendor/github.com/exoscale/egoscale/cserrorcode_string.go create mode 100644 vendor/github.com/exoscale/egoscale/dns.go create mode 100644 vendor/github.com/exoscale/egoscale/doc.go create mode 100644 vendor/github.com/exoscale/egoscale/errorcode_string.go create mode 100644 vendor/github.com/exoscale/egoscale/events.go create mode 100644 vendor/github.com/exoscale/egoscale/events_response.go create mode 100644 vendor/github.com/exoscale/egoscale/eventtypes_response.go create mode 100644 vendor/github.com/exoscale/egoscale/go.mod create mode 100644 vendor/github.com/exoscale/egoscale/go.sum create mode 100644 vendor/github.com/exoscale/egoscale/gopher.png create mode 100644 vendor/github.com/exoscale/egoscale/instance_groups.go create mode 100644 vendor/github.com/exoscale/egoscale/instancegroups_response.go create mode 100644 vendor/github.com/exoscale/egoscale/isos.go create mode 100644 vendor/github.com/exoscale/egoscale/isos_response.go create mode 100644 vendor/github.com/exoscale/egoscale/jobstatustype_string.go create mode 100644 vendor/github.com/exoscale/egoscale/macaddress.go create mode 100644 vendor/github.com/exoscale/egoscale/network_offerings.go create mode 100644 vendor/github.com/exoscale/egoscale/networkofferings_response.go create mode 100644 vendor/github.com/exoscale/egoscale/networks.go create mode 100644 vendor/github.com/exoscale/egoscale/networks_response.go create mode 100644 vendor/github.com/exoscale/egoscale/nics.go create mode 100644 vendor/github.com/exoscale/egoscale/nics_response.go create mode 100644 vendor/github.com/exoscale/egoscale/oscategories_response.go create mode 100644 vendor/github.com/exoscale/egoscale/publicipaddresses_response.go create mode 100644 vendor/github.com/exoscale/egoscale/record_string.go create mode 100644 vendor/github.com/exoscale/egoscale/request.go create mode 100644 vendor/github.com/exoscale/egoscale/request_type.go create mode 100644 vendor/github.com/exoscale/egoscale/resource_limits.go create mode 100644 vendor/github.com/exoscale/egoscale/resource_metadata.go create mode 100644 vendor/github.com/exoscale/egoscale/resourcedetails_response.go create mode 100644 vendor/github.com/exoscale/egoscale/resourcelimits_response.go create mode 100644 vendor/github.com/exoscale/egoscale/reversedns.go create mode 100644 vendor/github.com/exoscale/egoscale/runstatus.go create mode 100644 vendor/github.com/exoscale/egoscale/runstatus_event.go create mode 100644 vendor/github.com/exoscale/egoscale/runstatus_incident.go create mode 100644 vendor/github.com/exoscale/egoscale/runstatus_maintenance.go create mode 100644 vendor/github.com/exoscale/egoscale/runstatus_page.go create mode 100644 vendor/github.com/exoscale/egoscale/runstatus_service.go create mode 100644 vendor/github.com/exoscale/egoscale/security_groups.go create mode 100644 vendor/github.com/exoscale/egoscale/securitygroups_response.go create mode 100644 vendor/github.com/exoscale/egoscale/serialization.go create mode 100644 vendor/github.com/exoscale/egoscale/service_offerings.go create mode 100644 vendor/github.com/exoscale/egoscale/serviceofferings_response.go create mode 100644 vendor/github.com/exoscale/egoscale/snapshots.go create mode 100644 vendor/github.com/exoscale/egoscale/snapshots_response.go create mode 100644 vendor/github.com/exoscale/egoscale/ssh_keypairs.go create mode 100644 vendor/github.com/exoscale/egoscale/sshkeypairs_response.go create mode 100644 vendor/github.com/exoscale/egoscale/tags.go create mode 100644 vendor/github.com/exoscale/egoscale/tags_response.go create mode 100644 vendor/github.com/exoscale/egoscale/templates.go create mode 100644 vendor/github.com/exoscale/egoscale/templates_response.go create mode 100644 vendor/github.com/exoscale/egoscale/users.go create mode 100644 vendor/github.com/exoscale/egoscale/users_response.go create mode 100644 vendor/github.com/exoscale/egoscale/uuid.go create mode 100644 vendor/github.com/exoscale/egoscale/version.go create mode 100644 vendor/github.com/exoscale/egoscale/virtual_machines.go create mode 100644 vendor/github.com/exoscale/egoscale/virtualmachines_response.go create mode 100644 vendor/github.com/exoscale/egoscale/volumes.go create mode 100644 vendor/github.com/exoscale/egoscale/volumes_response.go create mode 100644 vendor/github.com/exoscale/egoscale/zones.go create mode 100644 vendor/github.com/exoscale/egoscale/zones_response.go create mode 100644 vendor/github.com/fatih/structs/.gitignore create mode 100644 vendor/github.com/fatih/structs/.travis.yml create mode 100644 vendor/github.com/fatih/structs/LICENSE create mode 100644 vendor/github.com/fatih/structs/README.md create mode 100644 vendor/github.com/fatih/structs/field.go create mode 100644 vendor/github.com/fatih/structs/structs.go create mode 100644 vendor/github.com/fatih/structs/tags.go create mode 100644 vendor/github.com/go-acme/lego/v3/platform/config/env/env.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/acmedns/acmedns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/acmedns/acmedns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/alidns/alidns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/alidns/alidns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/auroradns/auroradns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/auroradns/auroradns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/azure/azure.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/azure/azure.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/bindman/bindman.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/bindman/bindman.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/bluecat.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/bluecat.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/cloudflare/cloudflare.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/cloudflare/cloudflare.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/cloudns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/cloudns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/internal/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/cloudxns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/cloudxns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/internal/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/conoha/conoha.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/conoha/conoha.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/conoha/internal/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/designate/designate.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/designate/designate.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/digitalocean.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/digitalocean.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dns_providers.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dnsimple/dnsimple.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dnsimple/dnsimple.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/dnsmadeeasy.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/dnsmadeeasy.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/internal/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dnspod/dnspod.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dnspod/dnspod.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dode/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dode/dode.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dode/dode.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/dreamhost.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/dreamhost.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/duckdns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/duckdns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dyn/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dyn/dyn.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/dyn/dyn.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/easydns/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/easydns/easydns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/easydns/easydns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/exec/exec.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/exec/exec.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/exoscale/exoscale.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/exoscale/exoscale.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/fastdns/fastdns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/fastdns/fastdns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/gandi/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/gandi/gandi.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/gandi/gandi.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/gandiv5.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/gandiv5.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/gcloud/gcloud.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/gcloud/googlecloud.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/glesys/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/glesys/glesys.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/glesys/glesys.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/godaddy.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/godaddy.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/hostingde.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/hostingde.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/model.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/httpreq/httpreq.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/httpreq/httpreq.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/iij/iij.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/iij/iij.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/inwx/inwx.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/inwx/inwx.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/joker/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/joker/joker.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/joker/joker.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/lightsail/lightsail.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/lightsail/lightsail.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/linode/linode.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/linode/linode.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/linodev4/linodev4.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/linodev4/linodev4.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/mydnsjp.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/mydnsjp.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/namecheap.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/namecheap.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/namedotcom/namedotcom.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/namedotcom/namedotcom.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/namesilo/namesilo.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/namesilo/namesilo.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/netcup/internal/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/netcup/netcup.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/netcup/netcup.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/internal/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/nifcloud.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/nifcloud.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/ns1/ns1.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/ns1/ns1.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/configprovider.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/oraclecloud.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/oraclecloud.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/otc/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/otc/otc.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/otc/otc.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/ovh/ovh.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/ovh/ovh.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/pdns/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/pdns/pdns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/pdns/pdns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/rackspace.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/rackspace.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/rfc2136/rfc2136.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/rfc2136/rfc2136.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/route53/route53.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/route53/route53.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/sakuracloud.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/sakuracloud.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/selectel/internal/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/selectel/selectel.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/selectel/selectel.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/stackpath.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/stackpath.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/transip/transip.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/transip/transip.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/vegadns/vegadns.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/vegadns/vegadns.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/versio/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/versio/versio.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/versio/versio.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/vscale/internal/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/vscale/vscale.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/vscale/vscale.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/vultr/vultr.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/vultr/vultr.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/client.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/zoneee.go create mode 100644 vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/zoneee.toml create mode 100644 vendor/github.com/go-acme/lego/v3/providers/http/webroot/webroot.go create mode 100644 vendor/github.com/go-errors/errors/.travis.yml create mode 100644 vendor/github.com/go-errors/errors/LICENSE.MIT create mode 100644 vendor/github.com/go-errors/errors/README.md create mode 100644 vendor/github.com/go-errors/errors/cover.out create mode 100644 vendor/github.com/go-errors/errors/error.go create mode 100644 vendor/github.com/go-errors/errors/parse_panic.go create mode 100644 vendor/github.com/go-errors/errors/stackframe.go create mode 100644 vendor/github.com/go-ini/ini/.gitignore create mode 100644 vendor/github.com/go-ini/ini/.travis.yml create mode 100644 vendor/github.com/go-ini/ini/LICENSE create mode 100644 vendor/github.com/go-ini/ini/Makefile create mode 100644 vendor/github.com/go-ini/ini/README.md create mode 100644 vendor/github.com/go-ini/ini/error.go create mode 100644 vendor/github.com/go-ini/ini/file.go create mode 100644 vendor/github.com/go-ini/ini/ini.go create mode 100644 vendor/github.com/go-ini/ini/key.go create mode 100644 vendor/github.com/go-ini/ini/parser.go create mode 100644 vendor/github.com/go-ini/ini/section.go create mode 100644 vendor/github.com/go-ini/ini/struct.go create mode 100644 vendor/github.com/gofrs/uuid/.gitignore create mode 100644 vendor/github.com/gofrs/uuid/.travis.yml create mode 100644 vendor/github.com/gofrs/uuid/LICENSE create mode 100644 vendor/github.com/gofrs/uuid/README.md create mode 100644 vendor/github.com/gofrs/uuid/codec.go create mode 100644 vendor/github.com/gofrs/uuid/fuzz.go create mode 100644 vendor/github.com/gofrs/uuid/generator.go create mode 100644 vendor/github.com/gofrs/uuid/sql.go create mode 100644 vendor/github.com/gofrs/uuid/uuid.go create mode 100644 vendor/github.com/golang/protobuf/jsonpb/jsonpb.go create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/generator/generator.go create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/generator/internal/remap/remap.go create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.golden create mode 100644 vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto create mode 100644 vendor/github.com/golang/protobuf/ptypes/any.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/any/any.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/any/any.proto create mode 100644 vendor/github.com/golang/protobuf/ptypes/doc.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/duration.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/duration/duration.proto create mode 100644 vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/struct/struct.proto create mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto create mode 100644 vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go create mode 100644 vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.proto create mode 100644 vendor/github.com/google/go-querystring/LICENSE create mode 100644 vendor/github.com/google/go-querystring/query/encode.go create mode 100644 vendor/github.com/google/uuid/.travis.yml create mode 100644 vendor/github.com/google/uuid/CONTRIBUTING.md create mode 100644 vendor/github.com/google/uuid/CONTRIBUTORS create mode 100644 vendor/github.com/google/uuid/LICENSE create mode 100644 vendor/github.com/google/uuid/README.md create mode 100644 vendor/github.com/google/uuid/dce.go create mode 100644 vendor/github.com/google/uuid/doc.go create mode 100644 vendor/github.com/google/uuid/go.mod create mode 100644 vendor/github.com/google/uuid/hash.go create mode 100644 vendor/github.com/google/uuid/marshal.go create mode 100644 vendor/github.com/google/uuid/node.go create mode 100644 vendor/github.com/google/uuid/node_js.go create mode 100644 vendor/github.com/google/uuid/node_net.go create mode 100644 vendor/github.com/google/uuid/sql.go create mode 100644 vendor/github.com/google/uuid/time.go create mode 100644 vendor/github.com/google/uuid/util.go create mode 100644 vendor/github.com/google/uuid/uuid.go create mode 100644 vendor/github.com/google/uuid/version1.go create mode 100644 vendor/github.com/google/uuid/version4.go create mode 100644 vendor/github.com/googleapis/gax-go/v2/LICENSE create mode 100644 vendor/github.com/googleapis/gax-go/v2/call_option.go create mode 100644 vendor/github.com/googleapis/gax-go/v2/gax.go create mode 100644 vendor/github.com/googleapis/gax-go/v2/go.mod create mode 100644 vendor/github.com/googleapis/gax-go/v2/go.sum create mode 100644 vendor/github.com/googleapis/gax-go/v2/header.go create mode 100644 vendor/github.com/googleapis/gax-go/v2/invoke.go create mode 100644 vendor/github.com/gophercloud/gophercloud/.gitignore create mode 100644 vendor/github.com/gophercloud/gophercloud/.travis.yml create mode 100644 vendor/github.com/gophercloud/gophercloud/.zuul.yaml create mode 100644 vendor/github.com/gophercloud/gophercloud/CHANGELOG.md create mode 100644 vendor/github.com/gophercloud/gophercloud/LICENSE create mode 100644 vendor/github.com/gophercloud/gophercloud/README.md create mode 100644 vendor/github.com/gophercloud/gophercloud/auth_options.go create mode 100644 vendor/github.com/gophercloud/gophercloud/auth_result.go create mode 100644 vendor/github.com/gophercloud/gophercloud/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/endpoint_search.go create mode 100644 vendor/github.com/gophercloud/gophercloud/errors.go create mode 100644 vendor/github.com/gophercloud/gophercloud/go.mod create mode 100644 vendor/github.com/gophercloud/gophercloud/go.sum create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/client.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/urls.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/urls.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/errors.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/urls.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/urls.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/doc.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/urls.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go create mode 100644 vendor/github.com/gophercloud/gophercloud/openstack/utils/choose_version.go create mode 100644 vendor/github.com/gophercloud/gophercloud/pagination/http.go create mode 100644 vendor/github.com/gophercloud/gophercloud/pagination/linked.go create mode 100644 vendor/github.com/gophercloud/gophercloud/pagination/marker.go create mode 100644 vendor/github.com/gophercloud/gophercloud/pagination/pager.go create mode 100644 vendor/github.com/gophercloud/gophercloud/pagination/pkg.go create mode 100644 vendor/github.com/gophercloud/gophercloud/pagination/single.go create mode 100644 vendor/github.com/gophercloud/gophercloud/params.go create mode 100644 vendor/github.com/gophercloud/gophercloud/provider_client.go create mode 100644 vendor/github.com/gophercloud/gophercloud/results.go create mode 100644 vendor/github.com/gophercloud/gophercloud/service_client.go create mode 100644 vendor/github.com/gophercloud/gophercloud/util.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.proto create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go create mode 100644 vendor/github.com/hashicorp/golang-lru/LICENSE create mode 100644 vendor/github.com/hashicorp/golang-lru/simplelru/lru.go create mode 100644 vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go create mode 100644 vendor/github.com/iij/doapi/LICENSE.md create mode 100644 vendor/github.com/iij/doapi/README.md create mode 100644 vendor/github.com/iij/doapi/api.go create mode 100644 vendor/github.com/iij/doapi/parse.go create mode 100644 vendor/github.com/iij/doapi/protocol/Commit.go create mode 100644 vendor/github.com/iij/doapi/protocol/RecordAdd.go create mode 100644 vendor/github.com/iij/doapi/protocol/RecordDelete.go create mode 100644 vendor/github.com/iij/doapi/protocol/RecordGet.go create mode 100644 vendor/github.com/iij/doapi/protocol/RecordListGet.go create mode 100644 vendor/github.com/iij/doapi/protocol/Reset.go create mode 100644 vendor/github.com/iij/doapi/protocol/ZoneListGet.go create mode 100644 vendor/github.com/iij/doapi/protocol/common.go create mode 100644 vendor/github.com/jmespath/go-jmespath/.gitignore create mode 100644 vendor/github.com/jmespath/go-jmespath/.travis.yml create mode 100644 vendor/github.com/jmespath/go-jmespath/LICENSE create mode 100644 vendor/github.com/jmespath/go-jmespath/Makefile create mode 100644 vendor/github.com/jmespath/go-jmespath/README.md create mode 100644 vendor/github.com/jmespath/go-jmespath/api.go create mode 100644 vendor/github.com/jmespath/go-jmespath/astnodetype_string.go create mode 100644 vendor/github.com/jmespath/go-jmespath/functions.go create mode 100644 vendor/github.com/jmespath/go-jmespath/interpreter.go create mode 100644 vendor/github.com/jmespath/go-jmespath/lexer.go create mode 100644 vendor/github.com/jmespath/go-jmespath/parser.go create mode 100644 vendor/github.com/jmespath/go-jmespath/toktype_string.go create mode 100644 vendor/github.com/jmespath/go-jmespath/util.go create mode 100644 vendor/github.com/json-iterator/go/.codecov.yml create mode 100644 vendor/github.com/json-iterator/go/.gitignore create mode 100644 vendor/github.com/json-iterator/go/.travis.yml create mode 100644 vendor/github.com/json-iterator/go/Gopkg.lock create mode 100644 vendor/github.com/json-iterator/go/Gopkg.toml create mode 100644 vendor/github.com/json-iterator/go/LICENSE create mode 100644 vendor/github.com/json-iterator/go/README.md create mode 100644 vendor/github.com/json-iterator/go/adapter.go create mode 100644 vendor/github.com/json-iterator/go/any.go create mode 100644 vendor/github.com/json-iterator/go/any_array.go create mode 100644 vendor/github.com/json-iterator/go/any_bool.go create mode 100644 vendor/github.com/json-iterator/go/any_float.go create mode 100644 vendor/github.com/json-iterator/go/any_int32.go create mode 100644 vendor/github.com/json-iterator/go/any_int64.go create mode 100644 vendor/github.com/json-iterator/go/any_invalid.go create mode 100644 vendor/github.com/json-iterator/go/any_nil.go create mode 100644 vendor/github.com/json-iterator/go/any_number.go create mode 100644 vendor/github.com/json-iterator/go/any_object.go create mode 100644 vendor/github.com/json-iterator/go/any_str.go create mode 100644 vendor/github.com/json-iterator/go/any_uint32.go create mode 100644 vendor/github.com/json-iterator/go/any_uint64.go create mode 100644 vendor/github.com/json-iterator/go/build.sh create mode 100644 vendor/github.com/json-iterator/go/config.go create mode 100644 vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md create mode 100644 vendor/github.com/json-iterator/go/iter.go create mode 100644 vendor/github.com/json-iterator/go/iter_array.go create mode 100644 vendor/github.com/json-iterator/go/iter_float.go create mode 100644 vendor/github.com/json-iterator/go/iter_int.go create mode 100644 vendor/github.com/json-iterator/go/iter_object.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip_sloppy.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip_strict.go create mode 100644 vendor/github.com/json-iterator/go/iter_str.go create mode 100644 vendor/github.com/json-iterator/go/jsoniter.go create mode 100644 vendor/github.com/json-iterator/go/pool.go create mode 100644 vendor/github.com/json-iterator/go/reflect.go create mode 100644 vendor/github.com/json-iterator/go/reflect_array.go create mode 100644 vendor/github.com/json-iterator/go/reflect_dynamic.go create mode 100644 vendor/github.com/json-iterator/go/reflect_extension.go create mode 100644 vendor/github.com/json-iterator/go/reflect_json_number.go create mode 100644 vendor/github.com/json-iterator/go/reflect_json_raw_message.go create mode 100644 vendor/github.com/json-iterator/go/reflect_map.go create mode 100644 vendor/github.com/json-iterator/go/reflect_marshaler.go create mode 100644 vendor/github.com/json-iterator/go/reflect_native.go create mode 100644 vendor/github.com/json-iterator/go/reflect_optional.go create mode 100644 vendor/github.com/json-iterator/go/reflect_slice.go create mode 100644 vendor/github.com/json-iterator/go/reflect_struct_decoder.go create mode 100644 vendor/github.com/json-iterator/go/reflect_struct_encoder.go create mode 100644 vendor/github.com/json-iterator/go/stream.go create mode 100644 vendor/github.com/json-iterator/go/stream_float.go create mode 100644 vendor/github.com/json-iterator/go/stream_int.go create mode 100644 vendor/github.com/json-iterator/go/stream_str.go create mode 100644 vendor/github.com/json-iterator/go/test.sh create mode 100644 vendor/github.com/kolo/xmlrpc/LICENSE create mode 100644 vendor/github.com/kolo/xmlrpc/README.md create mode 100644 vendor/github.com/kolo/xmlrpc/client.go create mode 100644 vendor/github.com/kolo/xmlrpc/decoder.go create mode 100644 vendor/github.com/kolo/xmlrpc/encoder.go create mode 100644 vendor/github.com/kolo/xmlrpc/request.go create mode 100644 vendor/github.com/kolo/xmlrpc/response.go create mode 100644 vendor/github.com/kolo/xmlrpc/test_server.rb create mode 100644 vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE create mode 100644 vendor/github.com/konsorten/go-windows-terminal-sequences/README.md create mode 100644 vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod create mode 100644 vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go create mode 100644 vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go create mode 100644 vendor/github.com/labbsr0x/bindman-dns-webhook/LICENSE create mode 100644 vendor/github.com/labbsr0x/bindman-dns-webhook/src/client/client.go create mode 100644 vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/dnsmanager.go create mode 100644 vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/dnsrecord.go create mode 100644 vendor/github.com/labbsr0x/bindman-dns-webhook/src/types/error.go create mode 100644 vendor/github.com/labbsr0x/goh/LICENSE create mode 100644 vendor/github.com/labbsr0x/goh/gohclient/gohclient.go create mode 100644 vendor/github.com/linode/linodego/.gitignore create mode 100644 vendor/github.com/linode/linodego/.travis.yml create mode 100644 vendor/github.com/linode/linodego/API_SUPPORT.md create mode 100644 vendor/github.com/linode/linodego/CHANGELOG.md create mode 100644 vendor/github.com/linode/linodego/LICENSE create mode 100644 vendor/github.com/linode/linodego/Makefile create mode 100644 vendor/github.com/linode/linodego/README.md create mode 100644 vendor/github.com/linode/linodego/account.go create mode 100644 vendor/github.com/linode/linodego/account_events.go create mode 100644 vendor/github.com/linode/linodego/account_invoices.go create mode 100644 vendor/github.com/linode/linodego/account_notifications.go create mode 100644 vendor/github.com/linode/linodego/account_oauth_client.go create mode 100644 vendor/github.com/linode/linodego/account_payments.go create mode 100644 vendor/github.com/linode/linodego/account_settings.go create mode 100644 vendor/github.com/linode/linodego/account_users.go create mode 100644 vendor/github.com/linode/linodego/client.go create mode 100644 vendor/github.com/linode/linodego/domain_records.go create mode 100644 vendor/github.com/linode/linodego/domains.go create mode 100644 vendor/github.com/linode/linodego/env.sample create mode 100644 vendor/github.com/linode/linodego/errors.go create mode 100644 vendor/github.com/linode/linodego/go.mod create mode 100644 vendor/github.com/linode/linodego/go.sum create mode 100644 vendor/github.com/linode/linodego/images.go create mode 100644 vendor/github.com/linode/linodego/instance_configs.go create mode 100644 vendor/github.com/linode/linodego/instance_disks.go create mode 100644 vendor/github.com/linode/linodego/instance_ips.go create mode 100644 vendor/github.com/linode/linodego/instance_snapshots.go create mode 100644 vendor/github.com/linode/linodego/instance_stats.go create mode 100644 vendor/github.com/linode/linodego/instance_volumes.go create mode 100644 vendor/github.com/linode/linodego/instances.go create mode 100644 vendor/github.com/linode/linodego/kernels.go create mode 100644 vendor/github.com/linode/linodego/longview.go create mode 100644 vendor/github.com/linode/linodego/longview_subscriptions.go create mode 100644 vendor/github.com/linode/linodego/managed.go create mode 100644 vendor/github.com/linode/linodego/network_ips.go create mode 100644 vendor/github.com/linode/linodego/network_pools.go create mode 100644 vendor/github.com/linode/linodego/network_ranges.go create mode 100644 vendor/github.com/linode/linodego/nodebalancer.go create mode 100644 vendor/github.com/linode/linodego/nodebalancer_config_nodes.go create mode 100644 vendor/github.com/linode/linodego/nodebalancer_configs.go create mode 100644 vendor/github.com/linode/linodego/pagination.go create mode 100644 vendor/github.com/linode/linodego/profile.go create mode 100644 vendor/github.com/linode/linodego/profile_sshkeys.go create mode 100644 vendor/github.com/linode/linodego/profile_tokens.go create mode 100644 vendor/github.com/linode/linodego/regions.go create mode 100644 vendor/github.com/linode/linodego/resources.go create mode 100644 vendor/github.com/linode/linodego/stackscripts.go create mode 100644 vendor/github.com/linode/linodego/support.go create mode 100644 vendor/github.com/linode/linodego/tags.go create mode 100644 vendor/github.com/linode/linodego/types.go create mode 100644 vendor/github.com/linode/linodego/util.go create mode 100644 vendor/github.com/linode/linodego/volumes.go create mode 100644 vendor/github.com/linode/linodego/waitfor.go create mode 100644 vendor/github.com/mitchellh/go-homedir/LICENSE create mode 100644 vendor/github.com/mitchellh/go-homedir/README.md create mode 100644 vendor/github.com/mitchellh/go-homedir/go.mod create mode 100644 vendor/github.com/mitchellh/go-homedir/homedir.go create mode 100644 vendor/github.com/mitchellh/mapstructure/.travis.yml create mode 100644 vendor/github.com/mitchellh/mapstructure/CHANGELOG.md create mode 100644 vendor/github.com/mitchellh/mapstructure/LICENSE create mode 100644 vendor/github.com/mitchellh/mapstructure/README.md create mode 100644 vendor/github.com/mitchellh/mapstructure/decode_hooks.go create mode 100644 vendor/github.com/mitchellh/mapstructure/error.go create mode 100644 vendor/github.com/mitchellh/mapstructure/go.mod create mode 100644 vendor/github.com/mitchellh/mapstructure/mapstructure.go create mode 100644 vendor/github.com/modern-go/concurrent/.gitignore create mode 100644 vendor/github.com/modern-go/concurrent/.travis.yml create mode 100644 vendor/github.com/modern-go/concurrent/LICENSE create mode 100644 vendor/github.com/modern-go/concurrent/README.md create mode 100644 vendor/github.com/modern-go/concurrent/executor.go create mode 100644 vendor/github.com/modern-go/concurrent/go_above_19.go create mode 100644 vendor/github.com/modern-go/concurrent/go_below_19.go create mode 100644 vendor/github.com/modern-go/concurrent/log.go create mode 100644 vendor/github.com/modern-go/concurrent/test.sh create mode 100644 vendor/github.com/modern-go/concurrent/unbounded_executor.go create mode 100644 vendor/github.com/modern-go/reflect2/.gitignore create mode 100644 vendor/github.com/modern-go/reflect2/.travis.yml create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.lock create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.toml create mode 100644 vendor/github.com/modern-go/reflect2/LICENSE create mode 100644 vendor/github.com/modern-go/reflect2/README.md create mode 100644 vendor/github.com/modern-go/reflect2/go_above_17.go create mode 100644 vendor/github.com/modern-go/reflect2/go_above_19.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_17.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_19.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_amd64.s create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_kind.go create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_386.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm64.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mips64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mipsx.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_s390x.s create mode 100644 vendor/github.com/modern-go/reflect2/safe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_type.go create mode 100644 vendor/github.com/modern-go/reflect2/test.sh create mode 100644 vendor/github.com/modern-go/reflect2/type_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_array.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_eface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_iface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_link.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_ptr.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_type.go create mode 100644 vendor/github.com/namedotcom/go/LICENSE create mode 100644 vendor/github.com/namedotcom/go/namecom/dns.go create mode 100644 vendor/github.com/namedotcom/go/namecom/dnssecs.go create mode 100644 vendor/github.com/namedotcom/go/namecom/domains.go create mode 100644 vendor/github.com/namedotcom/go/namecom/emailforwardings.go create mode 100644 vendor/github.com/namedotcom/go/namecom/hello.go create mode 100644 vendor/github.com/namedotcom/go/namecom/namecom.go create mode 100644 vendor/github.com/namedotcom/go/namecom/transfers.go create mode 100644 vendor/github.com/namedotcom/go/namecom/urlforwardings.go create mode 100644 vendor/github.com/namedotcom/go/namecom/vanitynameservers.go create mode 100644 vendor/github.com/nrdcg/auroradns/.gitignore create mode 100644 vendor/github.com/nrdcg/auroradns/.golangci.toml create mode 100644 vendor/github.com/nrdcg/auroradns/.travis.yml create mode 100644 vendor/github.com/nrdcg/auroradns/LICENSE create mode 100644 vendor/github.com/nrdcg/auroradns/Makefile create mode 100644 vendor/github.com/nrdcg/auroradns/README.md create mode 100644 vendor/github.com/nrdcg/auroradns/auth.go create mode 100644 vendor/github.com/nrdcg/auroradns/client.go create mode 100644 vendor/github.com/nrdcg/auroradns/go.mod create mode 100644 vendor/github.com/nrdcg/auroradns/go.sum create mode 100644 vendor/github.com/nrdcg/auroradns/records.go create mode 100644 vendor/github.com/nrdcg/auroradns/zones.go create mode 100644 vendor/github.com/nrdcg/goinwx/.gitignore create mode 100644 vendor/github.com/nrdcg/goinwx/.golangci.toml create mode 100644 vendor/github.com/nrdcg/goinwx/.travis.yml create mode 100644 vendor/github.com/nrdcg/goinwx/LICENSE create mode 100644 vendor/github.com/nrdcg/goinwx/Makefile create mode 100644 vendor/github.com/nrdcg/goinwx/README.md create mode 100644 vendor/github.com/nrdcg/goinwx/account.go create mode 100644 vendor/github.com/nrdcg/goinwx/contact.go create mode 100644 vendor/github.com/nrdcg/goinwx/domain.go create mode 100644 vendor/github.com/nrdcg/goinwx/go.mod create mode 100644 vendor/github.com/nrdcg/goinwx/go.sum create mode 100644 vendor/github.com/nrdcg/goinwx/goinwx.go create mode 100644 vendor/github.com/nrdcg/goinwx/nameserver.go create mode 100644 vendor/github.com/nrdcg/goinwx/response.go create mode 100644 vendor/github.com/nrdcg/namesilo/.gitignore create mode 100644 vendor/github.com/nrdcg/namesilo/.golangci.toml create mode 100644 vendor/github.com/nrdcg/namesilo/.travis.yml create mode 100644 vendor/github.com/nrdcg/namesilo/LICENSE create mode 100644 vendor/github.com/nrdcg/namesilo/Makefile create mode 100644 vendor/github.com/nrdcg/namesilo/auth.go create mode 100644 vendor/github.com/nrdcg/namesilo/go.mod create mode 100644 vendor/github.com/nrdcg/namesilo/go.sum create mode 100644 vendor/github.com/nrdcg/namesilo/model.go create mode 100644 vendor/github.com/nrdcg/namesilo/namesilo.go create mode 100644 vendor/github.com/nrdcg/namesilo/params.go create mode 100644 vendor/github.com/nrdcg/namesilo/readme.md create mode 100644 vendor/github.com/nrdcg/namesilo/zz_gen_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/LICENSE.txt create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/common.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/configuration.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/errors.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/helpers.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/http.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/http_signer.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/log.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/retry.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/common/version.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/change_steering_policy_compartment_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/change_steering_policy_compartment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/change_zone_compartment_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/change_zone_compartment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_attachment_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/create_steering_policy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/create_zone_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/create_zone_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/delete_domain_records_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/delete_r_r_set_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/delete_steering_policy_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/delete_steering_policy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/delete_zone_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/dns_client.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/external_master.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/get_domain_records_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/get_r_r_set_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/get_steering_policy_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/get_steering_policy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/get_zone_records_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/get_zone_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/list_steering_policies_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/list_steering_policy_attachments_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/list_zones_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/nameserver.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/patch_domain_records_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/patch_domain_records_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/patch_r_r_set_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/patch_rr_set_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/patch_zone_records_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/patch_zone_records_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/record.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/record_collection.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/record_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/record_operation.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/rr_set.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/sort_order.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_answer.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_attachment.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_attachment_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_filter_answer_data.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_filter_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_filter_rule_case.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_health_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_health_rule_case.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_limit_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_limit_rule_case.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_priority_answer_data.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_priority_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_priority_rule_case.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_summary.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_weighted_answer_data.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_weighted_rule.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/steering_policy_weighted_rule_case.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/tsig.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_domain_records_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_domain_records_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_r_r_set_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_rr_set_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_steering_policy_attachment_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_steering_policy_attachment_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_steering_policy_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_steering_policy_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_zone_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_zone_records_details.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_zone_records_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/update_zone_request_response.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/zone.go create mode 100644 vendor/github.com/oracle/oci-go-sdk/dns/zone_summary.go create mode 100644 vendor/github.com/ovh/go-ovh/LICENSE create mode 100644 vendor/github.com/ovh/go-ovh/ovh/configuration.go create mode 100644 vendor/github.com/ovh/go-ovh/ovh/consumer_key.go create mode 100644 vendor/github.com/ovh/go-ovh/ovh/error.go create mode 100644 vendor/github.com/ovh/go-ovh/ovh/logger.go create mode 100644 vendor/github.com/ovh/go-ovh/ovh/ovh.go create mode 100644 vendor/github.com/sacloud/libsacloud/.gitignore create mode 100644 vendor/github.com/sacloud/libsacloud/.travis.yml create mode 100644 vendor/github.com/sacloud/libsacloud/Dockerfile create mode 100644 vendor/github.com/sacloud/libsacloud/LICENSE.txt create mode 100644 vendor/github.com/sacloud/libsacloud/Makefile create mode 100644 vendor/github.com/sacloud/libsacloud/README.md create mode 100644 vendor/github.com/sacloud/libsacloud/api/archive.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/archive_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/auth_status.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/auto_backup.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/auto_backup_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/base_api.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/bill.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/bridge.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/bridge_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/cdrom.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/cdrom_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/client.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/coupon.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/database.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/database_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/disk.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/disk_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/dns.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/dns_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/doc.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/error.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/gslb.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/gslb_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/icon.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/icon_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/interface.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/interface_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/internet.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/internet_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/ipaddress.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/ipaddress_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/ipv6addr.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/ipv6addr_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/ipv6net.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/ipv6net_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/license.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/license_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/load_balancer.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/load_balancer_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/mobile_gateway.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/mobile_gateway_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/newsfeed.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/nfs.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/nfs_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/note.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/note_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/packet_filter.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/packet_filter_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/polling.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/private_host.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/private_host_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_disk.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_disk_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_internet.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_internet_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_license.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_license_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_private_host.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_private_host_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_server.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/product_server_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/proxylb.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/proxylb_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/public_price.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/public_price_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/rate_limit_transport.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/region.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/region_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/server.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/server_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/sim.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/sim_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/simple_monitor.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/simple_monitor_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/ssh_key.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/ssh_key_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/subnet.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/subnet_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/switch.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/switch_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/vpc_router.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/vpc_router_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/webaccel.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/webaccel_search.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/zone.go create mode 100644 vendor/github.com/sacloud/libsacloud/api/zone_gen.go create mode 100644 vendor/github.com/sacloud/libsacloud/docker-compose.yml create mode 100644 vendor/github.com/sacloud/libsacloud/go.mod create mode 100644 vendor/github.com/sacloud/libsacloud/go.sum create mode 100644 vendor/github.com/sacloud/libsacloud/libsacloud.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/account.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/appliance.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/archive.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/auth_status.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/auto_backup.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/bill.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/bridge.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/cdrom.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/common_types.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/coupon.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/database.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/database_status.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/delete_cache_result.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/disk.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/dns.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/doc.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/feed.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/ftp_server.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/gslb.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/host.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/icon.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/instance.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/interface.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/internet.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/ipaddress.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/ipv6addr.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/ipv6net.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/license.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/loadbalancer.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/lock.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/member.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/mobile_gateway.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/monitor.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/nfs.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/note.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/ostype/archive_ostype.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/ostype/archiveostypes_string.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/packet_filter.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/private_host.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/product_disk.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/product_internet.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/product_license.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/product_privatehost.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/product_server.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_assigned_cpu.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_assigned_memory.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_availability.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_bundle_info.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_class.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_connected_switches.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_copy_source.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_cpu.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_description.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_disk_connection.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_disk_size.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_disks.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_distant_from.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_host.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_host_name.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_icon.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_instance.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_interface_driver.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_interfaces.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_job_status.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_memory.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_name.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_note_class.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_original_archive_id.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_plan_id.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_private_host.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_private_host_plan.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_region.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_scope.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_server.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_server_plan.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_service_class.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_storage.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_storage_class.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_switch.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_tags.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_timestamp.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_wait_disk_migration.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/prop_zone.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/proxylb.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/public_price.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/region.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/server.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/sim.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/simple_monitor.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/sitetosite_connection_detail.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/ssh_key.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/storage.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/subnet.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/switch.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/vpc_router.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_setting.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/vpc_router_status.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/webaccel.go create mode 100644 vendor/github.com/sacloud/libsacloud/sacloud/zone.go create mode 100644 vendor/github.com/sacloud/libsacloud/utils/mutexkv/mutexkv.go create mode 100644 vendor/github.com/sirupsen/logrus/.gitignore create mode 100644 vendor/github.com/sirupsen/logrus/.travis.yml create mode 100644 vendor/github.com/sirupsen/logrus/CHANGELOG.md create mode 100644 vendor/github.com/sirupsen/logrus/LICENSE create mode 100644 vendor/github.com/sirupsen/logrus/README.md create mode 100644 vendor/github.com/sirupsen/logrus/alt_exit.go create mode 100644 vendor/github.com/sirupsen/logrus/appveyor.yml create mode 100644 vendor/github.com/sirupsen/logrus/doc.go create mode 100644 vendor/github.com/sirupsen/logrus/entry.go create mode 100644 vendor/github.com/sirupsen/logrus/exported.go create mode 100644 vendor/github.com/sirupsen/logrus/formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/go.mod create mode 100644 vendor/github.com/sirupsen/logrus/go.sum create mode 100644 vendor/github.com/sirupsen/logrus/hooks.go create mode 100644 vendor/github.com/sirupsen/logrus/json_formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/logger.go create mode 100644 vendor/github.com/sirupsen/logrus/logrus.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_appengine.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_bsd.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_solaris.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_unix.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_windows.go create mode 100644 vendor/github.com/sirupsen/logrus/text_formatter.go create mode 100644 vendor/github.com/sirupsen/logrus/writer.go create mode 100644 vendor/github.com/timewasted/linode/.gitignore create mode 100644 vendor/github.com/timewasted/linode/LICENSE create mode 100644 vendor/github.com/timewasted/linode/README.md create mode 100644 vendor/github.com/timewasted/linode/dns/dns.go create mode 100644 vendor/github.com/timewasted/linode/dns/domain.go create mode 100644 vendor/github.com/timewasted/linode/dns/resource.go create mode 100644 vendor/github.com/timewasted/linode/errors.go create mode 100644 vendor/github.com/timewasted/linode/linode.go create mode 100644 vendor/github.com/timewasted/linode/parameters.go create mode 100644 vendor/github.com/transip/gotransip/.travis.yml create mode 100644 vendor/github.com/transip/gotransip/CONTRIBUTING.md create mode 100644 vendor/github.com/transip/gotransip/LICENSE create mode 100644 vendor/github.com/transip/gotransip/README.md create mode 100644 vendor/github.com/transip/gotransip/api.go create mode 100644 vendor/github.com/transip/gotransip/client.go create mode 100644 vendor/github.com/transip/gotransip/domain/api.go create mode 100644 vendor/github.com/transip/gotransip/domain/domain.go create mode 100644 vendor/github.com/transip/gotransip/go.mod create mode 100644 vendor/github.com/transip/gotransip/go.sum create mode 100644 vendor/github.com/transip/gotransip/sign.go create mode 100644 vendor/github.com/transip/gotransip/soap.go create mode 100644 vendor/github.com/transip/gotransip/util/util.go create mode 100644 vendor/github.com/vultr/govultr/.codecov.yml create mode 100644 vendor/github.com/vultr/govultr/.gitignore create mode 100644 vendor/github.com/vultr/govultr/.travis.yml create mode 100644 vendor/github.com/vultr/govultr/CHANGELOG.md create mode 100644 vendor/github.com/vultr/govultr/CONTRIBUTING.md create mode 100644 vendor/github.com/vultr/govultr/LICENSE create mode 100644 vendor/github.com/vultr/govultr/README.md create mode 100644 vendor/github.com/vultr/govultr/account.go create mode 100644 vendor/github.com/vultr/govultr/api.go create mode 100644 vendor/github.com/vultr/govultr/application.go create mode 100644 vendor/github.com/vultr/govultr/backup.go create mode 100644 vendor/github.com/vultr/govultr/bare_metal_server.go create mode 100644 vendor/github.com/vultr/govultr/block_storage.go create mode 100644 vendor/github.com/vultr/govultr/dns_domains.go create mode 100644 vendor/github.com/vultr/govultr/dns_records.go create mode 100644 vendor/github.com/vultr/govultr/firewall_group.go create mode 100644 vendor/github.com/vultr/govultr/firewall_rule.go create mode 100644 vendor/github.com/vultr/govultr/go.mod create mode 100644 vendor/github.com/vultr/govultr/govultr.go create mode 100644 vendor/github.com/vultr/govultr/iso.go create mode 100644 vendor/github.com/vultr/govultr/network.go create mode 100644 vendor/github.com/vultr/govultr/os.go create mode 100644 vendor/github.com/vultr/govultr/plans.go create mode 100644 vendor/github.com/vultr/govultr/regions.go create mode 100644 vendor/github.com/vultr/govultr/reserved_ip.go create mode 100644 vendor/github.com/vultr/govultr/server.go create mode 100644 vendor/github.com/vultr/govultr/snapshot.go create mode 100644 vendor/github.com/vultr/govultr/ssh_key.go create mode 100644 vendor/github.com/vultr/govultr/startup_script.go create mode 100644 vendor/github.com/vultr/govultr/user.go create mode 100644 vendor/go.opencensus.io/.gitignore create mode 100644 vendor/go.opencensus.io/.travis.yml create mode 100644 vendor/go.opencensus.io/AUTHORS create mode 100644 vendor/go.opencensus.io/CONTRIBUTING.md create mode 100644 vendor/go.opencensus.io/Gopkg.lock create mode 100644 vendor/go.opencensus.io/Gopkg.toml create mode 100644 vendor/go.opencensus.io/LICENSE create mode 100644 vendor/go.opencensus.io/Makefile create mode 100644 vendor/go.opencensus.io/README.md create mode 100644 vendor/go.opencensus.io/appveyor.yml create mode 100644 vendor/go.opencensus.io/go.mod create mode 100644 vendor/go.opencensus.io/go.sum create mode 100644 vendor/go.opencensus.io/internal/internal.go create mode 100644 vendor/go.opencensus.io/internal/sanitize.go create mode 100644 vendor/go.opencensus.io/internal/tagencoding/tagencoding.go create mode 100644 vendor/go.opencensus.io/internal/traceinternals.go create mode 100644 vendor/go.opencensus.io/metric/metricdata/doc.go create mode 100644 vendor/go.opencensus.io/metric/metricdata/exemplar.go create mode 100644 vendor/go.opencensus.io/metric/metricdata/label.go create mode 100644 vendor/go.opencensus.io/metric/metricdata/metric.go create mode 100644 vendor/go.opencensus.io/metric/metricdata/point.go create mode 100644 vendor/go.opencensus.io/metric/metricdata/type_string.go create mode 100644 vendor/go.opencensus.io/metric/metricdata/unit.go create mode 100644 vendor/go.opencensus.io/metric/metricproducer/manager.go create mode 100644 vendor/go.opencensus.io/metric/metricproducer/producer.go create mode 100644 vendor/go.opencensus.io/opencensus.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/client.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/client_metrics.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/client_stats_handler.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/doc.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/server.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/server_metrics.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/server_stats_handler.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/stats_common.go create mode 100644 vendor/go.opencensus.io/plugin/ocgrpc/trace_common.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/client.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/client_stats.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/doc.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/propagation/tracecontext/propagation.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/route.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/server.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/span_annotating_client_trace.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/stats.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/trace.go create mode 100644 vendor/go.opencensus.io/plugin/ochttp/wrapped_body.go create mode 100644 vendor/go.opencensus.io/resource/resource.go create mode 100644 vendor/go.opencensus.io/stats/doc.go create mode 100644 vendor/go.opencensus.io/stats/internal/record.go create mode 100644 vendor/go.opencensus.io/stats/measure.go create mode 100644 vendor/go.opencensus.io/stats/measure_float64.go create mode 100644 vendor/go.opencensus.io/stats/measure_int64.go create mode 100644 vendor/go.opencensus.io/stats/record.go create mode 100644 vendor/go.opencensus.io/stats/units.go create mode 100644 vendor/go.opencensus.io/stats/view/aggregation.go create mode 100644 vendor/go.opencensus.io/stats/view/aggregation_data.go create mode 100644 vendor/go.opencensus.io/stats/view/collector.go create mode 100644 vendor/go.opencensus.io/stats/view/doc.go create mode 100644 vendor/go.opencensus.io/stats/view/export.go create mode 100644 vendor/go.opencensus.io/stats/view/view.go create mode 100644 vendor/go.opencensus.io/stats/view/view_to_metric.go create mode 100644 vendor/go.opencensus.io/stats/view/worker.go create mode 100644 vendor/go.opencensus.io/stats/view/worker_commands.go create mode 100644 vendor/go.opencensus.io/tag/context.go create mode 100644 vendor/go.opencensus.io/tag/doc.go create mode 100644 vendor/go.opencensus.io/tag/key.go create mode 100644 vendor/go.opencensus.io/tag/map.go create mode 100644 vendor/go.opencensus.io/tag/map_codec.go create mode 100644 vendor/go.opencensus.io/tag/metadata.go create mode 100644 vendor/go.opencensus.io/tag/profile_19.go create mode 100644 vendor/go.opencensus.io/tag/profile_not19.go create mode 100644 vendor/go.opencensus.io/tag/validate.go create mode 100644 vendor/go.opencensus.io/trace/basetypes.go create mode 100644 vendor/go.opencensus.io/trace/config.go create mode 100644 vendor/go.opencensus.io/trace/doc.go create mode 100644 vendor/go.opencensus.io/trace/evictedqueue.go create mode 100644 vendor/go.opencensus.io/trace/export.go create mode 100644 vendor/go.opencensus.io/trace/internal/internal.go create mode 100644 vendor/go.opencensus.io/trace/lrumap.go create mode 100644 vendor/go.opencensus.io/trace/propagation/propagation.go create mode 100644 vendor/go.opencensus.io/trace/sampling.go create mode 100644 vendor/go.opencensus.io/trace/spanbucket.go create mode 100644 vendor/go.opencensus.io/trace/spanstore.go create mode 100644 vendor/go.opencensus.io/trace/status_codes.go create mode 100644 vendor/go.opencensus.io/trace/trace.go create mode 100644 vendor/go.opencensus.io/trace/trace_go11.go create mode 100644 vendor/go.opencensus.io/trace/trace_nongo11.go create mode 100644 vendor/go.opencensus.io/trace/tracestate/tracestate.go create mode 100644 vendor/go.uber.org/ratelimit/.gitignore create mode 100644 vendor/go.uber.org/ratelimit/LICENSE create mode 100644 vendor/go.uber.org/ratelimit/Makefile create mode 100644 vendor/go.uber.org/ratelimit/README.md create mode 100644 vendor/go.uber.org/ratelimit/glide.lock create mode 100644 vendor/go.uber.org/ratelimit/glide.yaml create mode 100644 vendor/go.uber.org/ratelimit/internal/clock/clock.go create mode 100644 vendor/go.uber.org/ratelimit/internal/clock/interface.go create mode 100644 vendor/go.uber.org/ratelimit/internal/clock/real.go create mode 100644 vendor/go.uber.org/ratelimit/internal/clock/timers.go create mode 100644 vendor/go.uber.org/ratelimit/ratelimit.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/bmp-string.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/crypto.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/errors.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/mac.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/pbkdf.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/pkcs12.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/safebags.go create mode 100644 vendor/golang.org/x/net/context/context.go create mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp.go create mode 100644 vendor/golang.org/x/net/context/ctxhttp/ctxhttp_pre17.go create mode 100644 vendor/golang.org/x/net/context/go17.go create mode 100644 vendor/golang.org/x/net/context/go19.go create mode 100644 vendor/golang.org/x/net/context/pre_go17.go create mode 100644 vendor/golang.org/x/net/context/pre_go19.go create mode 100644 vendor/golang.org/x/net/http/httpguts/guts.go create mode 100644 vendor/golang.org/x/net/http/httpguts/httplex.go create mode 100644 vendor/golang.org/x/net/http2/.gitignore create mode 100644 vendor/golang.org/x/net/http2/Dockerfile create mode 100644 vendor/golang.org/x/net/http2/Makefile create mode 100644 vendor/golang.org/x/net/http2/README create mode 100644 vendor/golang.org/x/net/http2/ciphers.go create mode 100644 vendor/golang.org/x/net/http2/client_conn_pool.go create mode 100644 vendor/golang.org/x/net/http2/configure_transport.go create mode 100644 vendor/golang.org/x/net/http2/databuffer.go create mode 100644 vendor/golang.org/x/net/http2/errors.go create mode 100644 vendor/golang.org/x/net/http2/flow.go create mode 100644 vendor/golang.org/x/net/http2/frame.go create mode 100644 vendor/golang.org/x/net/http2/go111.go create mode 100644 vendor/golang.org/x/net/http2/go16.go create mode 100644 vendor/golang.org/x/net/http2/go17.go create mode 100644 vendor/golang.org/x/net/http2/go17_not18.go create mode 100644 vendor/golang.org/x/net/http2/go18.go create mode 100644 vendor/golang.org/x/net/http2/go19.go create mode 100644 vendor/golang.org/x/net/http2/gotrack.go create mode 100644 vendor/golang.org/x/net/http2/headermap.go create mode 100644 vendor/golang.org/x/net/http2/hpack/encode.go create mode 100644 vendor/golang.org/x/net/http2/hpack/hpack.go create mode 100644 vendor/golang.org/x/net/http2/hpack/huffman.go create mode 100644 vendor/golang.org/x/net/http2/hpack/tables.go create mode 100644 vendor/golang.org/x/net/http2/http2.go create mode 100644 vendor/golang.org/x/net/http2/not_go111.go create mode 100644 vendor/golang.org/x/net/http2/not_go16.go create mode 100644 vendor/golang.org/x/net/http2/not_go17.go create mode 100644 vendor/golang.org/x/net/http2/not_go18.go create mode 100644 vendor/golang.org/x/net/http2/not_go19.go create mode 100644 vendor/golang.org/x/net/http2/pipe.go create mode 100644 vendor/golang.org/x/net/http2/server.go create mode 100644 vendor/golang.org/x/net/http2/transport.go create mode 100644 vendor/golang.org/x/net/http2/write.go create mode 100644 vendor/golang.org/x/net/http2/writesched.go create mode 100644 vendor/golang.org/x/net/http2/writesched_priority.go create mode 100644 vendor/golang.org/x/net/http2/writesched_random.go create mode 100644 vendor/golang.org/x/net/internal/timeseries/timeseries.go create mode 100644 vendor/golang.org/x/net/publicsuffix/list.go create mode 100644 vendor/golang.org/x/net/publicsuffix/table.go create mode 100644 vendor/golang.org/x/net/trace/events.go create mode 100644 vendor/golang.org/x/net/trace/histogram.go create mode 100644 vendor/golang.org/x/net/trace/trace.go create mode 100644 vendor/golang.org/x/net/trace/trace_go16.go create mode 100644 vendor/golang.org/x/net/trace/trace_go17.go create mode 100644 vendor/golang.org/x/oauth2/.travis.yml create mode 100644 vendor/golang.org/x/oauth2/AUTHORS create mode 100644 vendor/golang.org/x/oauth2/CONTRIBUTING.md create mode 100644 vendor/golang.org/x/oauth2/CONTRIBUTORS create mode 100644 vendor/golang.org/x/oauth2/LICENSE create mode 100644 vendor/golang.org/x/oauth2/README.md create mode 100644 vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go create mode 100644 vendor/golang.org/x/oauth2/go.mod create mode 100644 vendor/golang.org/x/oauth2/go.sum create mode 100644 vendor/golang.org/x/oauth2/google/appengine.go create mode 100644 vendor/golang.org/x/oauth2/google/appengine_gen1.go create mode 100644 vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go create mode 100644 vendor/golang.org/x/oauth2/google/default.go create mode 100644 vendor/golang.org/x/oauth2/google/doc.go create mode 100644 vendor/golang.org/x/oauth2/google/google.go create mode 100644 vendor/golang.org/x/oauth2/google/jwt.go create mode 100644 vendor/golang.org/x/oauth2/google/sdk.go create mode 100644 vendor/golang.org/x/oauth2/internal/client_appengine.go create mode 100644 vendor/golang.org/x/oauth2/internal/doc.go create mode 100644 vendor/golang.org/x/oauth2/internal/oauth2.go create mode 100644 vendor/golang.org/x/oauth2/internal/token.go create mode 100644 vendor/golang.org/x/oauth2/internal/transport.go create mode 100644 vendor/golang.org/x/oauth2/jws/jws.go create mode 100644 vendor/golang.org/x/oauth2/jwt/jwt.go create mode 100644 vendor/golang.org/x/oauth2/oauth2.go create mode 100644 vendor/golang.org/x/oauth2/token.go create mode 100644 vendor/golang.org/x/oauth2/transport.go create mode 100644 vendor/golang.org/x/sync/AUTHORS create mode 100644 vendor/golang.org/x/sync/CONTRIBUTORS create mode 100644 vendor/golang.org/x/sync/LICENSE create mode 100644 vendor/golang.org/x/sync/PATENTS create mode 100644 vendor/golang.org/x/sync/semaphore/semaphore.go create mode 100644 vendor/golang.org/x/time/AUTHORS create mode 100644 vendor/golang.org/x/time/CONTRIBUTORS create mode 100644 vendor/golang.org/x/time/LICENSE create mode 100644 vendor/golang.org/x/time/PATENTS create mode 100644 vendor/golang.org/x/time/rate/rate.go create mode 100644 vendor/google.golang.org/api/AUTHORS create mode 100644 vendor/google.golang.org/api/CONTRIBUTORS create mode 100644 vendor/google.golang.org/api/LICENSE create mode 100644 vendor/google.golang.org/api/dns/v1/dns-api.json create mode 100644 vendor/google.golang.org/api/dns/v1/dns-gen.go create mode 100644 vendor/google.golang.org/api/gensupport/buffer.go create mode 100644 vendor/google.golang.org/api/gensupport/doc.go create mode 100644 vendor/google.golang.org/api/gensupport/json.go create mode 100644 vendor/google.golang.org/api/gensupport/jsonfloat.go create mode 100644 vendor/google.golang.org/api/gensupport/media.go create mode 100644 vendor/google.golang.org/api/gensupport/params.go create mode 100644 vendor/google.golang.org/api/gensupport/resumable.go create mode 100644 vendor/google.golang.org/api/gensupport/send.go create mode 100644 vendor/google.golang.org/api/googleapi/googleapi.go create mode 100644 vendor/google.golang.org/api/googleapi/internal/uritemplates/LICENSE create mode 100644 vendor/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go create mode 100644 vendor/google.golang.org/api/googleapi/internal/uritemplates/utils.go create mode 100644 vendor/google.golang.org/api/googleapi/transport/apikey.go create mode 100644 vendor/google.golang.org/api/googleapi/types.go create mode 100644 vendor/google.golang.org/api/internal/creds.go create mode 100644 vendor/google.golang.org/api/internal/pool.go create mode 100644 vendor/google.golang.org/api/internal/service-account.json create mode 100644 vendor/google.golang.org/api/internal/settings.go create mode 100644 vendor/google.golang.org/api/option/credentials_go19.go create mode 100644 vendor/google.golang.org/api/option/credentials_notgo19.go create mode 100644 vendor/google.golang.org/api/option/option.go create mode 100644 vendor/google.golang.org/api/support/bundler/bundler.go create mode 100644 vendor/google.golang.org/api/transport/http/dial.go create mode 100644 vendor/google.golang.org/api/transport/http/dial_appengine.go create mode 100644 vendor/google.golang.org/api/transport/http/internal/propagation/http.go create mode 100644 vendor/google.golang.org/appengine/.travis.yml create mode 100644 vendor/google.golang.org/appengine/CONTRIBUTING.md create mode 100644 vendor/google.golang.org/appengine/LICENSE create mode 100644 vendor/google.golang.org/appengine/README.md create mode 100644 vendor/google.golang.org/appengine/appengine.go create mode 100644 vendor/google.golang.org/appengine/appengine_vm.go create mode 100644 vendor/google.golang.org/appengine/errors.go create mode 100644 vendor/google.golang.org/appengine/go.mod create mode 100644 vendor/google.golang.org/appengine/go.sum create mode 100644 vendor/google.golang.org/appengine/identity.go create mode 100644 vendor/google.golang.org/appengine/internal/api.go create mode 100644 vendor/google.golang.org/appengine/internal/api_classic.go create mode 100644 vendor/google.golang.org/appengine/internal/api_common.go create mode 100644 vendor/google.golang.org/appengine/internal/app_id.go create mode 100644 vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.proto create mode 100644 vendor/google.golang.org/appengine/internal/base/api_base.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/base/api_base.proto create mode 100644 vendor/google.golang.org/appengine/internal/datastore/datastore_v3.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/datastore/datastore_v3.proto create mode 100644 vendor/google.golang.org/appengine/internal/identity.go create mode 100644 vendor/google.golang.org/appengine/internal/identity_classic.go create mode 100644 vendor/google.golang.org/appengine/internal/identity_flex.go create mode 100644 vendor/google.golang.org/appengine/internal/identity_vm.go create mode 100644 vendor/google.golang.org/appengine/internal/internal.go create mode 100644 vendor/google.golang.org/appengine/internal/log/log_service.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/log/log_service.proto create mode 100644 vendor/google.golang.org/appengine/internal/main.go create mode 100644 vendor/google.golang.org/appengine/internal/main_common.go create mode 100644 vendor/google.golang.org/appengine/internal/main_vm.go create mode 100644 vendor/google.golang.org/appengine/internal/metadata.go create mode 100644 vendor/google.golang.org/appengine/internal/modules/modules_service.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/modules/modules_service.proto create mode 100644 vendor/google.golang.org/appengine/internal/net.go create mode 100644 vendor/google.golang.org/appengine/internal/regen.sh create mode 100644 vendor/google.golang.org/appengine/internal/remote_api/remote_api.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto create mode 100644 vendor/google.golang.org/appengine/internal/transaction.go create mode 100644 vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.pb.go create mode 100644 vendor/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto create mode 100644 vendor/google.golang.org/appengine/namespace.go create mode 100644 vendor/google.golang.org/appengine/timeout.go create mode 100644 vendor/google.golang.org/appengine/travis_install.sh create mode 100644 vendor/google.golang.org/appengine/travis_test.sh create mode 100644 vendor/google.golang.org/appengine/urlfetch/urlfetch.go create mode 100644 vendor/google.golang.org/genproto/LICENSE create mode 100644 vendor/google.golang.org/genproto/googleapis/api/httpbody/httpbody.pb.go create mode 100644 vendor/google.golang.org/genproto/googleapis/rpc/status/status.pb.go create mode 100644 vendor/google.golang.org/genproto/protobuf/field_mask/field_mask.pb.go create mode 100644 vendor/google.golang.org/grpc/.travis.yml create mode 100644 vendor/google.golang.org/grpc/AUTHORS create mode 100644 vendor/google.golang.org/grpc/CONTRIBUTING.md create mode 100644 vendor/google.golang.org/grpc/LICENSE create mode 100644 vendor/google.golang.org/grpc/Makefile create mode 100644 vendor/google.golang.org/grpc/README.md create mode 100644 vendor/google.golang.org/grpc/backoff.go create mode 100644 vendor/google.golang.org/grpc/balancer.go create mode 100644 vendor/google.golang.org/grpc/balancer/balancer.go create mode 100644 vendor/google.golang.org/grpc/balancer/base/balancer.go create mode 100644 vendor/google.golang.org/grpc/balancer/base/base.go create mode 100644 vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go create mode 100644 vendor/google.golang.org/grpc/balancer_conn_wrappers.go create mode 100644 vendor/google.golang.org/grpc/balancer_v1_wrapper.go create mode 100644 vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go create mode 100644 vendor/google.golang.org/grpc/call.go create mode 100644 vendor/google.golang.org/grpc/clientconn.go create mode 100644 vendor/google.golang.org/grpc/codec.go create mode 100644 vendor/google.golang.org/grpc/codegen.sh create mode 100644 vendor/google.golang.org/grpc/codes/code_string.go create mode 100644 vendor/google.golang.org/grpc/codes/codes.go create mode 100644 vendor/google.golang.org/grpc/connectivity/connectivity.go create mode 100644 vendor/google.golang.org/grpc/credentials/credentials.go create mode 100644 vendor/google.golang.org/grpc/credentials/internal/syscallconn.go create mode 100644 vendor/google.golang.org/grpc/credentials/internal/syscallconn_appengine.go create mode 100644 vendor/google.golang.org/grpc/credentials/tls13.go create mode 100644 vendor/google.golang.org/grpc/dialoptions.go create mode 100644 vendor/google.golang.org/grpc/doc.go create mode 100644 vendor/google.golang.org/grpc/encoding/encoding.go create mode 100644 vendor/google.golang.org/grpc/encoding/proto/proto.go create mode 100644 vendor/google.golang.org/grpc/go.mod create mode 100644 vendor/google.golang.org/grpc/go.sum create mode 100644 vendor/google.golang.org/grpc/grpclog/grpclog.go create mode 100644 vendor/google.golang.org/grpc/grpclog/logger.go create mode 100644 vendor/google.golang.org/grpc/grpclog/loggerv2.go create mode 100644 vendor/google.golang.org/grpc/install_gae.sh create mode 100644 vendor/google.golang.org/grpc/interceptor.go create mode 100644 vendor/google.golang.org/grpc/internal/backoff/backoff.go create mode 100644 vendor/google.golang.org/grpc/internal/balancerload/load.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/binarylog.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/binarylog_testutil.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/env_config.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/method_logger.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/regenerate.sh create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/sink.go create mode 100644 vendor/google.golang.org/grpc/internal/binarylog/util.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/funcs.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/types.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/types_linux.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/types_nonlinux.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/util_linux.go create mode 100644 vendor/google.golang.org/grpc/internal/channelz/util_nonlinux.go create mode 100644 vendor/google.golang.org/grpc/internal/envconfig/envconfig.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcrand/grpcrand.go create mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/event.go create mode 100644 vendor/google.golang.org/grpc/internal/internal.go create mode 100644 vendor/google.golang.org/grpc/internal/syscall/syscall_linux.go create mode 100644 vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/bdp_estimator.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/controlbuf.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/defaults.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/flowcontrol.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/handler_server.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/http2_client.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/http2_server.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/http_util.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/log.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/transport.go create mode 100644 vendor/google.golang.org/grpc/keepalive/keepalive.go create mode 100644 vendor/google.golang.org/grpc/metadata/metadata.go create mode 100644 vendor/google.golang.org/grpc/naming/dns_resolver.go create mode 100644 vendor/google.golang.org/grpc/naming/naming.go create mode 100644 vendor/google.golang.org/grpc/peer/peer.go create mode 100644 vendor/google.golang.org/grpc/picker_wrapper.go create mode 100644 vendor/google.golang.org/grpc/pickfirst.go create mode 100644 vendor/google.golang.org/grpc/proxy.go create mode 100644 vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go create mode 100644 vendor/google.golang.org/grpc/resolver/passthrough/passthrough.go create mode 100644 vendor/google.golang.org/grpc/resolver/resolver.go create mode 100644 vendor/google.golang.org/grpc/resolver_conn_wrapper.go create mode 100644 vendor/google.golang.org/grpc/rpc_util.go create mode 100644 vendor/google.golang.org/grpc/server.go create mode 100644 vendor/google.golang.org/grpc/service_config.go create mode 100644 vendor/google.golang.org/grpc/stats/handlers.go create mode 100644 vendor/google.golang.org/grpc/stats/stats.go create mode 100644 vendor/google.golang.org/grpc/status/status.go create mode 100644 vendor/google.golang.org/grpc/stream.go create mode 100644 vendor/google.golang.org/grpc/tap/tap.go create mode 100644 vendor/google.golang.org/grpc/trace.go create mode 100644 vendor/google.golang.org/grpc/version.go create mode 100644 vendor/google.golang.org/grpc/vet.sh create mode 100644 vendor/gopkg.in/ini.v1/.gitignore create mode 100644 vendor/gopkg.in/ini.v1/.travis.yml create mode 100644 vendor/gopkg.in/ini.v1/LICENSE create mode 100644 vendor/gopkg.in/ini.v1/Makefile create mode 100644 vendor/gopkg.in/ini.v1/README.md create mode 100644 vendor/gopkg.in/ini.v1/error.go create mode 100644 vendor/gopkg.in/ini.v1/file.go create mode 100644 vendor/gopkg.in/ini.v1/ini.go create mode 100644 vendor/gopkg.in/ini.v1/key.go create mode 100644 vendor/gopkg.in/ini.v1/parser.go create mode 100644 vendor/gopkg.in/ini.v1/section.go create mode 100644 vendor/gopkg.in/ini.v1/struct.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/LICENSE.txt create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/account_apikey.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/account_setting.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/account_team.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/account_user.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/account_warning.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/client.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/data_feed.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/data_source.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/doc.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/apikey.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/doc.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/permissions.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/settings.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/team.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/user.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/warning.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/doc.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/feed.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/region.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/source.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/string.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/answer.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/doc.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/record.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/zone.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/filter/doc.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/filter/filter.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/config.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/doc.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/notify.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_job.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_notify.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/record.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/stat.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/util.go create mode 100644 vendor/gopkg.in/ns1/ns1-go.v2/rest/zone.go create mode 100644 vendor/gopkg.in/resty.v1/.gitignore create mode 100644 vendor/gopkg.in/resty.v1/.travis.yml create mode 100644 vendor/gopkg.in/resty.v1/BUILD.bazel create mode 100644 vendor/gopkg.in/resty.v1/LICENSE create mode 100644 vendor/gopkg.in/resty.v1/README.md create mode 100644 vendor/gopkg.in/resty.v1/WORKSPACE create mode 100644 vendor/gopkg.in/resty.v1/client.go create mode 100644 vendor/gopkg.in/resty.v1/default.go create mode 100644 vendor/gopkg.in/resty.v1/go.mod create mode 100644 vendor/gopkg.in/resty.v1/middleware.go create mode 100644 vendor/gopkg.in/resty.v1/redirect.go create mode 100644 vendor/gopkg.in/resty.v1/request.go create mode 100644 vendor/gopkg.in/resty.v1/request16.go create mode 100644 vendor/gopkg.in/resty.v1/request17.go create mode 100644 vendor/gopkg.in/resty.v1/response.go create mode 100644 vendor/gopkg.in/resty.v1/resty.go create mode 100644 vendor/gopkg.in/resty.v1/retry.go create mode 100644 vendor/gopkg.in/resty.v1/util.go diff --git a/vendor/cloud.google.com/go/LICENSE b/vendor/cloud.google.com/go/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/cloud.google.com/go/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go new file mode 100644 index 000000000..125b7033c --- /dev/null +++ b/vendor/cloud.google.com/go/compute/metadata/metadata.go @@ -0,0 +1,513 @@ +// Copyright 2014 Google LLC +// +// 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. + +// Package metadata provides access to Google Compute Engine (GCE) +// metadata and API service accounts. +// +// This package is a wrapper around the GCE metadata service, +// as documented at https://developers.google.com/compute/docs/metadata. +package metadata // import "cloud.google.com/go/compute/metadata" + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net" + "net/http" + "net/url" + "os" + "runtime" + "strings" + "sync" + "time" +) + +const ( + // metadataIP is the documented metadata server IP address. + metadataIP = "169.254.169.254" + + // metadataHostEnv is the environment variable specifying the + // GCE metadata hostname. If empty, the default value of + // metadataIP ("169.254.169.254") is used instead. + // This is variable name is not defined by any spec, as far as + // I know; it was made up for the Go package. + metadataHostEnv = "GCE_METADATA_HOST" + + userAgent = "gcloud-golang/0.1" +) + +type cachedValue struct { + k string + trim bool + mu sync.Mutex + v string +} + +var ( + projID = &cachedValue{k: "project/project-id", trim: true} + projNum = &cachedValue{k: "project/numeric-project-id", trim: true} + instID = &cachedValue{k: "instance/id", trim: true} +) + +var ( + defaultClient = &Client{hc: &http.Client{ + Transport: &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 2 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + ResponseHeaderTimeout: 2 * time.Second, + }, + }} + subscribeClient = &Client{hc: &http.Client{ + Transport: &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 2 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + }, + }} +) + +// NotDefinedError is returned when requested metadata is not defined. +// +// The underlying string is the suffix after "/computeMetadata/v1/". +// +// This error is not returned if the value is defined to be the empty +// string. +type NotDefinedError string + +func (suffix NotDefinedError) Error() string { + return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) +} + +func (c *cachedValue) get(cl *Client) (v string, err error) { + defer c.mu.Unlock() + c.mu.Lock() + if c.v != "" { + return c.v, nil + } + if c.trim { + v, err = cl.getTrimmed(c.k) + } else { + v, err = cl.Get(c.k) + } + if err == nil { + c.v = v + } + return +} + +var ( + onGCEOnce sync.Once + onGCE bool +) + +// OnGCE reports whether this process is running on Google Compute Engine. +func OnGCE() bool { + onGCEOnce.Do(initOnGCE) + return onGCE +} + +func initOnGCE() { + onGCE = testOnGCE() +} + +func testOnGCE() bool { + // The user explicitly said they're on GCE, so trust them. + if os.Getenv(metadataHostEnv) != "" { + return true + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + resc := make(chan bool, 2) + + // Try two strategies in parallel. + // See https://github.com/googleapis/google-cloud-go/issues/194 + go func() { + req, _ := http.NewRequest("GET", "http://"+metadataIP, nil) + req.Header.Set("User-Agent", userAgent) + res, err := defaultClient.hc.Do(req.WithContext(ctx)) + if err != nil { + resc <- false + return + } + defer res.Body.Close() + resc <- res.Header.Get("Metadata-Flavor") == "Google" + }() + + go func() { + addrs, err := net.LookupHost("metadata.google.internal") + if err != nil || len(addrs) == 0 { + resc <- false + return + } + resc <- strsContains(addrs, metadataIP) + }() + + tryHarder := systemInfoSuggestsGCE() + if tryHarder { + res := <-resc + if res { + // The first strategy succeeded, so let's use it. + return true + } + // Wait for either the DNS or metadata server probe to + // contradict the other one and say we are running on + // GCE. Give it a lot of time to do so, since the system + // info already suggests we're running on a GCE BIOS. + timer := time.NewTimer(5 * time.Second) + defer timer.Stop() + select { + case res = <-resc: + return res + case <-timer.C: + // Too slow. Who knows what this system is. + return false + } + } + + // There's no hint from the system info that we're running on + // GCE, so use the first probe's result as truth, whether it's + // true or false. The goal here is to optimize for speed for + // users who are NOT running on GCE. We can't assume that + // either a DNS lookup or an HTTP request to a blackholed IP + // address is fast. Worst case this should return when the + // metaClient's Transport.ResponseHeaderTimeout or + // Transport.Dial.Timeout fires (in two seconds). + return <-resc +} + +// systemInfoSuggestsGCE reports whether the local system (without +// doing network requests) suggests that we're running on GCE. If this +// returns true, testOnGCE tries a bit harder to reach its metadata +// server. +func systemInfoSuggestsGCE() bool { + if runtime.GOOS != "linux" { + // We don't have any non-Linux clues available, at least yet. + return false + } + slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name") + name := strings.TrimSpace(string(slurp)) + return name == "Google" || name == "Google Compute Engine" +} + +// Subscribe calls Client.Subscribe on a client designed for subscribing (one with no +// ResponseHeaderTimeout). +func Subscribe(suffix string, fn func(v string, ok bool) error) error { + return subscribeClient.Subscribe(suffix, fn) +} + +// Get calls Client.Get on the default client. +func Get(suffix string) (string, error) { return defaultClient.Get(suffix) } + +// ProjectID returns the current instance's project ID string. +func ProjectID() (string, error) { return defaultClient.ProjectID() } + +// NumericProjectID returns the current instance's numeric project ID. +func NumericProjectID() (string, error) { return defaultClient.NumericProjectID() } + +// InternalIP returns the instance's primary internal IP address. +func InternalIP() (string, error) { return defaultClient.InternalIP() } + +// ExternalIP returns the instance's primary external (public) IP address. +func ExternalIP() (string, error) { return defaultClient.ExternalIP() } + +// Hostname returns the instance's hostname. This will be of the form +// ".c..internal". +func Hostname() (string, error) { return defaultClient.Hostname() } + +// InstanceTags returns the list of user-defined instance tags, +// assigned when initially creating a GCE instance. +func InstanceTags() ([]string, error) { return defaultClient.InstanceTags() } + +// InstanceID returns the current VM's numeric instance ID. +func InstanceID() (string, error) { return defaultClient.InstanceID() } + +// InstanceName returns the current VM's instance ID string. +func InstanceName() (string, error) { return defaultClient.InstanceName() } + +// Zone returns the current VM's zone, such as "us-central1-b". +func Zone() (string, error) { return defaultClient.Zone() } + +// InstanceAttributes calls Client.InstanceAttributes on the default client. +func InstanceAttributes() ([]string, error) { return defaultClient.InstanceAttributes() } + +// ProjectAttributes calls Client.ProjectAttributes on the default client. +func ProjectAttributes() ([]string, error) { return defaultClient.ProjectAttributes() } + +// InstanceAttributeValue calls Client.InstanceAttributeValue on the default client. +func InstanceAttributeValue(attr string) (string, error) { + return defaultClient.InstanceAttributeValue(attr) +} + +// ProjectAttributeValue calls Client.ProjectAttributeValue on the default client. +func ProjectAttributeValue(attr string) (string, error) { + return defaultClient.ProjectAttributeValue(attr) +} + +// Scopes calls Client.Scopes on the default client. +func Scopes(serviceAccount string) ([]string, error) { return defaultClient.Scopes(serviceAccount) } + +func strsContains(ss []string, s string) bool { + for _, v := range ss { + if v == s { + return true + } + } + return false +} + +// A Client provides metadata. +type Client struct { + hc *http.Client +} + +// NewClient returns a Client that can be used to fetch metadata. All HTTP requests +// will use the given http.Client instead of the default client. +func NewClient(c *http.Client) *Client { + return &Client{hc: c} +} + +// getETag returns a value from the metadata service as well as the associated ETag. +// This func is otherwise equivalent to Get. +func (c *Client) getETag(suffix string) (value, etag string, err error) { + // Using a fixed IP makes it very difficult to spoof the metadata service in + // a container, which is an important use-case for local testing of cloud + // deployments. To enable spoofing of the metadata service, the environment + // variable GCE_METADATA_HOST is first inspected to decide where metadata + // requests shall go. + host := os.Getenv(metadataHostEnv) + if host == "" { + // Using 169.254.169.254 instead of "metadata" here because Go + // binaries built with the "netgo" tag and without cgo won't + // know the search suffix for "metadata" is + // ".google.internal", and this IP address is documented as + // being stable anyway. + host = metadataIP + } + u := "http://" + host + "/computeMetadata/v1/" + suffix + req, _ := http.NewRequest("GET", u, nil) + req.Header.Set("Metadata-Flavor", "Google") + req.Header.Set("User-Agent", userAgent) + res, err := c.hc.Do(req) + if err != nil { + return "", "", err + } + defer res.Body.Close() + if res.StatusCode == http.StatusNotFound { + return "", "", NotDefinedError(suffix) + } + all, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", "", err + } + if res.StatusCode != 200 { + return "", "", &Error{Code: res.StatusCode, Message: string(all)} + } + return string(all), res.Header.Get("Etag"), nil +} + +// Get returns a value from the metadata service. +// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". +// +// If the GCE_METADATA_HOST environment variable is not defined, a default of +// 169.254.169.254 will be used instead. +// +// If the requested metadata is not defined, the returned error will +// be of type NotDefinedError. +func (c *Client) Get(suffix string) (string, error) { + val, _, err := c.getETag(suffix) + return val, err +} + +func (c *Client) getTrimmed(suffix string) (s string, err error) { + s, err = c.Get(suffix) + s = strings.TrimSpace(s) + return +} + +func (c *Client) lines(suffix string) ([]string, error) { + j, err := c.Get(suffix) + if err != nil { + return nil, err + } + s := strings.Split(strings.TrimSpace(j), "\n") + for i := range s { + s[i] = strings.TrimSpace(s[i]) + } + return s, nil +} + +// ProjectID returns the current instance's project ID string. +func (c *Client) ProjectID() (string, error) { return projID.get(c) } + +// NumericProjectID returns the current instance's numeric project ID. +func (c *Client) NumericProjectID() (string, error) { return projNum.get(c) } + +// InstanceID returns the current VM's numeric instance ID. +func (c *Client) InstanceID() (string, error) { return instID.get(c) } + +// InternalIP returns the instance's primary internal IP address. +func (c *Client) InternalIP() (string, error) { + return c.getTrimmed("instance/network-interfaces/0/ip") +} + +// ExternalIP returns the instance's primary external (public) IP address. +func (c *Client) ExternalIP() (string, error) { + return c.getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip") +} + +// Hostname returns the instance's hostname. This will be of the form +// ".c..internal". +func (c *Client) Hostname() (string, error) { + return c.getTrimmed("instance/hostname") +} + +// InstanceTags returns the list of user-defined instance tags, +// assigned when initially creating a GCE instance. +func (c *Client) InstanceTags() ([]string, error) { + var s []string + j, err := c.Get("instance/tags") + if err != nil { + return nil, err + } + if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { + return nil, err + } + return s, nil +} + +// InstanceName returns the current VM's instance ID string. +func (c *Client) InstanceName() (string, error) { + host, err := c.Hostname() + if err != nil { + return "", err + } + return strings.Split(host, ".")[0], nil +} + +// Zone returns the current VM's zone, such as "us-central1-b". +func (c *Client) Zone() (string, error) { + zone, err := c.getTrimmed("instance/zone") + // zone is of the form "projects//zones/". + if err != nil { + return "", err + } + return zone[strings.LastIndex(zone, "/")+1:], nil +} + +// InstanceAttributes returns the list of user-defined attributes, +// assigned when initially creating a GCE VM instance. The value of an +// attribute can be obtained with InstanceAttributeValue. +func (c *Client) InstanceAttributes() ([]string, error) { return c.lines("instance/attributes/") } + +// ProjectAttributes returns the list of user-defined attributes +// applying to the project as a whole, not just this VM. The value of +// an attribute can be obtained with ProjectAttributeValue. +func (c *Client) ProjectAttributes() ([]string, error) { return c.lines("project/attributes/") } + +// InstanceAttributeValue returns the value of the provided VM +// instance attribute. +// +// If the requested attribute is not defined, the returned error will +// be of type NotDefinedError. +// +// InstanceAttributeValue may return ("", nil) if the attribute was +// defined to be the empty string. +func (c *Client) InstanceAttributeValue(attr string) (string, error) { + return c.Get("instance/attributes/" + attr) +} + +// ProjectAttributeValue returns the value of the provided +// project attribute. +// +// If the requested attribute is not defined, the returned error will +// be of type NotDefinedError. +// +// ProjectAttributeValue may return ("", nil) if the attribute was +// defined to be the empty string. +func (c *Client) ProjectAttributeValue(attr string) (string, error) { + return c.Get("project/attributes/" + attr) +} + +// Scopes returns the service account scopes for the given account. +// The account may be empty or the string "default" to use the instance's +// main account. +func (c *Client) Scopes(serviceAccount string) ([]string, error) { + if serviceAccount == "" { + serviceAccount = "default" + } + return c.lines("instance/service-accounts/" + serviceAccount + "/scopes") +} + +// Subscribe subscribes to a value from the metadata service. +// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". +// The suffix may contain query parameters. +// +// Subscribe calls fn with the latest metadata value indicated by the provided +// suffix. If the metadata value is deleted, fn is called with the empty string +// and ok false. Subscribe blocks until fn returns a non-nil error or the value +// is deleted. Subscribe returns the error value returned from the last call to +// fn, which may be nil when ok == false. +func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error { + const failedSubscribeSleep = time.Second * 5 + + // First check to see if the metadata value exists at all. + val, lastETag, err := c.getETag(suffix) + if err != nil { + return err + } + + if err := fn(val, true); err != nil { + return err + } + + ok := true + if strings.ContainsRune(suffix, '?') { + suffix += "&wait_for_change=true&last_etag=" + } else { + suffix += "?wait_for_change=true&last_etag=" + } + for { + val, etag, err := c.getETag(suffix + url.QueryEscape(lastETag)) + if err != nil { + if _, deleted := err.(NotDefinedError); !deleted { + time.Sleep(failedSubscribeSleep) + continue // Retry on other errors. + } + ok = false + } + lastETag = etag + + if err := fn(val, ok); err != nil || !ok { + return err + } + } +} + +// Error contains an error response from the server. +type Error struct { + // Code is the HTTP response status code. + Code int + // Message is the server response message. + Message string +} + +func (e *Error) Error() string { + return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message) +} diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/.travis.yml b/vendor/contrib.go.opencensus.io/exporter/ocagent/.travis.yml new file mode 100644 index 000000000..ee417bbe6 --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/.travis.yml @@ -0,0 +1,18 @@ +language: go + +go: + - 1.11.x + +go_import_path: contrib.go.opencensus.io/exporter/ocagent + +before_script: + - GO_FILES=$(find . -iname '*.go' | grep -v /vendor/) # All the .go files, excluding vendor/ if any + - PKGS=$(go list ./... | grep -v /vendor/) # All the import paths, excluding vendor/ if any + +script: + - go build ./... # Ensure dependency updates don't break build + - if [ -n "$(gofmt -s -l $GO_FILES)" ]; then echo "gofmt the following files:"; gofmt -s -l $GO_FILES; exit 1; fi + - go vet ./... + - GO111MODULE=on go test -v -race $PKGS # Run all the tests with the race detector enabled + - GO111MODULE=off go test -v -race $PKGS # Make sure tests still pass when not using Go modules. + - 'if [[ $TRAVIS_GO_VERSION = 1.8* ]]; then ! golint ./... | grep -vE "(_mock|_string|\.pb)\.go:"; fi' diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/CONTRIBUTING.md b/vendor/contrib.go.opencensus.io/exporter/ocagent/CONTRIBUTING.md new file mode 100644 index 000000000..0786fdf43 --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/CONTRIBUTING.md @@ -0,0 +1,24 @@ +# How to contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement. You (or your employer) retain the copyright to your contribution, +this simply gives us permission to use and redistribute your contributions as +part of the project. Head over to to see +your current agreements on file or to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + +## Code reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult [GitHub Help] for more +information on using pull requests. + +[GitHub Help]: https://help.github.com/articles/about-pull-requests/ diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/LICENSE b/vendor/contrib.go.opencensus.io/exporter/ocagent/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/LICENSE @@ -0,0 +1,201 @@ + 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. diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/README.md b/vendor/contrib.go.opencensus.io/exporter/ocagent/README.md new file mode 100644 index 000000000..3b9e908f5 --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/README.md @@ -0,0 +1,61 @@ +# OpenCensus Agent Go Exporter + +[![Build Status][travis-image]][travis-url] [![GoDoc][godoc-image]][godoc-url] + + +This repository contains the Go implementation of the OpenCensus Agent (OC-Agent) Exporter. +OC-Agent is a deamon process running in a VM that can retrieve spans/stats/metrics from +OpenCensus Library, export them to other backends and possibly push configurations back to +Library. See more details on [OC-Agent Readme][OCAgentReadme]. + +Note: This is an experimental repository and is likely to get backwards-incompatible changes. +Ultimately we may want to move the OC-Agent Go Exporter to [OpenCensus Go core library][OpenCensusGo]. + +## Installation + +```bash +$ go get -u contrib.go.opencensus.io/exporter/ocagent +``` + +## Usage + +```go +import ( + "context" + "fmt" + "log" + "time" + + "contrib.go.opencensus.io/exporter/ocagent" + "go.opencensus.io/trace" +) + +func Example() { + exp, err := ocagent.NewExporter(ocagent.WithInsecure(), ocagent.WithServiceName("your-service-name")) + if err != nil { + log.Fatalf("Failed to create the agent exporter: %v", err) + } + defer exp.Stop() + + // Now register it as a trace exporter. + trace.RegisterExporter(exp) + + // Then use the OpenCensus tracing library, like we normally would. + ctx, span := trace.StartSpan(context.Background(), "AgentExporter-Example") + defer span.End() + + for i := 0; i < 10; i++ { + _, iSpan := trace.StartSpan(ctx, fmt.Sprintf("Sample-%d", i)) + <-time.After(6 * time.Millisecond) + iSpan.End() + } +} +``` + +[OCAgentReadme]: https://github.com/census-instrumentation/opencensus-proto/tree/master/opencensus/proto/agent#opencensus-agent-proto +[OpenCensusGo]: https://github.com/census-instrumentation/opencensus-go +[godoc-image]: https://godoc.org/contrib.go.opencensus.io/exporter/ocagent?status.svg +[godoc-url]: https://godoc.org/contrib.go.opencensus.io/exporter/ocagent +[travis-image]: https://travis-ci.org/census-ecosystem/opencensus-go-exporter-ocagent.svg?branch=master +[travis-url]: https://travis-ci.org/census-ecosystem/opencensus-go-exporter-ocagent + diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/common.go b/vendor/contrib.go.opencensus.io/exporter/ocagent/common.go new file mode 100644 index 000000000..297e44b6e --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/common.go @@ -0,0 +1,38 @@ +// Copyright 2018, OpenCensus Authors +// +// 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. + +package ocagent + +import ( + "math/rand" + "time" +) + +var randSrc = rand.New(rand.NewSource(time.Now().UnixNano())) + +// retries function fn upto n times, if fn returns an error lest it returns nil early. +// It applies exponential backoff in units of (1< 0 { + ctx = metadata.NewOutgoingContext(ctx, metadata.New(ae.headers)) + } + traceExporter, err := traceSvcClient.Export(ctx) + if err != nil { + return fmt.Errorf("Exporter.Start:: TraceServiceClient: %v", err) + } + + firstTraceMessage := &agenttracepb.ExportTraceServiceRequest{ + Node: node, + Resource: ae.resource, + } + if err := traceExporter.Send(firstTraceMessage); err != nil { + return fmt.Errorf("Exporter.Start:: Failed to initiate the Config service: %v", err) + } + + ae.mu.Lock() + ae.traceExporter = traceExporter + ae.mu.Unlock() + + // Initiate the config service by sending over node identifier info. + configStream, err := traceSvcClient.Config(context.Background()) + if err != nil { + return fmt.Errorf("Exporter.Start:: ConfigStream: %v", err) + } + firstCfgMessage := &agenttracepb.CurrentLibraryConfig{Node: node} + if err := configStream.Send(firstCfgMessage); err != nil { + return fmt.Errorf("Exporter.Start:: Failed to initiate the Config service: %v", err) + } + + // In the background, handle trace configurations that are beamed down + // by the agent, but also reply to it with the applied configuration. + go ae.handleConfigStreaming(configStream) + + return nil +} + +func (ae *Exporter) createMetricsServiceConnection(cc *grpc.ClientConn, node *commonpb.Node) error { + metricsSvcClient := agentmetricspb.NewMetricsServiceClient(cc) + metricsExporter, err := metricsSvcClient.Export(context.Background()) + if err != nil { + return fmt.Errorf("MetricsExporter: failed to start the service client: %v", err) + } + // Initiate the metrics service by sending over the first message just containing the Node and Resource. + firstMetricsMessage := &agentmetricspb.ExportMetricsServiceRequest{ + Node: node, + Resource: ae.resource, + } + if err := metricsExporter.Send(firstMetricsMessage); err != nil { + return fmt.Errorf("MetricsExporter:: failed to send the first message: %v", err) + } + + ae.mu.Lock() + ae.metricsExporter = metricsExporter + ae.mu.Unlock() + + // With that we are good to go and can start sending metrics + return nil +} + +func (ae *Exporter) dialToAgent() (*grpc.ClientConn, error) { + addr := ae.prepareAgentAddress() + var dialOpts []grpc.DialOption + if ae.clientTransportCredentials != nil { + dialOpts = append(dialOpts, grpc.WithTransportCredentials(ae.clientTransportCredentials)) + } else if ae.canDialInsecure { + dialOpts = append(dialOpts, grpc.WithInsecure()) + } + if ae.compressor != "" { + dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.UseCompressor(ae.compressor))) + } + dialOpts = append(dialOpts, grpc.WithStatsHandler(&ocgrpc.ClientHandler{})) + + ctx := context.Background() + if len(ae.headers) > 0 { + ctx = metadata.NewOutgoingContext(ctx, metadata.New(ae.headers)) + } + return grpc.DialContext(ctx, addr, dialOpts...) +} + +func (ae *Exporter) handleConfigStreaming(configStream agenttracepb.TraceService_ConfigClient) error { + // Note: We haven't yet implemented configuration sending so we + // should NOT be changing connection states within this function for now. + for { + recv, err := configStream.Recv() + if err != nil { + // TODO: Check if this is a transient error or exponential backoff-able. + return err + } + cfg := recv.Config + if cfg == nil { + continue + } + + // Otherwise now apply the trace configuration sent down from the agent + if psamp := cfg.GetProbabilitySampler(); psamp != nil { + trace.ApplyConfig(trace.Config{DefaultSampler: trace.ProbabilitySampler(psamp.SamplingProbability)}) + } else if csamp := cfg.GetConstantSampler(); csamp != nil { + alwaysSample := csamp.Decision == tracepb.ConstantSampler_ALWAYS_ON + if alwaysSample { + trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) + } else { + trace.ApplyConfig(trace.Config{DefaultSampler: trace.NeverSample()}) + } + } else { // TODO: Add the rate limiting sampler here + } + + // Then finally send back to upstream the newly applied configuration + err = configStream.Send(&agenttracepb.CurrentLibraryConfig{Config: &tracepb.TraceConfig{Sampler: cfg.Sampler}}) + if err != nil { + return err + } + } +} + +// Stop shuts down all the connections and resources +// related to the exporter. +func (ae *Exporter) Stop() error { + ae.mu.RLock() + cc := ae.grpcClientConn + started := ae.started + stopped := ae.stopped + ae.mu.RUnlock() + + if !started { + return errNotStarted + } + if stopped { + // TODO: tell the user that we've already stopped, so perhaps a sentinel error? + return nil + } + + ae.Flush() + + // Now close the underlying gRPC connection. + var err error + if cc != nil { + err = cc.Close() + } + + // At this point we can change the state variables: started and stopped + ae.mu.Lock() + ae.started = false + ae.stopped = true + ae.mu.Unlock() + close(ae.stopCh) + + // Ensure that the backgroundConnector returns + <-ae.backgroundConnectionDoneCh + + return err +} + +func (ae *Exporter) ExportSpan(sd *trace.SpanData) { + if sd == nil { + return + } + _ = ae.traceBundler.Add(sd, 1) +} + +func (ae *Exporter) ExportTraceServiceRequest(batch *agenttracepb.ExportTraceServiceRequest) error { + if batch == nil || len(batch.Spans) == 0 { + return nil + } + + select { + case <-ae.stopCh: + return errStopped + + default: + if !ae.connected() { + return errNoConnection + } + + ae.senderMu.Lock() + err := ae.traceExporter.Send(batch) + ae.senderMu.Unlock() + if err != nil { + ae.setStateDisconnected() + return err + } + return nil + } +} + +func (ae *Exporter) ExportView(vd *view.Data) { + if vd == nil { + return + } + _ = ae.viewDataBundler.Add(vd, 1) +} + +func ocSpanDataToPbSpans(sdl []*trace.SpanData) []*tracepb.Span { + if len(sdl) == 0 { + return nil + } + protoSpans := make([]*tracepb.Span, 0, len(sdl)) + for _, sd := range sdl { + if sd != nil { + protoSpans = append(protoSpans, ocSpanToProtoSpan(sd)) + } + } + return protoSpans +} + +func (ae *Exporter) uploadTraces(sdl []*trace.SpanData) { + select { + case <-ae.stopCh: + return + + default: + if !ae.connected() { + return + } + + protoSpans := ocSpanDataToPbSpans(sdl) + if len(protoSpans) == 0 { + return + } + ae.senderMu.Lock() + err := ae.traceExporter.Send(&agenttracepb.ExportTraceServiceRequest{ + Spans: protoSpans, + }) + ae.senderMu.Unlock() + if err != nil { + ae.setStateDisconnected() + } + } +} + +func ocViewDataToPbMetrics(vdl []*view.Data) []*metricspb.Metric { + if len(vdl) == 0 { + return nil + } + metrics := make([]*metricspb.Metric, 0, len(vdl)) + for _, vd := range vdl { + if vd != nil { + vmetric, err := viewDataToMetric(vd) + // TODO: (@odeke-em) somehow report this error, if it is non-nil. + if err == nil && vmetric != nil { + metrics = append(metrics, vmetric) + } + } + } + return metrics +} + +func (ae *Exporter) uploadViewData(vdl []*view.Data) { + select { + case <-ae.stopCh: + return + + default: + if !ae.connected() { + return + } + + protoMetrics := ocViewDataToPbMetrics(vdl) + if len(protoMetrics) == 0 { + return + } + err := ae.metricsExporter.Send(&agentmetricspb.ExportMetricsServiceRequest{ + Metrics: protoMetrics, + // TODO:(@odeke-em) + // a) Figure out how to derive a Node from the environment + // b) Figure out how to derive a Resource from the environment + // or better letting users of the exporter configure it. + }) + if err != nil { + ae.setStateDisconnected() + } + } +} + +func (ae *Exporter) Flush() { + ae.traceBundler.Flush() + ae.viewDataBundler.Flush() +} + +func resourceProtoFromEnv() *resourcepb.Resource { + rs, _ := resource.FromEnv(context.Background()) + if rs == nil { + return nil + } + + rprs := &resourcepb.Resource{ + Type: rs.Type, + } + if rs.Labels != nil { + rprs.Labels = make(map[string]string) + for k, v := range rs.Labels { + rprs.Labels[k] = v + } + } + return rprs +} diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/options.go b/vendor/contrib.go.opencensus.io/exporter/ocagent/options.go new file mode 100644 index 000000000..3e05ae8b3 --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/options.go @@ -0,0 +1,128 @@ +// Copyright 2018, OpenCensus Authors +// +// 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. + +package ocagent + +import ( + "time" + + "google.golang.org/grpc/credentials" +) + +const ( + DefaultAgentPort uint16 = 55678 + DefaultAgentHost string = "localhost" +) + +type ExporterOption interface { + withExporter(e *Exporter) +} + +type insecureGrpcConnection int + +var _ ExporterOption = (*insecureGrpcConnection)(nil) + +func (igc *insecureGrpcConnection) withExporter(e *Exporter) { + e.canDialInsecure = true +} + +// WithInsecure disables client transport security for the exporter's gRPC connection +// just like grpc.WithInsecure() https://godoc.org/google.golang.org/grpc#WithInsecure +// does. Note, by default, client security is required unless WithInsecure is used. +func WithInsecure() ExporterOption { return new(insecureGrpcConnection) } + +type addressSetter string + +func (as addressSetter) withExporter(e *Exporter) { + e.agentAddress = string(as) +} + +var _ ExporterOption = (*addressSetter)(nil) + +// WithAddress allows one to set the address that the exporter will +// connect to the agent on. If unset, it will instead try to use +// connect to DefaultAgentHost:DefaultAgentPort +func WithAddress(addr string) ExporterOption { + return addressSetter(addr) +} + +type serviceNameSetter string + +func (sns serviceNameSetter) withExporter(e *Exporter) { + e.serviceName = string(sns) +} + +var _ ExporterOption = (*serviceNameSetter)(nil) + +// WithServiceName allows one to set/override the service name +// that the exporter will report to the agent. +func WithServiceName(serviceName string) ExporterOption { + return serviceNameSetter(serviceName) +} + +type reconnectionPeriod time.Duration + +func (rp reconnectionPeriod) withExporter(e *Exporter) { + e.reconnectionPeriod = time.Duration(rp) +} + +func WithReconnectionPeriod(rp time.Duration) ExporterOption { + return reconnectionPeriod(rp) +} + +type compressorSetter string + +func (c compressorSetter) withExporter(e *Exporter) { + e.compressor = string(c) +} + +// UseCompressor will set the compressor for the gRPC client to use when sending requests. +// It is the responsibility of the caller to ensure that the compressor set has been registered +// with google.golang.org/grpc/encoding. This can be done by encoding.RegisterCompressor. Some +// compressors auto-register on import, such as gzip, which can be registered by calling +// `import _ "google.golang.org/grpc/encoding/gzip"` +func UseCompressor(compressorName string) ExporterOption { + return compressorSetter(compressorName) +} + +type headerSetter map[string]string + +func (h headerSetter) withExporter(e *Exporter) { + e.headers = map[string]string(h) +} + +// WithHeaders will send the provided headers when the gRPC stream connection +// is instantiated +func WithHeaders(headers map[string]string) ExporterOption { + return headerSetter(headers) +} + +type clientCredentials struct { + credentials.TransportCredentials +} + +var _ ExporterOption = (*clientCredentials)(nil) + +// WithTLSCredentials allows the connection to use TLS credentials +// when talking to the server. It takes in grpc.TransportCredentials instead +// of say a Certificate file or a tls.Certificate, because the retrieving +// these credentials can be done in many ways e.g. plain file, in code tls.Config +// or by certificate rotation, so it is up to the caller to decide what to use. +func WithTLSCredentials(creds credentials.TransportCredentials) ExporterOption { + return &clientCredentials{TransportCredentials: creds} +} + +func (cc *clientCredentials) withExporter(e *Exporter) { + e.clientTransportCredentials = cc.TransportCredentials +} diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/transform_spans.go b/vendor/contrib.go.opencensus.io/exporter/ocagent/transform_spans.go new file mode 100644 index 000000000..983ebe7b7 --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/transform_spans.go @@ -0,0 +1,248 @@ +// Copyright 2018, OpenCensus Authors +// +// 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. + +package ocagent + +import ( + "math" + "time" + + "go.opencensus.io/trace" + "go.opencensus.io/trace/tracestate" + + tracepb "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1" + "github.com/golang/protobuf/ptypes/timestamp" +) + +const ( + maxAnnotationEventsPerSpan = 32 + maxMessageEventsPerSpan = 128 +) + +func ocSpanToProtoSpan(sd *trace.SpanData) *tracepb.Span { + if sd == nil { + return nil + } + var namePtr *tracepb.TruncatableString + if sd.Name != "" { + namePtr = &tracepb.TruncatableString{Value: sd.Name} + } + return &tracepb.Span{ + TraceId: sd.TraceID[:], + SpanId: sd.SpanID[:], + ParentSpanId: sd.ParentSpanID[:], + Status: ocStatusToProtoStatus(sd.Status), + StartTime: timeToTimestamp(sd.StartTime), + EndTime: timeToTimestamp(sd.EndTime), + Links: ocLinksToProtoLinks(sd.Links), + Kind: ocSpanKindToProtoSpanKind(sd.SpanKind), + Name: namePtr, + Attributes: ocAttributesToProtoAttributes(sd.Attributes), + TimeEvents: ocTimeEventsToProtoTimeEvents(sd.Annotations, sd.MessageEvents), + Tracestate: ocTracestateToProtoTracestate(sd.Tracestate), + } +} + +var blankStatus trace.Status + +func ocStatusToProtoStatus(status trace.Status) *tracepb.Status { + if status == blankStatus { + return nil + } + return &tracepb.Status{ + Code: status.Code, + Message: status.Message, + } +} + +func ocLinksToProtoLinks(links []trace.Link) *tracepb.Span_Links { + if len(links) == 0 { + return nil + } + + sl := make([]*tracepb.Span_Link, 0, len(links)) + for _, ocLink := range links { + // This redefinition is necessary to prevent ocLink.*ID[:] copies + // being reused -- in short we need a new ocLink per iteration. + ocLink := ocLink + + sl = append(sl, &tracepb.Span_Link{ + TraceId: ocLink.TraceID[:], + SpanId: ocLink.SpanID[:], + Type: ocLinkTypeToProtoLinkType(ocLink.Type), + }) + } + + return &tracepb.Span_Links{ + Link: sl, + } +} + +func ocLinkTypeToProtoLinkType(oct trace.LinkType) tracepb.Span_Link_Type { + switch oct { + case trace.LinkTypeChild: + return tracepb.Span_Link_CHILD_LINKED_SPAN + case trace.LinkTypeParent: + return tracepb.Span_Link_PARENT_LINKED_SPAN + default: + return tracepb.Span_Link_TYPE_UNSPECIFIED + } +} + +func ocAttributesToProtoAttributes(attrs map[string]interface{}) *tracepb.Span_Attributes { + if len(attrs) == 0 { + return nil + } + outMap := make(map[string]*tracepb.AttributeValue) + for k, v := range attrs { + switch v := v.(type) { + case bool: + outMap[k] = &tracepb.AttributeValue{Value: &tracepb.AttributeValue_BoolValue{BoolValue: v}} + + case int: + outMap[k] = &tracepb.AttributeValue{Value: &tracepb.AttributeValue_IntValue{IntValue: int64(v)}} + + case int64: + outMap[k] = &tracepb.AttributeValue{Value: &tracepb.AttributeValue_IntValue{IntValue: v}} + + case string: + outMap[k] = &tracepb.AttributeValue{ + Value: &tracepb.AttributeValue_StringValue{ + StringValue: &tracepb.TruncatableString{Value: v}, + }, + } + } + } + return &tracepb.Span_Attributes{ + AttributeMap: outMap, + } +} + +// This code is mostly copied from +// https://github.com/census-ecosystem/opencensus-go-exporter-stackdriver/blob/master/trace_proto.go#L46 +func ocTimeEventsToProtoTimeEvents(as []trace.Annotation, es []trace.MessageEvent) *tracepb.Span_TimeEvents { + if len(as) == 0 && len(es) == 0 { + return nil + } + + timeEvents := &tracepb.Span_TimeEvents{} + var annotations, droppedAnnotationsCount int + var messageEvents, droppedMessageEventsCount int + + // Transform annotations + for i, a := range as { + if annotations >= maxAnnotationEventsPerSpan { + droppedAnnotationsCount = len(as) - i + break + } + annotations++ + timeEvents.TimeEvent = append(timeEvents.TimeEvent, + &tracepb.Span_TimeEvent{ + Time: timeToTimestamp(a.Time), + Value: transformAnnotationToTimeEvent(&a), + }, + ) + } + + // Transform message events + for i, e := range es { + if messageEvents >= maxMessageEventsPerSpan { + droppedMessageEventsCount = len(es) - i + break + } + messageEvents++ + timeEvents.TimeEvent = append(timeEvents.TimeEvent, + &tracepb.Span_TimeEvent{ + Time: timeToTimestamp(e.Time), + Value: transformMessageEventToTimeEvent(&e), + }, + ) + } + + // Process dropped counter + timeEvents.DroppedAnnotationsCount = clip32(droppedAnnotationsCount) + timeEvents.DroppedMessageEventsCount = clip32(droppedMessageEventsCount) + + return timeEvents +} + +func transformAnnotationToTimeEvent(a *trace.Annotation) *tracepb.Span_TimeEvent_Annotation_ { + return &tracepb.Span_TimeEvent_Annotation_{ + Annotation: &tracepb.Span_TimeEvent_Annotation{ + Description: &tracepb.TruncatableString{Value: a.Message}, + Attributes: ocAttributesToProtoAttributes(a.Attributes), + }, + } +} + +func transformMessageEventToTimeEvent(e *trace.MessageEvent) *tracepb.Span_TimeEvent_MessageEvent_ { + return &tracepb.Span_TimeEvent_MessageEvent_{ + MessageEvent: &tracepb.Span_TimeEvent_MessageEvent{ + Type: tracepb.Span_TimeEvent_MessageEvent_Type(e.EventType), + Id: uint64(e.MessageID), + UncompressedSize: uint64(e.UncompressedByteSize), + CompressedSize: uint64(e.CompressedByteSize), + }, + } +} + +// clip32 clips an int to the range of an int32. +func clip32(x int) int32 { + if x < math.MinInt32 { + return math.MinInt32 + } + if x > math.MaxInt32 { + return math.MaxInt32 + } + return int32(x) +} + +func timeToTimestamp(t time.Time) *timestamp.Timestamp { + nanoTime := t.UnixNano() + return ×tamp.Timestamp{ + Seconds: nanoTime / 1e9, + Nanos: int32(nanoTime % 1e9), + } +} + +func ocSpanKindToProtoSpanKind(kind int) tracepb.Span_SpanKind { + switch kind { + case trace.SpanKindClient: + return tracepb.Span_CLIENT + case trace.SpanKindServer: + return tracepb.Span_SERVER + default: + return tracepb.Span_SPAN_KIND_UNSPECIFIED + } +} + +func ocTracestateToProtoTracestate(ts *tracestate.Tracestate) *tracepb.Span_Tracestate { + if ts == nil { + return nil + } + return &tracepb.Span_Tracestate{ + Entries: ocTracestateEntriesToProtoTracestateEntries(ts.Entries()), + } +} + +func ocTracestateEntriesToProtoTracestateEntries(entries []tracestate.Entry) []*tracepb.Span_Tracestate_Entry { + protoEntries := make([]*tracepb.Span_Tracestate_Entry, 0, len(entries)) + for _, entry := range entries { + protoEntries = append(protoEntries, &tracepb.Span_Tracestate_Entry{ + Key: entry.Key, + Value: entry.Value, + }) + } + return protoEntries +} diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/transform_stats_to_metrics.go b/vendor/contrib.go.opencensus.io/exporter/ocagent/transform_stats_to_metrics.go new file mode 100644 index 000000000..43f18dec1 --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/transform_stats_to_metrics.go @@ -0,0 +1,274 @@ +// Copyright 2018, OpenCensus Authors +// +// 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. + +package ocagent + +import ( + "errors" + "time" + + "go.opencensus.io/stats" + "go.opencensus.io/stats/view" + "go.opencensus.io/tag" + + "github.com/golang/protobuf/ptypes/timestamp" + + metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" +) + +var ( + errNilMeasure = errors.New("expecting a non-nil stats.Measure") + errNilView = errors.New("expecting a non-nil view.View") + errNilViewData = errors.New("expecting a non-nil view.Data") +) + +func viewDataToMetric(vd *view.Data) (*metricspb.Metric, error) { + if vd == nil { + return nil, errNilViewData + } + + descriptor, err := viewToMetricDescriptor(vd.View) + if err != nil { + return nil, err + } + + timeseries, err := viewDataToTimeseries(vd) + if err != nil { + return nil, err + } + + metric := &metricspb.Metric{ + MetricDescriptor: descriptor, + Timeseries: timeseries, + } + return metric, nil +} + +func viewToMetricDescriptor(v *view.View) (*metricspb.MetricDescriptor, error) { + if v == nil { + return nil, errNilView + } + if v.Measure == nil { + return nil, errNilMeasure + } + + desc := &metricspb.MetricDescriptor{ + Name: stringOrCall(v.Name, v.Measure.Name), + Description: stringOrCall(v.Description, v.Measure.Description), + Unit: v.Measure.Unit(), + Type: aggregationToMetricDescriptorType(v), + LabelKeys: tagKeysToLabelKeys(v.TagKeys), + } + return desc, nil +} + +func stringOrCall(first string, call func() string) string { + if first != "" { + return first + } + return call() +} + +type measureType uint + +const ( + measureUnknown measureType = iota + measureInt64 + measureFloat64 +) + +func measureTypeFromMeasure(m stats.Measure) measureType { + switch m.(type) { + default: + return measureUnknown + case *stats.Float64Measure: + return measureFloat64 + case *stats.Int64Measure: + return measureInt64 + } +} + +func aggregationToMetricDescriptorType(v *view.View) metricspb.MetricDescriptor_Type { + if v == nil || v.Aggregation == nil { + return metricspb.MetricDescriptor_UNSPECIFIED + } + if v.Measure == nil { + return metricspb.MetricDescriptor_UNSPECIFIED + } + + switch v.Aggregation.Type { + case view.AggTypeCount: + // Cumulative on int64 + return metricspb.MetricDescriptor_CUMULATIVE_INT64 + + case view.AggTypeDistribution: + // Cumulative types + return metricspb.MetricDescriptor_CUMULATIVE_DISTRIBUTION + + case view.AggTypeLastValue: + // Gauge types + switch measureTypeFromMeasure(v.Measure) { + case measureFloat64: + return metricspb.MetricDescriptor_GAUGE_DOUBLE + case measureInt64: + return metricspb.MetricDescriptor_GAUGE_INT64 + } + + case view.AggTypeSum: + // Cumulative types + switch measureTypeFromMeasure(v.Measure) { + case measureFloat64: + return metricspb.MetricDescriptor_CUMULATIVE_DOUBLE + case measureInt64: + return metricspb.MetricDescriptor_CUMULATIVE_INT64 + } + } + + // For all other cases, return unspecified. + return metricspb.MetricDescriptor_UNSPECIFIED +} + +func tagKeysToLabelKeys(tagKeys []tag.Key) []*metricspb.LabelKey { + labelKeys := make([]*metricspb.LabelKey, 0, len(tagKeys)) + for _, tagKey := range tagKeys { + labelKeys = append(labelKeys, &metricspb.LabelKey{ + Key: tagKey.Name(), + }) + } + return labelKeys +} + +func viewDataToTimeseries(vd *view.Data) ([]*metricspb.TimeSeries, error) { + if vd == nil || len(vd.Rows) == 0 { + return nil, nil + } + + // Given that view.Data only contains Start, End + // the timestamps for all the row data will be the exact same + // per aggregation. However, the values will differ. + // Each row has its own tags. + startTimestamp := timeToProtoTimestamp(vd.Start) + endTimestamp := timeToProtoTimestamp(vd.End) + + mType := measureTypeFromMeasure(vd.View.Measure) + timeseries := make([]*metricspb.TimeSeries, 0, len(vd.Rows)) + // It is imperative that the ordering of "LabelValues" matches those + // of the Label keys in the metric descriptor. + for _, row := range vd.Rows { + labelValues := labelValuesFromTags(row.Tags) + point := rowToPoint(vd.View, row, endTimestamp, mType) + timeseries = append(timeseries, &metricspb.TimeSeries{ + StartTimestamp: startTimestamp, + LabelValues: labelValues, + Points: []*metricspb.Point{point}, + }) + } + + if len(timeseries) == 0 { + return nil, nil + } + + return timeseries, nil +} + +func timeToProtoTimestamp(t time.Time) *timestamp.Timestamp { + unixNano := t.UnixNano() + return ×tamp.Timestamp{ + Seconds: int64(unixNano / 1e9), + Nanos: int32(unixNano % 1e9), + } +} + +func rowToPoint(v *view.View, row *view.Row, endTimestamp *timestamp.Timestamp, mType measureType) *metricspb.Point { + pt := &metricspb.Point{ + Timestamp: endTimestamp, + } + + switch data := row.Data.(type) { + case *view.CountData: + pt.Value = &metricspb.Point_Int64Value{Int64Value: data.Value} + + case *view.DistributionData: + pt.Value = &metricspb.Point_DistributionValue{ + DistributionValue: &metricspb.DistributionValue{ + Count: data.Count, + Sum: float64(data.Count) * data.Mean, // because Mean := Sum/Count + // TODO: Add Exemplar + Buckets: bucketsToProtoBuckets(data.CountPerBucket), + BucketOptions: &metricspb.DistributionValue_BucketOptions{ + Type: &metricspb.DistributionValue_BucketOptions_Explicit_{ + Explicit: &metricspb.DistributionValue_BucketOptions_Explicit{ + Bounds: v.Aggregation.Buckets, + }, + }, + }, + SumOfSquaredDeviation: data.SumOfSquaredDev, + }} + + case *view.LastValueData: + setPointValue(pt, data.Value, mType) + + case *view.SumData: + setPointValue(pt, data.Value, mType) + } + + return pt +} + +// Not returning anything from this function because metricspb.Point.is_Value is an unexported +// interface hence we just have to set its value by pointer. +func setPointValue(pt *metricspb.Point, value float64, mType measureType) { + if mType == measureInt64 { + pt.Value = &metricspb.Point_Int64Value{Int64Value: int64(value)} + } else { + pt.Value = &metricspb.Point_DoubleValue{DoubleValue: value} + } +} + +func bucketsToProtoBuckets(countPerBucket []int64) []*metricspb.DistributionValue_Bucket { + distBuckets := make([]*metricspb.DistributionValue_Bucket, len(countPerBucket)) + for i := 0; i < len(countPerBucket); i++ { + count := countPerBucket[i] + + distBuckets[i] = &metricspb.DistributionValue_Bucket{ + Count: count, + } + } + + return distBuckets +} + +func labelValuesFromTags(tags []tag.Tag) []*metricspb.LabelValue { + if len(tags) == 0 { + return nil + } + + labelValues := make([]*metricspb.LabelValue, 0, len(tags)) + for _, tag_ := range tags { + labelValues = append(labelValues, &metricspb.LabelValue{ + Value: tag_.Value, + + // It is imperative that we set the "HasValue" attribute, + // in order to distinguish missing a label from the empty string. + // https://godoc.org/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1#LabelValue.HasValue + // + // OpenCensus-Go uses non-pointers for tags as seen by this function's arguments, + // so the best case that we can use to distinguish missing labels/tags from the + // empty string is by checking if the Tag.Key.Name() != "" to indicate that we have + // a value. + HasValue: tag_.Key.Name() != "", + }) + } + return labelValues +} diff --git a/vendor/contrib.go.opencensus.io/exporter/ocagent/version.go b/vendor/contrib.go.opencensus.io/exporter/ocagent/version.go new file mode 100644 index 000000000..68be4c75b --- /dev/null +++ b/vendor/contrib.go.opencensus.io/exporter/ocagent/version.go @@ -0,0 +1,17 @@ +// Copyright 2018, OpenCensus Authors +// +// 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. + +package ocagent + +const Version = "0.0.1" diff --git a/vendor/github.com/Azure/azure-sdk-for-go/LICENSE b/vendor/github.com/Azure/azure-sdk-for-go/LICENSE new file mode 100644 index 000000000..af39a91e7 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/LICENSE @@ -0,0 +1,202 @@ + + 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 2016 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/NOTICE b/vendor/github.com/Azure/azure-sdk-for-go/NOTICE new file mode 100644 index 000000000..2d1d72608 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/NOTICE @@ -0,0 +1,5 @@ +Microsoft Azure-SDK-for-Go +Copyright 2014-2017 Microsoft + +This product includes software developed at +the Microsoft Corporation (https://www.microsoft.com). diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/client.go new file mode 100644 index 000000000..482d2f943 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/client.go @@ -0,0 +1,51 @@ +// Package dns implements the Azure ARM Dns service API version 2017-09-01. +// +// The DNS Management Client. +package dns + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // DefaultBaseURI is the default URI used for the service Dns + DefaultBaseURI = "https://management.azure.com" +) + +// BaseClient is the base client for Dns. +type BaseClient struct { + autorest.Client + BaseURI string + SubscriptionID string +} + +// New creates an instance of the BaseClient client. +func New(subscriptionID string) BaseClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the BaseClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient { + return BaseClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/models.go new file mode 100644 index 000000000..e21c526ce --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/models.go @@ -0,0 +1,833 @@ +package dns + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "encoding/json" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/to" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// The package's fully qualified name. +const fqdn = "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns" + +// RecordType enumerates the values for record type. +type RecordType string + +const ( + // A ... + A RecordType = "A" + // AAAA ... + AAAA RecordType = "AAAA" + // CAA ... + CAA RecordType = "CAA" + // CNAME ... + CNAME RecordType = "CNAME" + // MX ... + MX RecordType = "MX" + // NS ... + NS RecordType = "NS" + // PTR ... + PTR RecordType = "PTR" + // SOA ... + SOA RecordType = "SOA" + // SRV ... + SRV RecordType = "SRV" + // TXT ... + TXT RecordType = "TXT" +) + +// PossibleRecordTypeValues returns an array of possible values for the RecordType const type. +func PossibleRecordTypeValues() []RecordType { + return []RecordType{A, AAAA, CAA, CNAME, MX, NS, PTR, SOA, SRV, TXT} +} + +// AaaaRecord an AAAA record. +type AaaaRecord struct { + // Ipv6Address - The IPv6 address of this AAAA record. + Ipv6Address *string `json:"ipv6Address,omitempty"` +} + +// ARecord an A record. +type ARecord struct { + // Ipv4Address - The IPv4 address of this A record. + Ipv4Address *string `json:"ipv4Address,omitempty"` +} + +// AzureEntityResource the resource model definition for a Azure Resource Manager resource with an etag. +type AzureEntityResource struct { + // Etag - READ-ONLY; Resource Etag. + Etag *string `json:"etag,omitempty"` + // ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; The name of the resource + Name *string `json:"name,omitempty"` + // Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts. + Type *string `json:"type,omitempty"` +} + +// CaaRecord a CAA record. +type CaaRecord struct { + // Flags - The flags for this CAA record as an integer between 0 and 255. + Flags *int32 `json:"flags,omitempty"` + // Tag - The tag for this CAA record. + Tag *string `json:"tag,omitempty"` + // Value - The value for this CAA record. + Value *string `json:"value,omitempty"` +} + +// CloudError an error message +type CloudError struct { + // Error - The error message body + Error *CloudErrorBody `json:"error,omitempty"` +} + +// CloudErrorBody the body of an error message +type CloudErrorBody struct { + // Code - The error code + Code *string `json:"code,omitempty"` + // Message - A description of what caused the error + Message *string `json:"message,omitempty"` + // Target - The target resource of the error message + Target *string `json:"target,omitempty"` + // Details - Extra error information + Details *[]CloudErrorBody `json:"details,omitempty"` +} + +// CnameRecord a CNAME record. +type CnameRecord struct { + // Cname - The canonical name for this CNAME record. + Cname *string `json:"cname,omitempty"` +} + +// MxRecord an MX record. +type MxRecord struct { + // Preference - The preference value for this MX record. + Preference *int32 `json:"preference,omitempty"` + // Exchange - The domain name of the mail host for this MX record. + Exchange *string `json:"exchange,omitempty"` +} + +// NsRecord an NS record. +type NsRecord struct { + // Nsdname - The name server name for this NS record. + Nsdname *string `json:"nsdname,omitempty"` +} + +// ProxyResource the resource model definition for a ARM proxy resource. It will have everything other than +// required location and tags +type ProxyResource struct { + // ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; The name of the resource + Name *string `json:"name,omitempty"` + // Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts. + Type *string `json:"type,omitempty"` +} + +// PtrRecord a PTR record. +type PtrRecord struct { + // Ptrdname - The PTR target domain name for this PTR record. + Ptrdname *string `json:"ptrdname,omitempty"` +} + +// RecordSet describes a DNS record set (a collection of DNS records with the same name and type). +type RecordSet struct { + autorest.Response `json:"-"` + // ID - READ-ONLY; The ID of the record set. + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; The name of the record set. + Name *string `json:"name,omitempty"` + // Type - READ-ONLY; The type of the record set. + Type *string `json:"type,omitempty"` + // Etag - The etag of the record set. + Etag *string `json:"etag,omitempty"` + // RecordSetProperties - The properties of the record set. + *RecordSetProperties `json:"properties,omitempty"` +} + +// MarshalJSON is the custom marshaler for RecordSet. +func (rs RecordSet) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if rs.Etag != nil { + objectMap["etag"] = rs.Etag + } + if rs.RecordSetProperties != nil { + objectMap["properties"] = rs.RecordSetProperties + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for RecordSet struct. +func (rs *RecordSet) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + rs.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + rs.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + rs.Type = &typeVar + } + case "etag": + if v != nil { + var etag string + err = json.Unmarshal(*v, &etag) + if err != nil { + return err + } + rs.Etag = &etag + } + case "properties": + if v != nil { + var recordSetProperties RecordSetProperties + err = json.Unmarshal(*v, &recordSetProperties) + if err != nil { + return err + } + rs.RecordSetProperties = &recordSetProperties + } + } + } + + return nil +} + +// RecordSetListResult the response to a record set List operation. +type RecordSetListResult struct { + autorest.Response `json:"-"` + // Value - Information about the record sets in the response. + Value *[]RecordSet `json:"value,omitempty"` + // NextLink - READ-ONLY; The continuation token for the next page of results. + NextLink *string `json:"nextLink,omitempty"` +} + +// RecordSetListResultIterator provides access to a complete listing of RecordSet values. +type RecordSetListResultIterator struct { + i int + page RecordSetListResultPage +} + +// NextWithContext advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *RecordSetListResultIterator) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetListResultIterator.NextWithContext") + defer func() { + sc := -1 + if iter.Response().Response.Response != nil { + sc = iter.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err = iter.page.NextWithContext(ctx) + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (iter *RecordSetListResultIterator) Next() error { + return iter.NextWithContext(context.Background()) +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter RecordSetListResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter RecordSetListResultIterator) Response() RecordSetListResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter RecordSetListResultIterator) Value() RecordSet { + if !iter.page.NotDone() { + return RecordSet{} + } + return iter.page.Values()[iter.i] +} + +// Creates a new instance of the RecordSetListResultIterator type. +func NewRecordSetListResultIterator(page RecordSetListResultPage) RecordSetListResultIterator { + return RecordSetListResultIterator{page: page} +} + +// IsEmpty returns true if the ListResult contains no values. +func (rslr RecordSetListResult) IsEmpty() bool { + return rslr.Value == nil || len(*rslr.Value) == 0 +} + +// recordSetListResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (rslr RecordSetListResult) recordSetListResultPreparer(ctx context.Context) (*http.Request, error) { + if rslr.NextLink == nil || len(to.String(rslr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare((&http.Request{}).WithContext(ctx), + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(rslr.NextLink))) +} + +// RecordSetListResultPage contains a page of RecordSet values. +type RecordSetListResultPage struct { + fn func(context.Context, RecordSetListResult) (RecordSetListResult, error) + rslr RecordSetListResult +} + +// NextWithContext advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *RecordSetListResultPage) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetListResultPage.NextWithContext") + defer func() { + sc := -1 + if page.Response().Response.Response != nil { + sc = page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + next, err := page.fn(ctx, page.rslr) + if err != nil { + return err + } + page.rslr = next + return nil +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (page *RecordSetListResultPage) Next() error { + return page.NextWithContext(context.Background()) +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page RecordSetListResultPage) NotDone() bool { + return !page.rslr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page RecordSetListResultPage) Response() RecordSetListResult { + return page.rslr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page RecordSetListResultPage) Values() []RecordSet { + if page.rslr.IsEmpty() { + return nil + } + return *page.rslr.Value +} + +// Creates a new instance of the RecordSetListResultPage type. +func NewRecordSetListResultPage(getNextPage func(context.Context, RecordSetListResult) (RecordSetListResult, error)) RecordSetListResultPage { + return RecordSetListResultPage{fn: getNextPage} +} + +// RecordSetProperties represents the properties of the records in the record set. +type RecordSetProperties struct { + // Metadata - The metadata attached to the record set. + Metadata map[string]*string `json:"metadata"` + // TTL - The TTL (time-to-live) of the records in the record set. + TTL *int64 `json:"TTL,omitempty"` + // Fqdn - READ-ONLY; Fully qualified domain name of the record set. + Fqdn *string `json:"fqdn,omitempty"` + // ARecords - The list of A records in the record set. + ARecords *[]ARecord `json:"ARecords,omitempty"` + // AaaaRecords - The list of AAAA records in the record set. + AaaaRecords *[]AaaaRecord `json:"AAAARecords,omitempty"` + // MxRecords - The list of MX records in the record set. + MxRecords *[]MxRecord `json:"MXRecords,omitempty"` + // NsRecords - The list of NS records in the record set. + NsRecords *[]NsRecord `json:"NSRecords,omitempty"` + // PtrRecords - The list of PTR records in the record set. + PtrRecords *[]PtrRecord `json:"PTRRecords,omitempty"` + // SrvRecords - The list of SRV records in the record set. + SrvRecords *[]SrvRecord `json:"SRVRecords,omitempty"` + // TxtRecords - The list of TXT records in the record set. + TxtRecords *[]TxtRecord `json:"TXTRecords,omitempty"` + // CnameRecord - The CNAME record in the record set. + CnameRecord *CnameRecord `json:"CNAMERecord,omitempty"` + // SoaRecord - The SOA record in the record set. + SoaRecord *SoaRecord `json:"SOARecord,omitempty"` + // CaaRecords - The list of CAA records in the record set. + CaaRecords *[]CaaRecord `json:"caaRecords,omitempty"` +} + +// MarshalJSON is the custom marshaler for RecordSetProperties. +func (rsp RecordSetProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if rsp.Metadata != nil { + objectMap["metadata"] = rsp.Metadata + } + if rsp.TTL != nil { + objectMap["TTL"] = rsp.TTL + } + if rsp.ARecords != nil { + objectMap["ARecords"] = rsp.ARecords + } + if rsp.AaaaRecords != nil { + objectMap["AAAARecords"] = rsp.AaaaRecords + } + if rsp.MxRecords != nil { + objectMap["MXRecords"] = rsp.MxRecords + } + if rsp.NsRecords != nil { + objectMap["NSRecords"] = rsp.NsRecords + } + if rsp.PtrRecords != nil { + objectMap["PTRRecords"] = rsp.PtrRecords + } + if rsp.SrvRecords != nil { + objectMap["SRVRecords"] = rsp.SrvRecords + } + if rsp.TxtRecords != nil { + objectMap["TXTRecords"] = rsp.TxtRecords + } + if rsp.CnameRecord != nil { + objectMap["CNAMERecord"] = rsp.CnameRecord + } + if rsp.SoaRecord != nil { + objectMap["SOARecord"] = rsp.SoaRecord + } + if rsp.CaaRecords != nil { + objectMap["caaRecords"] = rsp.CaaRecords + } + return json.Marshal(objectMap) +} + +// RecordSetUpdateParameters parameters supplied to update a record set. +type RecordSetUpdateParameters struct { + // RecordSet - Specifies information about the record set being updated. + RecordSet *RecordSet `json:"RecordSet,omitempty"` +} + +// Resource ... +type Resource struct { + // ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; The name of the resource + Name *string `json:"name,omitempty"` + // Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts. + Type *string `json:"type,omitempty"` +} + +// SoaRecord an SOA record. +type SoaRecord struct { + // Host - The domain name of the authoritative name server for this SOA record. + Host *string `json:"host,omitempty"` + // Email - The email contact for this SOA record. + Email *string `json:"email,omitempty"` + // SerialNumber - The serial number for this SOA record. + SerialNumber *int64 `json:"serialNumber,omitempty"` + // RefreshTime - The refresh value for this SOA record. + RefreshTime *int64 `json:"refreshTime,omitempty"` + // RetryTime - The retry time for this SOA record. + RetryTime *int64 `json:"retryTime,omitempty"` + // ExpireTime - The expire time for this SOA record. + ExpireTime *int64 `json:"expireTime,omitempty"` + // MinimumTTL - The minimum value for this SOA record. By convention this is used to determine the negative caching duration. + MinimumTTL *int64 `json:"minimumTTL,omitempty"` +} + +// SrvRecord an SRV record. +type SrvRecord struct { + // Priority - The priority value for this SRV record. + Priority *int32 `json:"priority,omitempty"` + // Weight - The weight value for this SRV record. + Weight *int32 `json:"weight,omitempty"` + // Port - The port value for this SRV record. + Port *int32 `json:"port,omitempty"` + // Target - The target domain name for this SRV record. + Target *string `json:"target,omitempty"` +} + +// SubResource a reference to a another resource +type SubResource struct { + // ID - Resource Id. + ID *string `json:"id,omitempty"` +} + +// TrackedResource the resource model definition for a ARM tracked top level resource +type TrackedResource struct { + // Tags - Resource tags. + Tags map[string]*string `json:"tags"` + // Location - The geo-location where the resource lives + Location *string `json:"location,omitempty"` + // ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; The name of the resource + Name *string `json:"name,omitempty"` + // Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts. + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for TrackedResource. +func (tr TrackedResource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if tr.Tags != nil { + objectMap["tags"] = tr.Tags + } + if tr.Location != nil { + objectMap["location"] = tr.Location + } + return json.Marshal(objectMap) +} + +// TxtRecord a TXT record. +type TxtRecord struct { + // Value - The text value of this TXT record. + Value *[]string `json:"value,omitempty"` +} + +// Zone describes a DNS zone. +type Zone struct { + autorest.Response `json:"-"` + // Etag - The etag of the zone. + Etag *string `json:"etag,omitempty"` + // ZoneProperties - The properties of the zone. + *ZoneProperties `json:"properties,omitempty"` + // Tags - Resource tags. + Tags map[string]*string `json:"tags"` + // Location - The geo-location where the resource lives + Location *string `json:"location,omitempty"` + // ID - READ-ONLY; Fully qualified resource Id for the resource. Ex - /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} + ID *string `json:"id,omitempty"` + // Name - READ-ONLY; The name of the resource + Name *string `json:"name,omitempty"` + // Type - READ-ONLY; The type of the resource. Ex- Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts. + Type *string `json:"type,omitempty"` +} + +// MarshalJSON is the custom marshaler for Zone. +func (z Zone) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]interface{}) + if z.Etag != nil { + objectMap["etag"] = z.Etag + } + if z.ZoneProperties != nil { + objectMap["properties"] = z.ZoneProperties + } + if z.Tags != nil { + objectMap["tags"] = z.Tags + } + if z.Location != nil { + objectMap["location"] = z.Location + } + return json.Marshal(objectMap) +} + +// UnmarshalJSON is the custom unmarshaler for Zone struct. +func (z *Zone) UnmarshalJSON(body []byte) error { + var m map[string]*json.RawMessage + err := json.Unmarshal(body, &m) + if err != nil { + return err + } + for k, v := range m { + switch k { + case "etag": + if v != nil { + var etag string + err = json.Unmarshal(*v, &etag) + if err != nil { + return err + } + z.Etag = &etag + } + case "properties": + if v != nil { + var zoneProperties ZoneProperties + err = json.Unmarshal(*v, &zoneProperties) + if err != nil { + return err + } + z.ZoneProperties = &zoneProperties + } + case "tags": + if v != nil { + var tags map[string]*string + err = json.Unmarshal(*v, &tags) + if err != nil { + return err + } + z.Tags = tags + } + case "location": + if v != nil { + var location string + err = json.Unmarshal(*v, &location) + if err != nil { + return err + } + z.Location = &location + } + case "id": + if v != nil { + var ID string + err = json.Unmarshal(*v, &ID) + if err != nil { + return err + } + z.ID = &ID + } + case "name": + if v != nil { + var name string + err = json.Unmarshal(*v, &name) + if err != nil { + return err + } + z.Name = &name + } + case "type": + if v != nil { + var typeVar string + err = json.Unmarshal(*v, &typeVar) + if err != nil { + return err + } + z.Type = &typeVar + } + } + } + + return nil +} + +// ZoneListResult the response to a Zone List or ListAll operation. +type ZoneListResult struct { + autorest.Response `json:"-"` + // Value - Information about the DNS zones. + Value *[]Zone `json:"value,omitempty"` + // NextLink - READ-ONLY; The continuation token for the next page of results. + NextLink *string `json:"nextLink,omitempty"` +} + +// ZoneListResultIterator provides access to a complete listing of Zone values. +type ZoneListResultIterator struct { + i int + page ZoneListResultPage +} + +// NextWithContext advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *ZoneListResultIterator) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZoneListResultIterator.NextWithContext") + defer func() { + sc := -1 + if iter.Response().Response.Response != nil { + sc = iter.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err = iter.page.NextWithContext(ctx) + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (iter *ZoneListResultIterator) Next() error { + return iter.NextWithContext(context.Background()) +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter ZoneListResultIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter ZoneListResultIterator) Response() ZoneListResult { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter ZoneListResultIterator) Value() Zone { + if !iter.page.NotDone() { + return Zone{} + } + return iter.page.Values()[iter.i] +} + +// Creates a new instance of the ZoneListResultIterator type. +func NewZoneListResultIterator(page ZoneListResultPage) ZoneListResultIterator { + return ZoneListResultIterator{page: page} +} + +// IsEmpty returns true if the ListResult contains no values. +func (zlr ZoneListResult) IsEmpty() bool { + return zlr.Value == nil || len(*zlr.Value) == 0 +} + +// zoneListResultPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (zlr ZoneListResult) zoneListResultPreparer(ctx context.Context) (*http.Request, error) { + if zlr.NextLink == nil || len(to.String(zlr.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare((&http.Request{}).WithContext(ctx), + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(zlr.NextLink))) +} + +// ZoneListResultPage contains a page of Zone values. +type ZoneListResultPage struct { + fn func(context.Context, ZoneListResult) (ZoneListResult, error) + zlr ZoneListResult +} + +// NextWithContext advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *ZoneListResultPage) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZoneListResultPage.NextWithContext") + defer func() { + sc := -1 + if page.Response().Response.Response != nil { + sc = page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + next, err := page.fn(ctx, page.zlr) + if err != nil { + return err + } + page.zlr = next + return nil +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (page *ZoneListResultPage) Next() error { + return page.NextWithContext(context.Background()) +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page ZoneListResultPage) NotDone() bool { + return !page.zlr.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page ZoneListResultPage) Response() ZoneListResult { + return page.zlr +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page ZoneListResultPage) Values() []Zone { + if page.zlr.IsEmpty() { + return nil + } + return *page.zlr.Value +} + +// Creates a new instance of the ZoneListResultPage type. +func NewZoneListResultPage(getNextPage func(context.Context, ZoneListResult) (ZoneListResult, error)) ZoneListResultPage { + return ZoneListResultPage{fn: getNextPage} +} + +// ZoneProperties represents the properties of the zone. +type ZoneProperties struct { + // MaxNumberOfRecordSets - READ-ONLY; The maximum number of record sets that can be created in this DNS zone. This is a read-only property and any attempt to set this value will be ignored. + MaxNumberOfRecordSets *int64 `json:"maxNumberOfRecordSets,omitempty"` + // NumberOfRecordSets - READ-ONLY; The current number of record sets in this DNS zone. This is a read-only property and any attempt to set this value will be ignored. + NumberOfRecordSets *int64 `json:"numberOfRecordSets,omitempty"` + // NameServers - READ-ONLY; The name servers for this DNS zone. This is a read-only property and any attempt to set this value will be ignored. + NameServers *[]string `json:"nameServers,omitempty"` +} + +// ZonesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. +type ZonesDeleteFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *ZonesDeleteFuture) Result(client ZonesClient) (ar autorest.Response, err error) { + var done bool + done, err = future.DoneWithContext(context.Background(), client) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesDeleteFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("dns.ZonesDeleteFuture") + return + } + ar.Response = future.Response() + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/recordsets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/recordsets.go new file mode 100644 index 000000000..b341b1e44 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/recordsets.go @@ -0,0 +1,715 @@ +package dns + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// RecordSetsClient is the the DNS Management Client. +type RecordSetsClient struct { + BaseClient +} + +// NewRecordSetsClient creates an instance of the RecordSetsClient client. +func NewRecordSetsClient(subscriptionID string) RecordSetsClient { + return NewRecordSetsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewRecordSetsClientWithBaseURI creates an instance of the RecordSetsClient client. +func NewRecordSetsClientWithBaseURI(baseURI string, subscriptionID string) RecordSetsClient { + return RecordSetsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a record set within a DNS zone. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +// relativeRecordSetName - the name of the record set, relative to the name of the zone. +// recordType - the type of DNS record in this record set. Record sets of type SOA can be updated but not +// created (they are created when the DNS zone is created). +// parameters - parameters supplied to the CreateOrUpdate operation. +// ifMatch - the etag of the record set. Omit this value to always overwrite the current record set. Specify +// the last-seen etag value to prevent accidentally overwriting any concurrent changes. +// ifNoneMatch - set to '*' to allow a new record set to be created, but to prevent updating an existing record +// set. Other values will be ignored. +func (client RecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string, ifNoneMatch string) (result RecordSet, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.CreateOrUpdate") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.RecordSetsClient", "CreateOrUpdate", err.Error()) + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, parameters, ifMatch, ifNoneMatch) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client RecordSetsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string, ifNoneMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": autorest.Encode("path", recordType), + "relativeRecordSetName": relativeRecordSetName, + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + parameters.ID = nil + parameters.Name = nil + parameters.Type = nil + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + if len(ifMatch) > 0 { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithHeader("If-Match", autorest.String(ifMatch))) + } + if len(ifNoneMatch) > 0 { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) + } + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) CreateOrUpdateResponder(resp *http.Response) (result RecordSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a record set from a DNS zone. This operation cannot be undone. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +// relativeRecordSetName - the name of the record set, relative to the name of the zone. +// recordType - the type of DNS record in this record set. Record sets of type SOA cannot be deleted (they are +// deleted when the DNS zone is deleted). +// ifMatch - the etag of the record set. Omit this value to always delete the current record set. Specify the +// last-seen etag value to prevent accidentally deleting any concurrent changes. +func (client RecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, ifMatch string) (result autorest.Response, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Delete") + defer func() { + sc := -1 + if result.Response != nil { + sc = result.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.RecordSetsClient", "Delete", err.Error()) + } + + req, err := client.DeletePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, ifMatch) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client RecordSetsClient) DeletePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, ifMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": autorest.Encode("path", recordType), + "relativeRecordSetName": relativeRecordSetName, + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + if len(ifMatch) > 0 { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithHeader("If-Match", autorest.String(ifMatch))) + } + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) DeleteSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets a record set. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +// relativeRecordSetName - the name of the record set, relative to the name of the zone. +// recordType - the type of DNS record in this record set. +func (client RecordSetsClient) Get(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType) (result RecordSet, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Get") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.RecordSetsClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client RecordSetsClient) GetPreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": autorest.Encode("path", recordType), + "relativeRecordSetName": relativeRecordSetName, + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) GetSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) GetResponder(resp *http.Response) (result RecordSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByDNSZone lists all record sets in a DNS zone. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. +// recordsetnamesuffix - the suffix label of the record set name that has to be used to filter the record set +// enumerations. If this parameter is specified, Enumeration will return only records that end with +// . +func (client RecordSetsClient) ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByDNSZone") + defer func() { + sc := -1 + if result.rslr.Response.Response != nil { + sc = result.rslr.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.RecordSetsClient", "ListByDNSZone", err.Error()) + } + + result.fn = client.listByDNSZoneNextResults + req, err := client.ListByDNSZonePreparer(ctx, resourceGroupName, zoneName, top, recordsetnamesuffix) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", nil, "Failure preparing request") + return + } + + resp, err := client.ListByDNSZoneSender(req) + if err != nil { + result.rslr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", resp, "Failure sending request") + return + } + + result.rslr, err = client.ListByDNSZoneResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", resp, "Failure responding to request") + } + + return +} + +// ListByDNSZonePreparer prepares the ListByDNSZone request. +func (client RecordSetsClient) ListByDNSZonePreparer(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + if len(recordsetnamesuffix) > 0 { + queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordsetnamesuffix) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/recordsets", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByDNSZoneSender sends the ListByDNSZone request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) ListByDNSZoneSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListByDNSZoneResponder handles the response to the ListByDNSZone request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) ListByDNSZoneResponder(resp *http.Response) (result RecordSetListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByDNSZoneNextResults retrieves the next set of results, if any. +func (client RecordSetsClient) listByDNSZoneNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) { + req, err := lastResults.recordSetListResultPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByDNSZoneSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByDNSZoneResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByDNSZoneComplete enumerates all values, automatically crossing page boundaries as required. +func (client RecordSetsClient) ListByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByDNSZone") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.ListByDNSZone(ctx, resourceGroupName, zoneName, top, recordsetnamesuffix) + return +} + +// ListByType lists the record sets of a specified type in a DNS zone. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +// recordType - the type of record sets to enumerate. +// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. +// recordsetnamesuffix - the suffix label of the record set name that has to be used to filter the record set +// enumerations. If this parameter is specified, Enumeration will return only records that end with +// . +func (client RecordSetsClient) ListByType(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByType") + defer func() { + sc := -1 + if result.rslr.Response.Response != nil { + sc = result.rslr.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.RecordSetsClient", "ListByType", err.Error()) + } + + result.fn = client.listByTypeNextResults + req, err := client.ListByTypePreparer(ctx, resourceGroupName, zoneName, recordType, top, recordsetnamesuffix) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", nil, "Failure preparing request") + return + } + + resp, err := client.ListByTypeSender(req) + if err != nil { + result.rslr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", resp, "Failure sending request") + return + } + + result.rslr, err = client.ListByTypeResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", resp, "Failure responding to request") + } + + return +} + +// ListByTypePreparer prepares the ListByType request. +func (client RecordSetsClient) ListByTypePreparer(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": autorest.Encode("path", recordType), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + if len(recordsetnamesuffix) > 0 { + queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordsetnamesuffix) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByTypeSender sends the ListByType request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) ListByTypeSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListByTypeResponder handles the response to the ListByType request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) ListByTypeResponder(resp *http.Response) (result RecordSetListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByTypeNextResults retrieves the next set of results, if any. +func (client RecordSetsClient) listByTypeNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) { + req, err := lastResults.recordSetListResultPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByTypeSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByTypeResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByTypeComplete enumerates all values, automatically crossing page boundaries as required. +func (client RecordSetsClient) ListByTypeComplete(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByType") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.ListByType(ctx, resourceGroupName, zoneName, recordType, top, recordsetnamesuffix) + return +} + +// Update updates a record set within a DNS zone. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +// relativeRecordSetName - the name of the record set, relative to the name of the zone. +// recordType - the type of DNS record in this record set. +// parameters - parameters supplied to the Update operation. +// ifMatch - the etag of the record set. Omit this value to always overwrite the current record set. Specify +// the last-seen etag value to prevent accidentally overwriting concurrent changes. +func (client RecordSetsClient) Update(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string) (result RecordSet, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Update") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.RecordSetsClient", "Update", err.Error()) + } + + req, err := client.UpdatePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, parameters, ifMatch) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Update", nil, "Failure preparing request") + return + } + + resp, err := client.UpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Update", resp, "Failure sending request") + return + } + + result, err = client.UpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Update", resp, "Failure responding to request") + } + + return +} + +// UpdatePreparer prepares the Update request. +func (client RecordSetsClient) UpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": autorest.Encode("path", recordType), + "relativeRecordSetName": relativeRecordSetName, + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + parameters.ID = nil + parameters.Name = nil + parameters.Type = nil + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + if len(ifMatch) > 0 { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithHeader("If-Match", autorest.String(ifMatch))) + } + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// UpdateSender sends the Update request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) UpdateSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// UpdateResponder handles the response to the Update request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) UpdateResponder(resp *http.Response) (result RecordSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/version.go new file mode 100644 index 000000000..0556b6130 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/version.go @@ -0,0 +1,30 @@ +package dns + +import "github.com/Azure/azure-sdk-for-go/version" + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return "Azure-SDK-For-Go/" + version.Number + " dns/2017-09-01" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return version.Number +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/zones.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/zones.go new file mode 100644 index 000000000..7bc248d69 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns/zones.go @@ -0,0 +1,572 @@ +package dns + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// ZonesClient is the the DNS Management Client. +type ZonesClient struct { + BaseClient +} + +// NewZonesClient creates an instance of the ZonesClient client. +func NewZonesClient(subscriptionID string) ZonesClient { + return NewZonesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewZonesClientWithBaseURI creates an instance of the ZonesClient client. +func NewZonesClientWithBaseURI(baseURI string, subscriptionID string) ZonesClient { + return ZonesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates or updates a DNS zone. Does not modify DNS records within the zone. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +// parameters - parameters supplied to the CreateOrUpdate operation. +// ifMatch - the etag of the DNS zone. Omit this value to always overwrite the current zone. Specify the +// last-seen etag value to prevent accidentally overwriting any concurrent changes. +// ifNoneMatch - set to '*' to allow a new DNS zone to be created, but to prevent updating an existing zone. +// Other values will be ignored. +func (client ZonesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, parameters Zone, ifMatch string, ifNoneMatch string) (result Zone, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.CreateOrUpdate") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.ZonesClient", "CreateOrUpdate", err.Error()) + } + + req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, zoneName, parameters, ifMatch, ifNoneMatch) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ZonesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, parameters Zone, ifMatch string, ifNoneMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + if len(ifMatch) > 0 { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithHeader("If-Match", autorest.String(ifMatch))) + } + if len(ifNoneMatch) > 0 { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) + } + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ZonesClient) CreateOrUpdateResponder(resp *http.Response) (result Zone, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a DNS zone. WARNING: All DNS records in the zone will also be deleted. This operation cannot be +// undone. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +// ifMatch - the etag of the DNS zone. Omit this value to always delete the current zone. Specify the last-seen +// etag value to prevent accidentally deleting any concurrent changes. +func (client ZonesClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, ifMatch string) (result ZonesDeleteFuture, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.Delete") + defer func() { + sc := -1 + if result.Response() != nil { + sc = result.Response().StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.ZonesClient", "Delete", err.Error()) + } + + req, err := client.DeletePreparer(ctx, resourceGroupName, zoneName, ifMatch) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = client.DeleteSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", result.Response(), "Failure sending request") + return + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ZonesClient) DeletePreparer(ctx context.Context, resourceGroupName string, zoneName string, ifMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + if len(ifMatch) > 0 { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithHeader("If-Match", autorest.String(ifMatch))) + } + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) DeleteSender(req *http.Request) (future ZonesDeleteFuture, err error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + var resp *http.Response + resp, err = autorest.SendWithSender(client, req, sd...) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ZonesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets a DNS zone. Retrieves the zone properties, but not the record sets within the zone. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// zoneName - the name of the DNS zone (without a terminating dot). +func (client ZonesClient) Get(ctx context.Context, resourceGroupName string, zoneName string) (result Zone, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.Get") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.ZonesClient", "Get", err.Error()) + } + + req, err := client.GetPreparer(ctx, resourceGroupName, zoneName) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ZonesClient) GetPreparer(ctx context.Context, resourceGroupName string, zoneName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "zoneName": autorest.Encode("path", zoneName), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) GetSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ZonesClient) GetResponder(resp *http.Response) (result Zone, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists the DNS zones in all resource groups in a subscription. +// Parameters: +// top - the maximum number of DNS zones to return. If not specified, returns up to 100 zones. +func (client ZonesClient) List(ctx context.Context, top *int32) (result ZoneListResultPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.List") + defer func() { + sc := -1 + if result.zlr.Response.Response != nil { + sc = result.zlr.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.ZonesClient", "List", err.Error()) + } + + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, top) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.zlr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", resp, "Failure sending request") + return + } + + result.zlr, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ZonesClient) ListPreparer(ctx context.Context, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/dnszones", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) ListSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ZonesClient) ListResponder(resp *http.Response) (result ZoneListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client ZonesClient) listNextResults(ctx context.Context, lastResults ZoneListResult) (result ZoneListResult, err error) { + req, err := lastResults.zoneListResultPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client ZonesClient) ListComplete(ctx context.Context, top *int32) (result ZoneListResultIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.List") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.List(ctx, top) + return +} + +// ListByResourceGroup lists the DNS zones within a resource group. +// Parameters: +// resourceGroupName - the name of the resource group. The name is case insensitive. +// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. +func (client ZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result ZoneListResultPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.ListByResourceGroup") + defer func() { + sc := -1 + if result.zlr.Response.Response != nil { + sc = result.zlr.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: resourceGroupName, + Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil}, + {Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil}, + {Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}, + {TargetValue: client.SubscriptionID, + Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil { + return result, validation.NewError("dns.ZonesClient", "ListByResourceGroup", err.Error()) + } + + result.fn = client.listByResourceGroupNextResults + req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName, top) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.zlr.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result.zlr, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client ZonesClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client)) + return autorest.SendWithSender(client, req, sd...) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client ZonesClient) ListByResourceGroupResponder(resp *http.Response) (result ZoneListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listByResourceGroupNextResults retrieves the next set of results, if any. +func (client ZonesClient) listByResourceGroupNextResults(ctx context.Context, lastResults ZoneListResult) (result ZoneListResult, err error) { + req, err := lastResults.zoneListResultPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") + } + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. +func (client ZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result ZoneListResultIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.ListByResourceGroup") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.ListByResourceGroup(ctx, resourceGroupName, top) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go new file mode 100644 index 000000000..2aaec4050 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go @@ -0,0 +1,21 @@ +package version + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Number contains the semantic version of this SDK. +const Number = "v32.4.0" diff --git a/vendor/github.com/Azure/go-autorest/autorest/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/README.md b/vendor/github.com/Azure/go-autorest/autorest/adal/README.md new file mode 100644 index 000000000..7b0c4bc4d --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/README.md @@ -0,0 +1,292 @@ +# Azure Active Directory authentication for Go + +This is a standalone package for authenticating with Azure Active +Directory from other Go libraries and applications, in particular the [Azure SDK +for Go](https://github.com/Azure/azure-sdk-for-go). + +Note: Despite the package's name it is not related to other "ADAL" libraries +maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues +should be opened in [this repo's](https://github.com/Azure/go-autorest/issues) +or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue +trackers. + +## Install + +```bash +go get -u github.com/Azure/go-autorest/autorest/adal +``` + +## Usage + +An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli). + +### Register an Azure AD Application with secret + + +1. Register a new application with a `secret` credential + + ``` + az ad app create \ + --display-name example-app \ + --homepage https://example-app/home \ + --identifier-uris https://example-app/app \ + --password secret + ``` + +2. Create a service principal using the `Application ID` from previous step + + ``` + az ad sp create --id "Application ID" + ``` + + * Replace `Application ID` with `appId` from step 1. + +### Register an Azure AD Application with certificate + +1. Create a private key + + ``` + openssl genrsa -out "example-app.key" 2048 + ``` + +2. Create the certificate + + ``` + openssl req -new -key "example-app.key" -subj "/CN=example-app" -out "example-app.csr" + openssl x509 -req -in "example-app.csr" -signkey "example-app.key" -out "example-app.crt" -days 10000 + ``` + +3. Create the PKCS12 version of the certificate containing also the private key + + ``` + openssl pkcs12 -export -out "example-app.pfx" -inkey "example-app.key" -in "example-app.crt" -passout pass: + + ``` + +4. Register a new application with the certificate content form `example-app.crt` + + ``` + certificateContents="$(tail -n+2 "example-app.crt" | head -n-1)" + + az ad app create \ + --display-name example-app \ + --homepage https://example-app/home \ + --identifier-uris https://example-app/app \ + --key-usage Verify --end-date 2018-01-01 \ + --key-value "${certificateContents}" + ``` + +5. Create a service principal using the `Application ID` from previous step + + ``` + az ad sp create --id "APPLICATION_ID" + ``` + + * Replace `APPLICATION_ID` with `appId` from step 4. + + +### Grant the necessary permissions + +Azure relies on a Role-Based Access Control (RBAC) model to manage the access to resources at a fine-grained +level. There is a set of [pre-defined roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-built-in-roles) +which can be assigned to a service principal of an Azure AD application depending of your needs. + +``` +az role assignment create --assigner "SERVICE_PRINCIPAL_ID" --role "ROLE_NAME" +``` + +* Replace the `SERVICE_PRINCIPAL_ID` with the `appId` from previous step. +* Replace the `ROLE_NAME` with a role name of your choice. + +It is also possible to define custom role definitions. + +``` +az role definition create --role-definition role-definition.json +``` + +* Check [custom roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-control-custom-roles) for more details regarding the content of `role-definition.json` file. + + +### Acquire Access Token + +The common configuration used by all flows: + +```Go +const activeDirectoryEndpoint = "https://login.microsoftonline.com/" +tenantID := "TENANT_ID" +oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID) + +applicationID := "APPLICATION_ID" + +callback := func(token adal.Token) error { + // This is called after the token is acquired +} + +// The resource for which the token is acquired +resource := "https://management.core.windows.net/" +``` + +* Replace the `TENANT_ID` with your tenant ID. +* Replace the `APPLICATION_ID` with the value from previous section. + +#### Client Credentials + +```Go +applicationSecret := "APPLICATION_SECRET" + +spt, err := adal.NewServicePrincipalToken( + oauthConfig, + appliationID, + applicationSecret, + resource, + callbacks...) +if err != nil { + return nil, err +} + +// Acquire a new access token +err = spt.Refresh() +if (err == nil) { + token := spt.Token +} +``` + +* Replace the `APPLICATION_SECRET` with the `password` value from previous section. + +#### Client Certificate + +```Go +certificatePath := "./example-app.pfx" + +certData, err := ioutil.ReadFile(certificatePath) +if err != nil { + return nil, fmt.Errorf("failed to read the certificate file (%s): %v", certificatePath, err) +} + +// Get the certificate and private key from pfx file +certificate, rsaPrivateKey, err := decodePkcs12(certData, "") +if err != nil { + return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err) +} + +spt, err := adal.NewServicePrincipalTokenFromCertificate( + oauthConfig, + applicationID, + certificate, + rsaPrivateKey, + resource, + callbacks...) + +// Acquire a new access token +err = spt.Refresh() +if (err == nil) { + token := spt.Token +} +``` + +* Update the certificate path to point to the example-app.pfx file which was created in previous section. + + +#### Device Code + +```Go +oauthClient := &http.Client{} + +// Acquire the device code +deviceCode, err := adal.InitiateDeviceAuth( + oauthClient, + oauthConfig, + applicationID, + resource) +if err != nil { + return nil, fmt.Errorf("Failed to start device auth flow: %s", err) +} + +// Display the authentication message +fmt.Println(*deviceCode.Message) + +// Wait here until the user is authenticated +token, err := adal.WaitForUserCompletion(oauthClient, deviceCode) +if err != nil { + return nil, fmt.Errorf("Failed to finish device auth flow: %s", err) +} + +spt, err := adal.NewServicePrincipalTokenFromManualToken( + oauthConfig, + applicationID, + resource, + *token, + callbacks...) + +if (err == nil) { + token := spt.Token +} +``` + +#### Username password authenticate + +```Go +spt, err := adal.NewServicePrincipalTokenFromUsernamePassword( + oauthConfig, + applicationID, + username, + password, + resource, + callbacks...) + +if (err == nil) { + token := spt.Token +} +``` + +#### Authorization code authenticate + +``` Go +spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode( + oauthConfig, + applicationID, + clientSecret, + authorizationCode, + redirectURI, + resource, + callbacks...) + +err = spt.Refresh() +if (err == nil) { + token := spt.Token +} +``` + +### Command Line Tool + +A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above. + +``` +adal -h + +Usage of ./adal: + -applicationId string + application id + -certificatePath string + path to pk12/PFC application certificate + -mode string + authentication mode (device, secret, cert, refresh) (default "device") + -resource string + resource for which the token is requested + -secret string + application secret + -tenantId string + tenant id + -tokenCachePath string + location of oath token cache (default "/home/cgc/.adal/accessToken.json") +``` + +Example acquire a token for `https://management.core.windows.net/` using device code flow: + +``` +adal -mode device \ + -applicationId "APPLICATION_ID" \ + -tenantId "TENANT_ID" \ + -resource https://management.core.windows.net/ + +``` diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go new file mode 100644 index 000000000..fa5964742 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go @@ -0,0 +1,151 @@ +package adal + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "errors" + "fmt" + "net/url" +) + +const ( + activeDirectoryEndpointTemplate = "%s/oauth2/%s%s" +) + +// OAuthConfig represents the endpoints needed +// in OAuth operations +type OAuthConfig struct { + AuthorityEndpoint url.URL `json:"authorityEndpoint"` + AuthorizeEndpoint url.URL `json:"authorizeEndpoint"` + TokenEndpoint url.URL `json:"tokenEndpoint"` + DeviceCodeEndpoint url.URL `json:"deviceCodeEndpoint"` +} + +// IsZero returns true if the OAuthConfig object is zero-initialized. +func (oac OAuthConfig) IsZero() bool { + return oac == OAuthConfig{} +} + +func validateStringParam(param, name string) error { + if len(param) == 0 { + return fmt.Errorf("parameter '" + name + "' cannot be empty") + } + return nil +} + +// NewOAuthConfig returns an OAuthConfig with tenant specific urls +func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) { + apiVer := "1.0" + return NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID, &apiVer) +} + +// NewOAuthConfigWithAPIVersion returns an OAuthConfig with tenant specific urls. +// If apiVersion is not nil the "api-version" query parameter will be appended to the endpoint URLs with the specified value. +func NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID string, apiVersion *string) (*OAuthConfig, error) { + if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil { + return nil, err + } + api := "" + // it's legal for tenantID to be empty so don't validate it + if apiVersion != nil { + if err := validateStringParam(*apiVersion, "apiVersion"); err != nil { + return nil, err + } + api = fmt.Sprintf("?api-version=%s", *apiVersion) + } + u, err := url.Parse(activeDirectoryEndpoint) + if err != nil { + return nil, err + } + authorityURL, err := u.Parse(tenantID) + if err != nil { + return nil, err + } + authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", api)) + if err != nil { + return nil, err + } + tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", api)) + if err != nil { + return nil, err + } + deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", api)) + if err != nil { + return nil, err + } + + return &OAuthConfig{ + AuthorityEndpoint: *authorityURL, + AuthorizeEndpoint: *authorizeURL, + TokenEndpoint: *tokenURL, + DeviceCodeEndpoint: *deviceCodeURL, + }, nil +} + +// MultiTenantOAuthConfig provides endpoints for primary and aulixiary tenant IDs. +type MultiTenantOAuthConfig interface { + PrimaryTenant() *OAuthConfig + AuxiliaryTenants() []*OAuthConfig +} + +// OAuthOptions contains optional OAuthConfig creation arguments. +type OAuthOptions struct { + APIVersion string +} + +func (c OAuthOptions) apiVersion() string { + if c.APIVersion != "" { + return fmt.Sprintf("?api-version=%s", c.APIVersion) + } + return "1.0" +} + +// NewMultiTenantOAuthConfig creates an object that support multitenant OAuth configuration. +// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/authenticate-multi-tenant for more information. +func NewMultiTenantOAuthConfig(activeDirectoryEndpoint, primaryTenantID string, auxiliaryTenantIDs []string, options OAuthOptions) (MultiTenantOAuthConfig, error) { + if len(auxiliaryTenantIDs) == 0 || len(auxiliaryTenantIDs) > 3 { + return nil, errors.New("must specify one to three auxiliary tenants") + } + mtCfg := multiTenantOAuthConfig{ + cfgs: make([]*OAuthConfig, len(auxiliaryTenantIDs)+1), + } + apiVer := options.apiVersion() + pri, err := NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, primaryTenantID, &apiVer) + if err != nil { + return nil, fmt.Errorf("failed to create OAuthConfig for primary tenant: %v", err) + } + mtCfg.cfgs[0] = pri + for i := range auxiliaryTenantIDs { + aux, err := NewOAuthConfig(activeDirectoryEndpoint, auxiliaryTenantIDs[i]) + if err != nil { + return nil, fmt.Errorf("failed to create OAuthConfig for tenant '%s': %v", auxiliaryTenantIDs[i], err) + } + mtCfg.cfgs[i+1] = aux + } + return mtCfg, nil +} + +type multiTenantOAuthConfig struct { + // first config in the slice is the primary tenant + cfgs []*OAuthConfig +} + +func (m multiTenantOAuthConfig) PrimaryTenant() *OAuthConfig { + return m.cfgs[0] +} + +func (m multiTenantOAuthConfig) AuxiliaryTenants() []*OAuthConfig { + return m.cfgs[1:] +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go b/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go new file mode 100644 index 000000000..b38f4c245 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go @@ -0,0 +1,242 @@ +package adal + +// Copyright 2017 Microsoft Corporation +// +// 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. + +/* + This file is largely based on rjw57/oauth2device's code, with the follow differences: + * scope -> resource, and only allow a single one + * receive "Message" in the DeviceCode struct and show it to users as the prompt + * azure-xplat-cli has the following behavior that this emulates: + - does not send client_secret during the token exchange + - sends resource again in the token exchange request +*/ + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + "time" +) + +const ( + logPrefix = "autorest/adal/devicetoken:" +) + +var ( + // ErrDeviceGeneric represents an unknown error from the token endpoint when using device flow + ErrDeviceGeneric = fmt.Errorf("%s Error while retrieving OAuth token: Unknown Error", logPrefix) + + // ErrDeviceAccessDenied represents an access denied error from the token endpoint when using device flow + ErrDeviceAccessDenied = fmt.Errorf("%s Error while retrieving OAuth token: Access Denied", logPrefix) + + // ErrDeviceAuthorizationPending represents the server waiting on the user to complete the device flow + ErrDeviceAuthorizationPending = fmt.Errorf("%s Error while retrieving OAuth token: Authorization Pending", logPrefix) + + // ErrDeviceCodeExpired represents the server timing out and expiring the code during device flow + ErrDeviceCodeExpired = fmt.Errorf("%s Error while retrieving OAuth token: Code Expired", logPrefix) + + // ErrDeviceSlowDown represents the service telling us we're polling too often during device flow + ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix) + + // ErrDeviceCodeEmpty represents an empty device code from the device endpoint while using device flow + ErrDeviceCodeEmpty = fmt.Errorf("%s Error while retrieving device code: Device Code Empty", logPrefix) + + // ErrOAuthTokenEmpty represents an empty OAuth token from the token endpoint when using device flow + ErrOAuthTokenEmpty = fmt.Errorf("%s Error while retrieving OAuth token: Token Empty", logPrefix) + + errCodeSendingFails = "Error occurred while sending request for Device Authorization Code" + errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint" + errTokenSendingFails = "Error occurred while sending request with device code for a token" + errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)" + errStatusNotOK = "Error HTTP status != 200" +) + +// DeviceCode is the object returned by the device auth endpoint +// It contains information to instruct the user to complete the auth flow +type DeviceCode struct { + DeviceCode *string `json:"device_code,omitempty"` + UserCode *string `json:"user_code,omitempty"` + VerificationURL *string `json:"verification_url,omitempty"` + ExpiresIn *int64 `json:"expires_in,string,omitempty"` + Interval *int64 `json:"interval,string,omitempty"` + + Message *string `json:"message"` // Azure specific + Resource string // store the following, stored when initiating, used when exchanging + OAuthConfig OAuthConfig + ClientID string +} + +// TokenError is the object returned by the token exchange endpoint +// when something is amiss +type TokenError struct { + Error *string `json:"error,omitempty"` + ErrorCodes []int `json:"error_codes,omitempty"` + ErrorDescription *string `json:"error_description,omitempty"` + Timestamp *string `json:"timestamp,omitempty"` + TraceID *string `json:"trace_id,omitempty"` +} + +// DeviceToken is the object return by the token exchange endpoint +// It can either look like a Token or an ErrorToken, so put both here +// and check for presence of "Error" to know if we are in error state +type deviceToken struct { + Token + TokenError +} + +// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode +// that can be used with CheckForUserCompletion or WaitForUserCompletion. +func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) { + v := url.Values{ + "client_id": []string{clientID}, + "resource": []string{resource}, + } + + s := v.Encode() + body := ioutil.NopCloser(strings.NewReader(s)) + + req, err := http.NewRequest(http.MethodPost, oauthConfig.DeviceCodeEndpoint.String(), body) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error()) + } + + req.ContentLength = int64(len(s)) + req.Header.Set(contentType, mimeTypeFormPost) + resp, err := sender.Do(req) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error()) + } + defer resp.Body.Close() + + rb, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error()) + } + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, errStatusNotOK) + } + + if len(strings.Trim(string(rb), " ")) == 0 { + return nil, ErrDeviceCodeEmpty + } + + var code DeviceCode + err = json.Unmarshal(rb, &code) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error()) + } + + code.ClientID = clientID + code.Resource = resource + code.OAuthConfig = oauthConfig + + return &code, nil +} + +// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint +// to see if the device flow has: been completed, timed out, or otherwise failed +func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) { + v := url.Values{ + "client_id": []string{code.ClientID}, + "code": []string{*code.DeviceCode}, + "grant_type": []string{OAuthGrantTypeDeviceCode}, + "resource": []string{code.Resource}, + } + + s := v.Encode() + body := ioutil.NopCloser(strings.NewReader(s)) + + req, err := http.NewRequest(http.MethodPost, code.OAuthConfig.TokenEndpoint.String(), body) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error()) + } + + req.ContentLength = int64(len(s)) + req.Header.Set(contentType, mimeTypeFormPost) + resp, err := sender.Do(req) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error()) + } + defer resp.Body.Close() + + rb, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error()) + } + + if resp.StatusCode != http.StatusOK && len(strings.Trim(string(rb), " ")) == 0 { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, errStatusNotOK) + } + if len(strings.Trim(string(rb), " ")) == 0 { + return nil, ErrOAuthTokenEmpty + } + + var token deviceToken + err = json.Unmarshal(rb, &token) + if err != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error()) + } + + if token.Error == nil { + return &token.Token, nil + } + + switch *token.Error { + case "authorization_pending": + return nil, ErrDeviceAuthorizationPending + case "slow_down": + return nil, ErrDeviceSlowDown + case "access_denied": + return nil, ErrDeviceAccessDenied + case "code_expired": + return nil, ErrDeviceCodeExpired + default: + return nil, ErrDeviceGeneric + } +} + +// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs. +// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'. +func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) { + intervalDuration := time.Duration(*code.Interval) * time.Second + waitDuration := intervalDuration + + for { + token, err := CheckForUserCompletion(sender, code) + + if err == nil { + return token, nil + } + + switch err { + case ErrDeviceSlowDown: + waitDuration += waitDuration + case ErrDeviceAuthorizationPending: + // noop + default: // everything else is "fatal" to us + return nil, err + } + + if waitDuration > (intervalDuration * 3) { + return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix) + } + + time.Sleep(waitDuration) + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/go.mod b/vendor/github.com/Azure/go-autorest/autorest/adal/go.mod new file mode 100644 index 000000000..5c95dbfea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/go.mod @@ -0,0 +1,11 @@ +module github.com/Azure/go-autorest/autorest/adal + +go 1.12 + +require ( + github.com/Azure/go-autorest/autorest/date v0.1.0 + github.com/Azure/go-autorest/autorest/mocks v0.1.0 + github.com/Azure/go-autorest/tracing v0.1.0 + github.com/dgrijalva/jwt-go v3.2.0+incompatible + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 +) diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/go.sum b/vendor/github.com/Azure/go-autorest/autorest/adal/go.sum new file mode 100644 index 000000000..ef9d10161 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/go.sum @@ -0,0 +1,139 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc= +contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= +github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc= +github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= +github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go b/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go new file mode 100644 index 000000000..9e15f2751 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go @@ -0,0 +1,73 @@ +package adal + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" +) + +// LoadToken restores a Token object from a file located at 'path'. +func LoadToken(path string) (*Token, error) { + file, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) + } + defer file.Close() + + var token Token + + dec := json.NewDecoder(file) + if err = dec.Decode(&token); err != nil { + return nil, fmt.Errorf("failed to decode contents of file (%s) into Token representation: %v", path, err) + } + return &token, nil +} + +// SaveToken persists an oauth token at the given location on disk. +// It moves the new file into place so it can safely be used to replace an existing file +// that maybe accessed by multiple processes. +func SaveToken(path string, mode os.FileMode, token Token) error { + dir := filepath.Dir(path) + err := os.MkdirAll(dir, os.ModePerm) + if err != nil { + return fmt.Errorf("failed to create directory (%s) to store token in: %v", dir, err) + } + + newFile, err := ioutil.TempFile(dir, "token") + if err != nil { + return fmt.Errorf("failed to create the temp file to write the token: %v", err) + } + tempPath := newFile.Name() + + if err := json.NewEncoder(newFile).Encode(token); err != nil { + return fmt.Errorf("failed to encode token to file (%s) while saving token: %v", tempPath, err) + } + if err := newFile.Close(); err != nil { + return fmt.Errorf("failed to close temp file %s: %v", tempPath, err) + } + + // Atomic replace to avoid multi-writer file corruptions + if err := os.Rename(tempPath, path); err != nil { + return fmt.Errorf("failed to move temporary token to desired output location. src=%s dst=%s: %v", tempPath, path, err) + } + if err := os.Chmod(path, mode); err != nil { + return fmt.Errorf("failed to chmod the token file %s: %v", path, err) + } + return nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go b/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go new file mode 100644 index 000000000..834401e00 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go @@ -0,0 +1,60 @@ +package adal + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "net/http" +) + +const ( + contentType = "Content-Type" + mimeTypeFormPost = "application/x-www-form-urlencoded" +) + +// Sender is the interface that wraps the Do method to send HTTP requests. +// +// The standard http.Client conforms to this interface. +type Sender interface { + Do(*http.Request) (*http.Response, error) +} + +// SenderFunc is a method that implements the Sender interface. +type SenderFunc func(*http.Request) (*http.Response, error) + +// Do implements the Sender interface on SenderFunc. +func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { + return sf(r) +} + +// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the +// http.Request and pass it along or, first, pass the http.Request along then react to the +// http.Response result. +type SendDecorator func(Sender) Sender + +// CreateSender creates, decorates, and returns, as a Sender, the default http.Client. +func CreateSender(decorators ...SendDecorator) Sender { + return DecorateSender(&http.Client{}, decorators...) +} + +// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to +// the Sender. Decorators are applied in the order received, but their affect upon the request +// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a +// post-decorator (pass the http.Request along and react to the results in http.Response). +func DecorateSender(s Sender, decorators ...SendDecorator) Sender { + for _, decorate := range decorators { + s = decorate(s) + } + return s +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go new file mode 100644 index 000000000..4083e76e6 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go @@ -0,0 +1,1055 @@ +package adal + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "crypto/x509" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "math" + "net" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/tracing" + "github.com/dgrijalva/jwt-go" +) + +const ( + defaultRefresh = 5 * time.Minute + + // OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow + OAuthGrantTypeDeviceCode = "device_code" + + // OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows + OAuthGrantTypeClientCredentials = "client_credentials" + + // OAuthGrantTypeUserPass is the "grant_type" identifier used in username and password auth flows + OAuthGrantTypeUserPass = "password" + + // OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows + OAuthGrantTypeRefreshToken = "refresh_token" + + // OAuthGrantTypeAuthorizationCode is the "grant_type" identifier used in authorization code flows + OAuthGrantTypeAuthorizationCode = "authorization_code" + + // metadataHeader is the header required by MSI extension + metadataHeader = "Metadata" + + // msiEndpoint is the well known endpoint for getting MSI authentications tokens + msiEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" + + // the default number of attempts to refresh an MSI authentication token + defaultMaxMSIRefreshAttempts = 5 +) + +// OAuthTokenProvider is an interface which should be implemented by an access token retriever +type OAuthTokenProvider interface { + OAuthToken() string +} + +// MultitenantOAuthTokenProvider provides tokens used for multi-tenant authorization. +type MultitenantOAuthTokenProvider interface { + PrimaryOAuthToken() string + AuxiliaryOAuthTokens() []string +} + +// TokenRefreshError is an interface used by errors returned during token refresh. +type TokenRefreshError interface { + error + Response() *http.Response +} + +// Refresher is an interface for token refresh functionality +type Refresher interface { + Refresh() error + RefreshExchange(resource string) error + EnsureFresh() error +} + +// RefresherWithContext is an interface for token refresh functionality +type RefresherWithContext interface { + RefreshWithContext(ctx context.Context) error + RefreshExchangeWithContext(ctx context.Context, resource string) error + EnsureFreshWithContext(ctx context.Context) error +} + +// TokenRefreshCallback is the type representing callbacks that will be called after +// a successful token refresh +type TokenRefreshCallback func(Token) error + +// Token encapsulates the access token used to authorize Azure requests. +// https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#service-to-service-access-token-response +type Token struct { + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + + ExpiresIn json.Number `json:"expires_in"` + ExpiresOn json.Number `json:"expires_on"` + NotBefore json.Number `json:"not_before"` + + Resource string `json:"resource"` + Type string `json:"token_type"` +} + +func newToken() Token { + return Token{ + ExpiresIn: "0", + ExpiresOn: "0", + NotBefore: "0", + } +} + +// IsZero returns true if the token object is zero-initialized. +func (t Token) IsZero() bool { + return t == Token{} +} + +// Expires returns the time.Time when the Token expires. +func (t Token) Expires() time.Time { + s, err := t.ExpiresOn.Float64() + if err != nil { + s = -3600 + } + + expiration := date.NewUnixTimeFromSeconds(s) + + return time.Time(expiration).UTC() +} + +// IsExpired returns true if the Token is expired, false otherwise. +func (t Token) IsExpired() bool { + return t.WillExpireIn(0) +} + +// WillExpireIn returns true if the Token will expire after the passed time.Duration interval +// from now, false otherwise. +func (t Token) WillExpireIn(d time.Duration) bool { + return !t.Expires().After(time.Now().Add(d)) +} + +//OAuthToken return the current access token +func (t *Token) OAuthToken() string { + return t.AccessToken +} + +// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form +// that is submitted when acquiring an oAuth token. +type ServicePrincipalSecret interface { + SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error +} + +// ServicePrincipalNoSecret represents a secret type that contains no secret +// meaning it is not valid for fetching a fresh token. This is used by Manual +type ServicePrincipalNoSecret struct { +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret +// It only returns an error for the ServicePrincipalNoSecret type +func (noSecret *ServicePrincipalNoSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + return fmt.Errorf("Manually created ServicePrincipalToken does not contain secret material to retrieve a new access token") +} + +// MarshalJSON implements the json.Marshaler interface. +func (noSecret ServicePrincipalNoSecret) MarshalJSON() ([]byte, error) { + type tokenType struct { + Type string `json:"type"` + } + return json.Marshal(tokenType{ + Type: "ServicePrincipalNoSecret", + }) +} + +// ServicePrincipalTokenSecret implements ServicePrincipalSecret for client_secret type authorization. +type ServicePrincipalTokenSecret struct { + ClientSecret string `json:"value"` +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +// It will populate the form submitted during oAuth Token Acquisition using the client_secret. +func (tokenSecret *ServicePrincipalTokenSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + v.Set("client_secret", tokenSecret.ClientSecret) + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (tokenSecret ServicePrincipalTokenSecret) MarshalJSON() ([]byte, error) { + type tokenType struct { + Type string `json:"type"` + Value string `json:"value"` + } + return json.Marshal(tokenType{ + Type: "ServicePrincipalTokenSecret", + Value: tokenSecret.ClientSecret, + }) +} + +// ServicePrincipalCertificateSecret implements ServicePrincipalSecret for generic RSA cert auth with signed JWTs. +type ServicePrincipalCertificateSecret struct { + Certificate *x509.Certificate + PrivateKey *rsa.PrivateKey +} + +// SignJwt returns the JWT signed with the certificate's private key. +func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) { + hasher := sha1.New() + _, err := hasher.Write(secret.Certificate.Raw) + if err != nil { + return "", err + } + + thumbprint := base64.URLEncoding.EncodeToString(hasher.Sum(nil)) + + // The jti (JWT ID) claim provides a unique identifier for the JWT. + jti := make([]byte, 20) + _, err = rand.Read(jti) + if err != nil { + return "", err + } + + token := jwt.New(jwt.SigningMethodRS256) + token.Header["x5t"] = thumbprint + x5c := []string{base64.StdEncoding.EncodeToString(secret.Certificate.Raw)} + token.Header["x5c"] = x5c + token.Claims = jwt.MapClaims{ + "aud": spt.inner.OauthConfig.TokenEndpoint.String(), + "iss": spt.inner.ClientID, + "sub": spt.inner.ClientID, + "jti": base64.URLEncoding.EncodeToString(jti), + "nbf": time.Now().Unix(), + "exp": time.Now().Add(time.Hour * 24).Unix(), + } + + signedString, err := token.SignedString(secret.PrivateKey) + return signedString, err +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +// It will populate the form submitted during oAuth Token Acquisition using a JWT signed with a certificate. +func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + jwt, err := secret.SignJwt(spt) + if err != nil { + return err + } + + v.Set("client_assertion", jwt) + v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (secret ServicePrincipalCertificateSecret) MarshalJSON() ([]byte, error) { + return nil, errors.New("marshalling ServicePrincipalCertificateSecret is not supported") +} + +// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension. +type ServicePrincipalMSISecret struct { +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (msiSecret ServicePrincipalMSISecret) MarshalJSON() ([]byte, error) { + return nil, errors.New("marshalling ServicePrincipalMSISecret is not supported") +} + +// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth. +type ServicePrincipalUsernamePasswordSecret struct { + Username string `json:"username"` + Password string `json:"password"` +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + v.Set("username", secret.Username) + v.Set("password", secret.Password) + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (secret ServicePrincipalUsernamePasswordSecret) MarshalJSON() ([]byte, error) { + type tokenType struct { + Type string `json:"type"` + Username string `json:"username"` + Password string `json:"password"` + } + return json.Marshal(tokenType{ + Type: "ServicePrincipalUsernamePasswordSecret", + Username: secret.Username, + Password: secret.Password, + }) +} + +// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth. +type ServicePrincipalAuthorizationCodeSecret struct { + ClientSecret string `json:"value"` + AuthorizationCode string `json:"authCode"` + RedirectURI string `json:"redirect"` +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. +func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { + v.Set("code", secret.AuthorizationCode) + v.Set("client_secret", secret.ClientSecret) + v.Set("redirect_uri", secret.RedirectURI) + return nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (secret ServicePrincipalAuthorizationCodeSecret) MarshalJSON() ([]byte, error) { + type tokenType struct { + Type string `json:"type"` + Value string `json:"value"` + AuthCode string `json:"authCode"` + Redirect string `json:"redirect"` + } + return json.Marshal(tokenType{ + Type: "ServicePrincipalAuthorizationCodeSecret", + Value: secret.ClientSecret, + AuthCode: secret.AuthorizationCode, + Redirect: secret.RedirectURI, + }) +} + +// ServicePrincipalToken encapsulates a Token created for a Service Principal. +type ServicePrincipalToken struct { + inner servicePrincipalToken + refreshLock *sync.RWMutex + sender Sender + refreshCallbacks []TokenRefreshCallback + // MaxMSIRefreshAttempts is the maximum number of attempts to refresh an MSI token. + MaxMSIRefreshAttempts int +} + +// MarshalTokenJSON returns the marshalled inner token. +func (spt ServicePrincipalToken) MarshalTokenJSON() ([]byte, error) { + return json.Marshal(spt.inner.Token) +} + +// SetRefreshCallbacks replaces any existing refresh callbacks with the specified callbacks. +func (spt *ServicePrincipalToken) SetRefreshCallbacks(callbacks []TokenRefreshCallback) { + spt.refreshCallbacks = callbacks +} + +// MarshalJSON implements the json.Marshaler interface. +func (spt ServicePrincipalToken) MarshalJSON() ([]byte, error) { + return json.Marshal(spt.inner) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (spt *ServicePrincipalToken) UnmarshalJSON(data []byte) error { + // need to determine the token type + raw := map[string]interface{}{} + err := json.Unmarshal(data, &raw) + if err != nil { + return err + } + secret := raw["secret"].(map[string]interface{}) + switch secret["type"] { + case "ServicePrincipalNoSecret": + spt.inner.Secret = &ServicePrincipalNoSecret{} + case "ServicePrincipalTokenSecret": + spt.inner.Secret = &ServicePrincipalTokenSecret{} + case "ServicePrincipalCertificateSecret": + return errors.New("unmarshalling ServicePrincipalCertificateSecret is not supported") + case "ServicePrincipalMSISecret": + return errors.New("unmarshalling ServicePrincipalMSISecret is not supported") + case "ServicePrincipalUsernamePasswordSecret": + spt.inner.Secret = &ServicePrincipalUsernamePasswordSecret{} + case "ServicePrincipalAuthorizationCodeSecret": + spt.inner.Secret = &ServicePrincipalAuthorizationCodeSecret{} + default: + return fmt.Errorf("unrecognized token type '%s'", secret["type"]) + } + err = json.Unmarshal(data, &spt.inner) + if err != nil { + return err + } + // Don't override the refreshLock or the sender if those have been already set. + if spt.refreshLock == nil { + spt.refreshLock = &sync.RWMutex{} + } + if spt.sender == nil { + spt.sender = &http.Client{Transport: tracing.Transport} + } + return nil +} + +// internal type used for marshalling/unmarshalling +type servicePrincipalToken struct { + Token Token `json:"token"` + Secret ServicePrincipalSecret `json:"secret"` + OauthConfig OAuthConfig `json:"oauth"` + ClientID string `json:"clientID"` + Resource string `json:"resource"` + AutoRefresh bool `json:"autoRefresh"` + RefreshWithin time.Duration `json:"refreshWithin"` +} + +func validateOAuthConfig(oac OAuthConfig) error { + if oac.IsZero() { + return fmt.Errorf("parameter 'oauthConfig' cannot be zero-initialized") + } + return nil +} + +// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation. +func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(id, "id"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if secret == nil { + return nil, fmt.Errorf("parameter 'secret' cannot be nil") + } + spt := &ServicePrincipalToken{ + inner: servicePrincipalToken{ + Token: newToken(), + OauthConfig: oauthConfig, + Secret: secret, + ClientID: id, + Resource: resource, + AutoRefresh: true, + RefreshWithin: defaultRefresh, + }, + refreshLock: &sync.RWMutex{}, + sender: &http.Client{Transport: tracing.Transport}, + refreshCallbacks: callbacks, + } + return spt, nil +} + +// NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token +func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if token.IsZero() { + return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized") + } + spt, err := NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalNoSecret{}, + callbacks...) + if err != nil { + return nil, err + } + + spt.inner.Token = token + + return spt, nil +} + +// NewServicePrincipalTokenFromManualTokenSecret creates a ServicePrincipalToken using the supplied token and secret +func NewServicePrincipalTokenFromManualTokenSecret(oauthConfig OAuthConfig, clientID string, resource string, token Token, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if secret == nil { + return nil, fmt.Errorf("parameter 'secret' cannot be nil") + } + if token.IsZero() { + return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized") + } + spt, err := NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + secret, + callbacks...) + if err != nil { + return nil, err + } + + spt.inner.Token = token + + return spt, nil +} + +// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal +// credentials scoped to the named resource. +func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(secret, "secret"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + return NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalTokenSecret{ + ClientSecret: secret, + }, + callbacks..., + ) +} + +// NewServicePrincipalTokenFromCertificate creates a ServicePrincipalToken from the supplied pkcs12 bytes. +func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if certificate == nil { + return nil, fmt.Errorf("parameter 'certificate' cannot be nil") + } + if privateKey == nil { + return nil, fmt.Errorf("parameter 'privateKey' cannot be nil") + } + return NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalCertificateSecret{ + PrivateKey: privateKey, + Certificate: certificate, + }, + callbacks..., + ) +} + +// NewServicePrincipalTokenFromUsernamePassword creates a ServicePrincipalToken from the username and password. +func NewServicePrincipalTokenFromUsernamePassword(oauthConfig OAuthConfig, clientID string, username string, password string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(username, "username"); err != nil { + return nil, err + } + if err := validateStringParam(password, "password"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + return NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalUsernamePasswordSecret{ + Username: username, + Password: password, + }, + callbacks..., + ) +} + +// NewServicePrincipalTokenFromAuthorizationCode creates a ServicePrincipalToken from the +func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clientID string, clientSecret string, authorizationCode string, redirectURI string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + + if err := validateOAuthConfig(oauthConfig); err != nil { + return nil, err + } + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(clientSecret, "clientSecret"); err != nil { + return nil, err + } + if err := validateStringParam(authorizationCode, "authorizationCode"); err != nil { + return nil, err + } + if err := validateStringParam(redirectURI, "redirectURI"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + + return NewServicePrincipalTokenWithSecret( + oauthConfig, + clientID, + resource, + &ServicePrincipalAuthorizationCodeSecret{ + ClientSecret: clientSecret, + AuthorizationCode: authorizationCode, + RedirectURI: redirectURI, + }, + callbacks..., + ) +} + +// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines. +func GetMSIVMEndpoint() (string, error) { + return msiEndpoint, nil +} + +// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension. +// It will use the system assigned identity when creating the token. +func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, callbacks...) +} + +// NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension. +// It will use the specified user assigned identity when creating the token. +func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + return newServicePrincipalTokenFromMSI(msiEndpoint, resource, &userAssignedID, callbacks...) +} + +func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedID *string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + if err := validateStringParam(msiEndpoint, "msiEndpoint"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + if userAssignedID != nil { + if err := validateStringParam(*userAssignedID, "userAssignedID"); err != nil { + return nil, err + } + } + // We set the oauth config token endpoint to be MSI's endpoint + msiEndpointURL, err := url.Parse(msiEndpoint) + if err != nil { + return nil, err + } + + v := url.Values{} + v.Set("resource", resource) + v.Set("api-version", "2018-02-01") + if userAssignedID != nil { + v.Set("client_id", *userAssignedID) + } + msiEndpointURL.RawQuery = v.Encode() + + spt := &ServicePrincipalToken{ + inner: servicePrincipalToken{ + Token: newToken(), + OauthConfig: OAuthConfig{ + TokenEndpoint: *msiEndpointURL, + }, + Secret: &ServicePrincipalMSISecret{}, + Resource: resource, + AutoRefresh: true, + RefreshWithin: defaultRefresh, + }, + refreshLock: &sync.RWMutex{}, + sender: &http.Client{Transport: tracing.Transport}, + refreshCallbacks: callbacks, + MaxMSIRefreshAttempts: defaultMaxMSIRefreshAttempts, + } + + if userAssignedID != nil { + spt.inner.ClientID = *userAssignedID + } + + return spt, nil +} + +// internal type that implements TokenRefreshError +type tokenRefreshError struct { + message string + resp *http.Response +} + +// Error implements the error interface which is part of the TokenRefreshError interface. +func (tre tokenRefreshError) Error() string { + return tre.message +} + +// Response implements the TokenRefreshError interface, it returns the raw HTTP response from the refresh operation. +func (tre tokenRefreshError) Response() *http.Response { + return tre.resp +} + +func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError { + return tokenRefreshError{message: message, resp: resp} +} + +// EnsureFresh will refresh the token if it will expire within the refresh window (as set by +// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. +func (spt *ServicePrincipalToken) EnsureFresh() error { + return spt.EnsureFreshWithContext(context.Background()) +} + +// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by +// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. +func (spt *ServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { + if spt.inner.AutoRefresh && spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) { + // take the write lock then check to see if the token was already refreshed + spt.refreshLock.Lock() + defer spt.refreshLock.Unlock() + if spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) { + return spt.refreshInternal(ctx, spt.inner.Resource) + } + } + return nil +} + +// InvokeRefreshCallbacks calls any TokenRefreshCallbacks that were added to the SPT during initialization +func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { + if spt.refreshCallbacks != nil { + for _, callback := range spt.refreshCallbacks { + err := callback(spt.inner.Token) + if err != nil { + return fmt.Errorf("adal: TokenRefreshCallback handler failed. Error = '%v'", err) + } + } + } + return nil +} + +// Refresh obtains a fresh token for the Service Principal. +// This method is not safe for concurrent use and should be syncrhonized. +func (spt *ServicePrincipalToken) Refresh() error { + return spt.RefreshWithContext(context.Background()) +} + +// RefreshWithContext obtains a fresh token for the Service Principal. +// This method is not safe for concurrent use and should be syncrhonized. +func (spt *ServicePrincipalToken) RefreshWithContext(ctx context.Context) error { + spt.refreshLock.Lock() + defer spt.refreshLock.Unlock() + return spt.refreshInternal(ctx, spt.inner.Resource) +} + +// RefreshExchange refreshes the token, but for a different resource. +// This method is not safe for concurrent use and should be syncrhonized. +func (spt *ServicePrincipalToken) RefreshExchange(resource string) error { + return spt.RefreshExchangeWithContext(context.Background(), resource) +} + +// RefreshExchangeWithContext refreshes the token, but for a different resource. +// This method is not safe for concurrent use and should be syncrhonized. +func (spt *ServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error { + spt.refreshLock.Lock() + defer spt.refreshLock.Unlock() + return spt.refreshInternal(ctx, resource) +} + +func (spt *ServicePrincipalToken) getGrantType() string { + switch spt.inner.Secret.(type) { + case *ServicePrincipalUsernamePasswordSecret: + return OAuthGrantTypeUserPass + case *ServicePrincipalAuthorizationCodeSecret: + return OAuthGrantTypeAuthorizationCode + default: + return OAuthGrantTypeClientCredentials + } +} + +func isIMDS(u url.URL) bool { + imds, err := url.Parse(msiEndpoint) + if err != nil { + return false + } + return u.Host == imds.Host && u.Path == imds.Path +} + +func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error { + req, err := http.NewRequest(http.MethodPost, spt.inner.OauthConfig.TokenEndpoint.String(), nil) + if err != nil { + return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err) + } + req.Header.Add("User-Agent", UserAgent()) + req = req.WithContext(ctx) + if !isIMDS(spt.inner.OauthConfig.TokenEndpoint) { + v := url.Values{} + v.Set("client_id", spt.inner.ClientID) + v.Set("resource", resource) + + if spt.inner.Token.RefreshToken != "" { + v.Set("grant_type", OAuthGrantTypeRefreshToken) + v.Set("refresh_token", spt.inner.Token.RefreshToken) + // web apps must specify client_secret when refreshing tokens + // see https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code#refreshing-the-access-tokens + if spt.getGrantType() == OAuthGrantTypeAuthorizationCode { + err := spt.inner.Secret.SetAuthenticationValues(spt, &v) + if err != nil { + return err + } + } + } else { + v.Set("grant_type", spt.getGrantType()) + err := spt.inner.Secret.SetAuthenticationValues(spt, &v) + if err != nil { + return err + } + } + + s := v.Encode() + body := ioutil.NopCloser(strings.NewReader(s)) + req.ContentLength = int64(len(s)) + req.Header.Set(contentType, mimeTypeFormPost) + req.Body = body + } + + if _, ok := spt.inner.Secret.(*ServicePrincipalMSISecret); ok { + req.Method = http.MethodGet + req.Header.Set(metadataHeader, "true") + } + + var resp *http.Response + if isIMDS(spt.inner.OauthConfig.TokenEndpoint) { + resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts) + } else { + resp, err = spt.sender.Do(req) + } + if err != nil { + return newTokenRefreshError(fmt.Sprintf("adal: Failed to execute the refresh request. Error = '%v'", err), nil) + } + + defer resp.Body.Close() + rb, err := ioutil.ReadAll(resp.Body) + + if resp.StatusCode != http.StatusOK { + if err != nil { + return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body: %v", resp.StatusCode, err), resp) + } + return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb)), resp) + } + + // for the following error cases don't return a TokenRefreshError. the operation succeeded + // but some transient failure happened during deserialization. by returning a generic error + // the retry logic will kick in (we don't retry on TokenRefreshError). + + if err != nil { + return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err) + } + if len(strings.Trim(string(rb), " ")) == 0 { + return fmt.Errorf("adal: Empty service principal token received during refresh") + } + var token Token + err = json.Unmarshal(rb, &token) + if err != nil { + return fmt.Errorf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb)) + } + + spt.inner.Token = token + + return spt.InvokeRefreshCallbacks(token) +} + +// retry logic specific to retrieving a token from the IMDS endpoint +func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http.Response, err error) { + // copied from client.go due to circular dependency + retries := []int{ + http.StatusRequestTimeout, // 408 + http.StatusTooManyRequests, // 429 + http.StatusInternalServerError, // 500 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 + } + // extra retry status codes specific to IMDS + retries = append(retries, + http.StatusNotFound, + http.StatusGone, + // all remaining 5xx + http.StatusNotImplemented, + http.StatusHTTPVersionNotSupported, + http.StatusVariantAlsoNegotiates, + http.StatusInsufficientStorage, + http.StatusLoopDetected, + http.StatusNotExtended, + http.StatusNetworkAuthenticationRequired) + + // see https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/how-to-use-vm-token#retry-guidance + + const maxDelay time.Duration = 60 * time.Second + + attempt := 0 + delay := time.Duration(0) + + for attempt < maxAttempts { + resp, err = sender.Do(req) + // retry on temporary network errors, e.g. transient network failures. + // if we don't receive a response then assume we can't connect to the + // endpoint so we're likely not running on an Azure VM so don't retry. + if (err != nil && !isTemporaryNetworkError(err)) || resp == nil || resp.StatusCode == http.StatusOK || !containsInt(retries, resp.StatusCode) { + return + } + + // perform exponential backoff with a cap. + // must increment attempt before calculating delay. + attempt++ + // the base value of 2 is the "delta backoff" as specified in the guidance doc + delay += (time.Duration(math.Pow(2, float64(attempt))) * time.Second) + if delay > maxDelay { + delay = maxDelay + } + + select { + case <-time.After(delay): + // intentionally left blank + case <-req.Context().Done(): + err = req.Context().Err() + return + } + } + return +} + +// returns true if the specified error is a temporary network error or false if it's not. +// if the error doesn't implement the net.Error interface the return value is true. +func isTemporaryNetworkError(err error) bool { + if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) { + return true + } + return false +} + +// returns true if slice ints contains the value n +func containsInt(ints []int, n int) bool { + for _, i := range ints { + if i == n { + return true + } + } + return false +} + +// SetAutoRefresh enables or disables automatic refreshing of stale tokens. +func (spt *ServicePrincipalToken) SetAutoRefresh(autoRefresh bool) { + spt.inner.AutoRefresh = autoRefresh +} + +// SetRefreshWithin sets the interval within which if the token will expire, EnsureFresh will +// refresh the token. +func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) { + spt.inner.RefreshWithin = d + return +} + +// SetSender sets the http.Client used when obtaining the Service Principal token. An +// undecorated http.Client is used by default. +func (spt *ServicePrincipalToken) SetSender(s Sender) { spt.sender = s } + +// OAuthToken implements the OAuthTokenProvider interface. It returns the current access token. +func (spt *ServicePrincipalToken) OAuthToken() string { + spt.refreshLock.RLock() + defer spt.refreshLock.RUnlock() + return spt.inner.Token.OAuthToken() +} + +// Token returns a copy of the current token. +func (spt *ServicePrincipalToken) Token() Token { + spt.refreshLock.RLock() + defer spt.refreshLock.RUnlock() + return spt.inner.Token +} + +// MultiTenantServicePrincipalToken contains tokens for multi-tenant authorization. +type MultiTenantServicePrincipalToken struct { + PrimaryToken *ServicePrincipalToken + AuxiliaryTokens []*ServicePrincipalToken +} + +// PrimaryOAuthToken returns the primary authorization token. +func (mt *MultiTenantServicePrincipalToken) PrimaryOAuthToken() string { + return mt.PrimaryToken.OAuthToken() +} + +// AuxiliaryOAuthTokens returns one to three auxiliary authorization tokens. +func (mt *MultiTenantServicePrincipalToken) AuxiliaryOAuthTokens() []string { + tokens := make([]string, len(mt.AuxiliaryTokens)) + for i := range mt.AuxiliaryTokens { + tokens[i] = mt.AuxiliaryTokens[i].OAuthToken() + } + return tokens +} + +// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by +// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. +func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { + if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil { + return fmt.Errorf("failed to refresh primary token: %v", err) + } + for _, aux := range mt.AuxiliaryTokens { + if err := aux.EnsureFreshWithContext(ctx); err != nil { + return fmt.Errorf("failed to refresh auxiliary token: %v", err) + } + } + return nil +} + +// NewMultiTenantServicePrincipalToken creates a new MultiTenantServicePrincipalToken with the specified credentials and resource. +func NewMultiTenantServicePrincipalToken(multiTenantCfg MultiTenantOAuthConfig, clientID string, secret string, resource string) (*MultiTenantServicePrincipalToken, error) { + if err := validateStringParam(clientID, "clientID"); err != nil { + return nil, err + } + if err := validateStringParam(secret, "secret"); err != nil { + return nil, err + } + if err := validateStringParam(resource, "resource"); err != nil { + return nil, err + } + auxTenants := multiTenantCfg.AuxiliaryTenants() + m := MultiTenantServicePrincipalToken{ + AuxiliaryTokens: make([]*ServicePrincipalToken, len(auxTenants)), + } + primary, err := NewServicePrincipalToken(*multiTenantCfg.PrimaryTenant(), clientID, secret, resource) + if err != nil { + return nil, fmt.Errorf("failed to create SPT for primary tenant: %v", err) + } + m.PrimaryToken = primary + for i := range auxTenants { + aux, err := NewServicePrincipalToken(*auxTenants[i], clientID, secret, resource) + if err != nil { + return nil, fmt.Errorf("failed to create SPT for auxiliary tenant: %v", err) + } + m.AuxiliaryTokens[i] = aux + } + return &m, nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/version.go b/vendor/github.com/Azure/go-autorest/autorest/adal/version.go new file mode 100644 index 000000000..c867b3484 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/version.go @@ -0,0 +1,45 @@ +package adal + +import ( + "fmt" + "runtime" +) + +// Copyright 2017 Microsoft Corporation +// +// 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. + +const number = "v1.0.0" + +var ( + ua = fmt.Sprintf("Go/%s (%s-%s) go-autorest/adal/%s", + runtime.Version(), + runtime.GOARCH, + runtime.GOOS, + number, + ) +) + +// UserAgent returns a string containing the Go version, system architecture and OS, and the adal version. +func UserAgent() string { + return ua +} + +// AddToUserAgent adds an extension to the current user agent +func AddToUserAgent(extension string) error { + if extension != "" { + ua = fmt.Sprintf("%s %s", ua, extension) + return nil + } + return fmt.Errorf("Extension was empty, User Agent remained as '%s'", ua) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization.go b/vendor/github.com/Azure/go-autorest/autorest/authorization.go new file mode 100644 index 000000000..380865cd6 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/authorization.go @@ -0,0 +1,336 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "encoding/base64" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/tracing" +) + +const ( + bearerChallengeHeader = "Www-Authenticate" + bearer = "Bearer" + tenantID = "tenantID" + apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key" + bingAPISdkHeader = "X-BingApis-SDK-Client" + golangBingAPISdkHeaderValue = "Go-SDK" + authorization = "Authorization" + basic = "Basic" +) + +// Authorizer is the interface that provides a PrepareDecorator used to supply request +// authorization. Most often, the Authorizer decorator runs last so it has access to the full +// state of the formed HTTP request. +type Authorizer interface { + WithAuthorization() PrepareDecorator +} + +// NullAuthorizer implements a default, "do nothing" Authorizer. +type NullAuthorizer struct{} + +// WithAuthorization returns a PrepareDecorator that does nothing. +func (na NullAuthorizer) WithAuthorization() PrepareDecorator { + return WithNothing() +} + +// APIKeyAuthorizer implements API Key authorization. +type APIKeyAuthorizer struct { + headers map[string]interface{} + queryParameters map[string]interface{} +} + +// NewAPIKeyAuthorizerWithHeaders creates an ApiKeyAuthorizer with headers. +func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer { + return NewAPIKeyAuthorizer(headers, nil) +} + +// NewAPIKeyAuthorizerWithQueryParameters creates an ApiKeyAuthorizer with query parameters. +func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer { + return NewAPIKeyAuthorizer(nil, queryParameters) +} + +// NewAPIKeyAuthorizer creates an ApiKeyAuthorizer with headers. +func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer { + return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters} +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Parameters. +func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator { + return func(p Preparer) Preparer { + return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters)) + } +} + +// CognitiveServicesAuthorizer implements authorization for Cognitive Services. +type CognitiveServicesAuthorizer struct { + subscriptionKey string +} + +// NewCognitiveServicesAuthorizer is +func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer { + return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey} +} + +// WithAuthorization is +func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator { + headers := make(map[string]interface{}) + headers[apiKeyAuthorizerHeader] = csa.subscriptionKey + headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue + + return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() +} + +// BearerAuthorizer implements the bearer authorization +type BearerAuthorizer struct { + tokenProvider adal.OAuthTokenProvider +} + +// NewBearerAuthorizer crates a BearerAuthorizer using the given token provider +func NewBearerAuthorizer(tp adal.OAuthTokenProvider) *BearerAuthorizer { + return &BearerAuthorizer{tokenProvider: tp} +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose +// value is "Bearer " followed by the token. +// +// By default, the token will be automatically refreshed through the Refresher interface. +func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + // the ordering is important here, prefer RefresherWithContext if available + if refresher, ok := ba.tokenProvider.(adal.RefresherWithContext); ok { + err = refresher.EnsureFreshWithContext(r.Context()) + } else if refresher, ok := ba.tokenProvider.(adal.Refresher); ok { + err = refresher.EnsureFresh() + } + if err != nil { + var resp *http.Response + if tokError, ok := err.(adal.TokenRefreshError); ok { + resp = tokError.Response() + } + return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp, + "Failed to refresh the Token for request to %s", r.URL) + } + return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken()))) + } + return r, err + }) + } +} + +// BearerAuthorizerCallbackFunc is the authentication callback signature. +type BearerAuthorizerCallbackFunc func(tenantID, resource string) (*BearerAuthorizer, error) + +// BearerAuthorizerCallback implements bearer authorization via a callback. +type BearerAuthorizerCallback struct { + sender Sender + callback BearerAuthorizerCallbackFunc +} + +// NewBearerAuthorizerCallback creates a bearer authorization callback. The callback +// is invoked when the HTTP request is submitted. +func NewBearerAuthorizerCallback(sender Sender, callback BearerAuthorizerCallbackFunc) *BearerAuthorizerCallback { + if sender == nil { + sender = &http.Client{Transport: tracing.Transport} + } + return &BearerAuthorizerCallback{sender: sender, callback: callback} +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose value +// is "Bearer " followed by the token. The BearerAuthorizer is obtained via a user-supplied callback. +// +// By default, the token will be automatically refreshed through the Refresher interface. +func (bacb *BearerAuthorizerCallback) WithAuthorization() PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + // make a copy of the request and remove the body as it's not + // required and avoids us having to create a copy of it. + rCopy := *r + removeRequestBody(&rCopy) + + resp, err := bacb.sender.Do(&rCopy) + if err == nil && resp.StatusCode == 401 { + defer resp.Body.Close() + if hasBearerChallenge(resp) { + bc, err := newBearerChallenge(resp) + if err != nil { + return r, err + } + if bacb.callback != nil { + ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"]) + if err != nil { + return r, err + } + return Prepare(r, ba.WithAuthorization()) + } + } + } + } + return r, err + }) + } +} + +// returns true if the HTTP response contains a bearer challenge +func hasBearerChallenge(resp *http.Response) bool { + authHeader := resp.Header.Get(bearerChallengeHeader) + if len(authHeader) == 0 || strings.Index(authHeader, bearer) < 0 { + return false + } + return true +} + +type bearerChallenge struct { + values map[string]string +} + +func newBearerChallenge(resp *http.Response) (bc bearerChallenge, err error) { + challenge := strings.TrimSpace(resp.Header.Get(bearerChallengeHeader)) + trimmedChallenge := challenge[len(bearer)+1:] + + // challenge is a set of key=value pairs that are comma delimited + pairs := strings.Split(trimmedChallenge, ",") + if len(pairs) < 1 { + err = fmt.Errorf("challenge '%s' contains no pairs", challenge) + return bc, err + } + + bc.values = make(map[string]string) + for i := range pairs { + trimmedPair := strings.TrimSpace(pairs[i]) + pair := strings.Split(trimmedPair, "=") + if len(pair) == 2 { + // remove the enclosing quotes + key := strings.Trim(pair[0], "\"") + value := strings.Trim(pair[1], "\"") + + switch key { + case "authorization", "authorization_uri": + // strip the tenant ID from the authorization URL + asURL, err := url.Parse(value) + if err != nil { + return bc, err + } + bc.values[tenantID] = asURL.Path[1:] + default: + bc.values[key] = value + } + } + } + + return bc, err +} + +// EventGridKeyAuthorizer implements authorization for event grid using key authentication. +type EventGridKeyAuthorizer struct { + topicKey string +} + +// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer +// with the specified topic key. +func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer { + return EventGridKeyAuthorizer{topicKey: topicKey} +} + +// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header. +func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator { + headers := map[string]interface{}{ + "aeg-sas-key": egta.topicKey, + } + return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() +} + +// BasicAuthorizer implements basic HTTP authorization by adding the Authorization HTTP header +// with the value "Basic " where is a base64-encoded username:password tuple. +type BasicAuthorizer struct { + userName string + password string +} + +// NewBasicAuthorizer creates a new BasicAuthorizer with the specified username and password. +func NewBasicAuthorizer(userName, password string) *BasicAuthorizer { + return &BasicAuthorizer{ + userName: userName, + password: password, + } +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose +// value is "Basic " followed by the base64-encoded username:password tuple. +func (ba *BasicAuthorizer) WithAuthorization() PrepareDecorator { + headers := make(map[string]interface{}) + headers[authorization] = basic + " " + base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", ba.userName, ba.password))) + + return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() +} + +// MultiTenantServicePrincipalTokenAuthorizer provides authentication across tenants. +type MultiTenantServicePrincipalTokenAuthorizer interface { + WithAuthorization() PrepareDecorator +} + +// NewMultiTenantServicePrincipalTokenAuthorizer crates a BearerAuthorizer using the given token provider +func NewMultiTenantServicePrincipalTokenAuthorizer(tp adal.MultitenantOAuthTokenProvider) MultiTenantServicePrincipalTokenAuthorizer { + return &multiTenantSPTAuthorizer{tp: tp} +} + +type multiTenantSPTAuthorizer struct { + tp adal.MultitenantOAuthTokenProvider +} + +// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header using the +// primary token along with the auxiliary authorization header using the auxiliary tokens. +// +// By default, the token will be automatically refreshed through the Refresher interface. +func (mt multiTenantSPTAuthorizer) WithAuthorization() PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err != nil { + return r, err + } + if refresher, ok := mt.tp.(adal.RefresherWithContext); ok { + err = refresher.EnsureFreshWithContext(r.Context()) + if err != nil { + var resp *http.Response + if tokError, ok := err.(adal.TokenRefreshError); ok { + resp = tokError.Response() + } + return r, NewErrorWithError(err, "azure.multiTenantSPTAuthorizer", "WithAuthorization", resp, + "Failed to refresh one or more Tokens for request to %s", r.URL) + } + } + r, err = Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", mt.tp.PrimaryOAuthToken()))) + if err != nil { + return r, err + } + auxTokens := mt.tp.AuxiliaryOAuthTokens() + for i := range auxTokens { + auxTokens[i] = fmt.Sprintf("Bearer %s", auxTokens[i]) + } + return Prepare(r, WithHeader(headerAuxAuthorization, strings.Join(auxTokens, "; "))) + }) + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/autorest.go b/vendor/github.com/Azure/go-autorest/autorest/autorest.go new file mode 100644 index 000000000..aafdf021f --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/autorest.go @@ -0,0 +1,150 @@ +/* +Package autorest implements an HTTP request pipeline suitable for use across multiple go-routines +and provides the shared routines relied on by AutoRest (see https://github.com/Azure/autorest/) +generated Go code. + +The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending, +and Responding. A typical pattern is: + + req, err := Prepare(&http.Request{}, + token.WithAuthorization()) + + resp, err := Send(req, + WithLogging(logger), + DoErrorIfStatusCode(http.StatusInternalServerError), + DoCloseIfError(), + DoRetryForAttempts(5, time.Second)) + + err = Respond(resp, + ByDiscardingBody(), + ByClosing()) + +Each phase relies on decorators to modify and / or manage processing. Decorators may first modify +and then pass the data along, pass the data first and then modify the result, or wrap themselves +around passing the data (such as a logger might do). Decorators run in the order provided. For +example, the following: + + req, err := Prepare(&http.Request{}, + WithBaseURL("https://microsoft.com/"), + WithPath("a"), + WithPath("b"), + WithPath("c")) + +will set the URL to: + + https://microsoft.com/a/b/c + +Preparers and Responders may be shared and re-used (assuming the underlying decorators support +sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders +shared among multiple go-routines, and a single Sender shared among multiple sending go-routines, +all bound together by means of input / output channels. + +Decorators hold their passed state within a closure (such as the path components in the example +above). Be careful to share Preparers and Responders only in a context where such held state +applies. For example, it may not make sense to share a Preparer that applies a query string from a +fixed set of values. Similarly, sharing a Responder that reads the response body into a passed +struct (e.g., ByUnmarshallingJson) is likely incorrect. + +Lastly, the Swagger specification (https://swagger.io) that drives AutoRest +(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The +github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure +correct parsing and formatting. + +Errors raised by autorest objects and methods will conform to the autorest.Error interface. + +See the included examples for more detail. For details on the suggested use of this package by +generated clients, see the Client described below. +*/ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "context" + "net/http" + "time" +) + +const ( + // HeaderLocation specifies the HTTP Location header. + HeaderLocation = "Location" + + // HeaderRetryAfter specifies the HTTP Retry-After header. + HeaderRetryAfter = "Retry-After" +) + +// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set +// and false otherwise. +func ResponseHasStatusCode(resp *http.Response, codes ...int) bool { + if resp == nil { + return false + } + return containsInt(codes, resp.StatusCode) +} + +// GetLocation retrieves the URL from the Location header of the passed response. +func GetLocation(resp *http.Response) string { + return resp.Header.Get(HeaderLocation) +} + +// GetRetryAfter extracts the retry delay from the Retry-After header of the passed response. If +// the header is absent or is malformed, it will return the supplied default delay time.Duration. +func GetRetryAfter(resp *http.Response, defaultDelay time.Duration) time.Duration { + retry := resp.Header.Get(HeaderRetryAfter) + if retry == "" { + return defaultDelay + } + + d, err := time.ParseDuration(retry + "s") + if err != nil { + return defaultDelay + } + + return d +} + +// NewPollingRequest allocates and returns a new http.Request to poll for the passed response. +func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Request, error) { + location := GetLocation(resp) + if location == "" { + return nil, NewErrorWithResponse("autorest", "NewPollingRequest", resp, "Location header missing from response that requires polling") + } + + req, err := Prepare(&http.Request{Cancel: cancel}, + AsGet(), + WithBaseURL(location)) + if err != nil { + return nil, NewErrorWithError(err, "autorest", "NewPollingRequest", nil, "Failure creating poll request to %s", location) + } + + return req, nil +} + +// NewPollingRequestWithContext allocates and returns a new http.Request with the specified context to poll for the passed response. +func NewPollingRequestWithContext(ctx context.Context, resp *http.Response) (*http.Request, error) { + location := GetLocation(resp) + if location == "" { + return nil, NewErrorWithResponse("autorest", "NewPollingRequestWithContext", resp, "Location header missing from response that requires polling") + } + + req, err := Prepare((&http.Request{}).WithContext(ctx), + AsGet(), + WithBaseURL(location)) + if err != nil { + return nil, NewErrorWithError(err, "autorest", "NewPollingRequestWithContext", nil, "Failure creating poll request to %s", location) + } + + return req, nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go new file mode 100644 index 000000000..02d011961 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go @@ -0,0 +1,919 @@ +package azure + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + "time" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/tracing" +) + +const ( + headerAsyncOperation = "Azure-AsyncOperation" +) + +const ( + operationInProgress string = "InProgress" + operationCanceled string = "Canceled" + operationFailed string = "Failed" + operationSucceeded string = "Succeeded" +) + +var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.StatusCreated, http.StatusOK} + +// Future provides a mechanism to access the status and results of an asynchronous request. +// Since futures are stateful they should be passed by value to avoid race conditions. +type Future struct { + pt pollingTracker +} + +// NewFutureFromResponse returns a new Future object initialized +// with the initial response from an asynchronous operation. +func NewFutureFromResponse(resp *http.Response) (Future, error) { + pt, err := createPollingTracker(resp) + return Future{pt: pt}, err +} + +// Response returns the last HTTP response. +func (f Future) Response() *http.Response { + if f.pt == nil { + return nil + } + return f.pt.latestResponse() +} + +// Status returns the last status message of the operation. +func (f Future) Status() string { + if f.pt == nil { + return "" + } + return f.pt.pollingStatus() +} + +// PollingMethod returns the method used to monitor the status of the asynchronous operation. +func (f Future) PollingMethod() PollingMethodType { + if f.pt == nil { + return PollingUnknown + } + return f.pt.pollingMethod() +} + +// DoneWithContext queries the service to see if the operation has completed. +func (f *Future) DoneWithContext(ctx context.Context, sender autorest.Sender) (done bool, err error) { + ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.DoneWithContext") + defer func() { + sc := -1 + resp := f.Response() + if resp != nil { + sc = resp.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + + if f.pt == nil { + return false, autorest.NewError("Future", "Done", "future is not initialized") + } + if f.pt.hasTerminated() { + return true, f.pt.pollingError() + } + if err := f.pt.pollForStatus(ctx, sender); err != nil { + return false, err + } + if err := f.pt.checkForErrors(); err != nil { + return f.pt.hasTerminated(), err + } + if err := f.pt.updatePollingState(f.pt.provisioningStateApplicable()); err != nil { + return false, err + } + if err := f.pt.initPollingMethod(); err != nil { + return false, err + } + if err := f.pt.updatePollingMethod(); err != nil { + return false, err + } + return f.pt.hasTerminated(), f.pt.pollingError() +} + +// GetPollingDelay returns a duration the application should wait before checking +// the status of the asynchronous request and true; this value is returned from +// the service via the Retry-After response header. If the header wasn't returned +// then the function returns the zero-value time.Duration and false. +func (f Future) GetPollingDelay() (time.Duration, bool) { + if f.pt == nil { + return 0, false + } + resp := f.pt.latestResponse() + if resp == nil { + return 0, false + } + + retry := resp.Header.Get(autorest.HeaderRetryAfter) + if retry == "" { + return 0, false + } + + d, err := time.ParseDuration(retry + "s") + if err != nil { + panic(err) + } + + return d, true +} + +// WaitForCompletionRef will return when one of the following conditions is met: the long +// running operation has completed, the provided context is cancelled, or the client's +// polling duration has been exceeded. It will retry failed polling attempts based on +// the retry value defined in the client up to the maximum retry attempts. +// If no deadline is specified in the context then the client.PollingDuration will be +// used to determine if a default deadline should be used. +// If PollingDuration is greater than zero the value will be used as the context's timeout. +// If PollingDuration is zero then no default deadline will be used. +func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Client) (err error) { + ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.WaitForCompletionRef") + defer func() { + sc := -1 + resp := f.Response() + if resp != nil { + sc = resp.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + cancelCtx := ctx + // if the provided context already has a deadline don't override it + _, hasDeadline := ctx.Deadline() + if d := client.PollingDuration; !hasDeadline && d != 0 { + var cancel context.CancelFunc + cancelCtx, cancel = context.WithTimeout(ctx, d) + defer cancel() + } + + done, err := f.DoneWithContext(ctx, client) + for attempts := 0; !done; done, err = f.DoneWithContext(ctx, client) { + if attempts >= client.RetryAttempts { + return autorest.NewErrorWithError(err, "Future", "WaitForCompletion", f.pt.latestResponse(), "the number of retries has been exceeded") + } + // we want delayAttempt to be zero in the non-error case so + // that DelayForBackoff doesn't perform exponential back-off + var delayAttempt int + var delay time.Duration + if err == nil { + // check for Retry-After delay, if not present use the client's polling delay + var ok bool + delay, ok = f.GetPollingDelay() + if !ok { + delay = client.PollingDelay + } + } else { + // there was an error polling for status so perform exponential + // back-off based on the number of attempts using the client's retry + // duration. update attempts after delayAttempt to avoid off-by-one. + delayAttempt = attempts + delay = client.RetryDuration + attempts++ + } + // wait until the delay elapses or the context is cancelled + delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, cancelCtx.Done()) + if !delayElapsed { + return autorest.NewErrorWithError(cancelCtx.Err(), "Future", "WaitForCompletion", f.pt.latestResponse(), "context has been cancelled") + } + } + return +} + +// MarshalJSON implements the json.Marshaler interface. +func (f Future) MarshalJSON() ([]byte, error) { + return json.Marshal(f.pt) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (f *Future) UnmarshalJSON(data []byte) error { + // unmarshal into JSON object to determine the tracker type + obj := map[string]interface{}{} + err := json.Unmarshal(data, &obj) + if err != nil { + return err + } + if obj["method"] == nil { + return autorest.NewError("Future", "UnmarshalJSON", "missing 'method' property") + } + method := obj["method"].(string) + switch strings.ToUpper(method) { + case http.MethodDelete: + f.pt = &pollingTrackerDelete{} + case http.MethodPatch: + f.pt = &pollingTrackerPatch{} + case http.MethodPost: + f.pt = &pollingTrackerPost{} + case http.MethodPut: + f.pt = &pollingTrackerPut{} + default: + return autorest.NewError("Future", "UnmarshalJSON", "unsupoorted method '%s'", method) + } + // now unmarshal into the tracker + return json.Unmarshal(data, &f.pt) +} + +// PollingURL returns the URL used for retrieving the status of the long-running operation. +func (f Future) PollingURL() string { + if f.pt == nil { + return "" + } + return f.pt.pollingURL() +} + +// GetResult should be called once polling has completed successfully. +// It makes the final GET call to retrieve the resultant payload. +func (f Future) GetResult(sender autorest.Sender) (*http.Response, error) { + if f.pt.finalGetURL() == "" { + // we can end up in this situation if the async operation returns a 200 + // with no polling URLs. in that case return the response which should + // contain the JSON payload (only do this for successful terminal cases). + if lr := f.pt.latestResponse(); lr != nil && f.pt.hasSucceeded() { + return lr, nil + } + return nil, autorest.NewError("Future", "GetResult", "missing URL for retrieving result") + } + req, err := http.NewRequest(http.MethodGet, f.pt.finalGetURL(), nil) + if err != nil { + return nil, err + } + return sender.Do(req) +} + +type pollingTracker interface { + // these methods can differ per tracker + + // checks the response headers and status code to determine the polling mechanism + updatePollingMethod() error + + // checks the response for tracker-specific error conditions + checkForErrors() error + + // returns true if provisioning state should be checked + provisioningStateApplicable() bool + + // methods common to all trackers + + // initializes a tracker's polling URL and method, called for each iteration. + // these values can be overridden by each polling tracker as required. + initPollingMethod() error + + // initializes the tracker's internal state, call this when the tracker is created + initializeState() error + + // makes an HTTP request to check the status of the LRO + pollForStatus(ctx context.Context, sender autorest.Sender) error + + // updates internal tracker state, call this after each call to pollForStatus + updatePollingState(provStateApl bool) error + + // returns the error response from the service, can be nil + pollingError() error + + // returns the polling method being used + pollingMethod() PollingMethodType + + // returns the state of the LRO as returned from the service + pollingStatus() string + + // returns the URL used for polling status + pollingURL() string + + // returns the URL used for the final GET to retrieve the resource + finalGetURL() string + + // returns true if the LRO is in a terminal state + hasTerminated() bool + + // returns true if the LRO is in a failed terminal state + hasFailed() bool + + // returns true if the LRO is in a successful terminal state + hasSucceeded() bool + + // returns the cached HTTP response after a call to pollForStatus(), can be nil + latestResponse() *http.Response +} + +type pollingTrackerBase struct { + // resp is the last response, either from the submission of the LRO or from polling + resp *http.Response + + // method is the HTTP verb, this is needed for deserialization + Method string `json:"method"` + + // rawBody is the raw JSON response body + rawBody map[string]interface{} + + // denotes if polling is using async-operation or location header + Pm PollingMethodType `json:"pollingMethod"` + + // the URL to poll for status + URI string `json:"pollingURI"` + + // the state of the LRO as returned from the service + State string `json:"lroState"` + + // the URL to GET for the final result + FinalGetURI string `json:"resultURI"` + + // used to hold an error object returned from the service + Err *ServiceError `json:"error,omitempty"` +} + +func (pt *pollingTrackerBase) initializeState() error { + // determine the initial polling state based on response body and/or HTTP status + // code. this is applicable to the initial LRO response, not polling responses! + pt.Method = pt.resp.Request.Method + if err := pt.updateRawBody(); err != nil { + return err + } + switch pt.resp.StatusCode { + case http.StatusOK: + if ps := pt.getProvisioningState(); ps != nil { + pt.State = *ps + if pt.hasFailed() { + pt.updateErrorFromResponse() + return pt.pollingError() + } + } else { + pt.State = operationSucceeded + } + case http.StatusCreated: + if ps := pt.getProvisioningState(); ps != nil { + pt.State = *ps + } else { + pt.State = operationInProgress + } + case http.StatusAccepted: + pt.State = operationInProgress + case http.StatusNoContent: + pt.State = operationSucceeded + default: + pt.State = operationFailed + pt.updateErrorFromResponse() + return pt.pollingError() + } + return pt.initPollingMethod() +} + +func (pt pollingTrackerBase) getProvisioningState() *string { + if pt.rawBody != nil && pt.rawBody["properties"] != nil { + p := pt.rawBody["properties"].(map[string]interface{}) + if ps := p["provisioningState"]; ps != nil { + s := ps.(string) + return &s + } + } + return nil +} + +func (pt *pollingTrackerBase) updateRawBody() error { + pt.rawBody = map[string]interface{}{} + if pt.resp.ContentLength != 0 { + defer pt.resp.Body.Close() + b, err := ioutil.ReadAll(pt.resp.Body) + if err != nil { + return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to read response body") + } + // observed in 204 responses over HTTP/2.0; the content length is -1 but body is empty + if len(b) == 0 { + return nil + } + // put the body back so it's available to other callers + pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b)) + if err = json.Unmarshal(b, &pt.rawBody); err != nil { + return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to unmarshal response body") + } + } + return nil +} + +func (pt *pollingTrackerBase) pollForStatus(ctx context.Context, sender autorest.Sender) error { + req, err := http.NewRequest(http.MethodGet, pt.URI, nil) + if err != nil { + return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to create HTTP request") + } + + req = req.WithContext(ctx) + pt.resp, err = sender.Do(req) + if err != nil { + return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to send HTTP request") + } + if autorest.ResponseHasStatusCode(pt.resp, pollingCodes[:]...) { + // reset the service error on success case + pt.Err = nil + err = pt.updateRawBody() + } else { + // check response body for error content + pt.updateErrorFromResponse() + err = pt.pollingError() + } + return err +} + +// attempts to unmarshal a ServiceError type from the response body. +// if that fails then make a best attempt at creating something meaningful. +// NOTE: this assumes that the async operation has failed. +func (pt *pollingTrackerBase) updateErrorFromResponse() { + var err error + if pt.resp.ContentLength != 0 { + type respErr struct { + ServiceError *ServiceError `json:"error"` + } + re := respErr{} + defer pt.resp.Body.Close() + var b []byte + if b, err = ioutil.ReadAll(pt.resp.Body); err != nil || len(b) == 0 { + goto Default + } + if err = json.Unmarshal(b, &re); err != nil { + goto Default + } + // unmarshalling the error didn't yield anything, try unwrapped error + if re.ServiceError == nil { + err = json.Unmarshal(b, &re.ServiceError) + if err != nil { + goto Default + } + } + // the unmarshaller will ensure re.ServiceError is non-nil + // even if there was no content unmarshalled so check the code. + if re.ServiceError.Code != "" { + pt.Err = re.ServiceError + return + } + } +Default: + se := &ServiceError{ + Code: pt.pollingStatus(), + Message: "The async operation failed.", + } + if err != nil { + se.InnerError = make(map[string]interface{}) + se.InnerError["unmarshalError"] = err.Error() + } + // stick the response body into the error object in hopes + // it contains something useful to help diagnose the failure. + if len(pt.rawBody) > 0 { + se.AdditionalInfo = []map[string]interface{}{ + pt.rawBody, + } + } + pt.Err = se +} + +func (pt *pollingTrackerBase) updatePollingState(provStateApl bool) error { + if pt.Pm == PollingAsyncOperation && pt.rawBody["status"] != nil { + pt.State = pt.rawBody["status"].(string) + } else { + if pt.resp.StatusCode == http.StatusAccepted { + pt.State = operationInProgress + } else if provStateApl { + if ps := pt.getProvisioningState(); ps != nil { + pt.State = *ps + } else { + pt.State = operationSucceeded + } + } else { + return autorest.NewError("pollingTrackerBase", "updatePollingState", "the response from the async operation has an invalid status code") + } + } + // if the operation has failed update the error state + if pt.hasFailed() { + pt.updateErrorFromResponse() + } + return nil +} + +func (pt pollingTrackerBase) pollingError() error { + if pt.Err == nil { + return nil + } + return pt.Err +} + +func (pt pollingTrackerBase) pollingMethod() PollingMethodType { + return pt.Pm +} + +func (pt pollingTrackerBase) pollingStatus() string { + return pt.State +} + +func (pt pollingTrackerBase) pollingURL() string { + return pt.URI +} + +func (pt pollingTrackerBase) finalGetURL() string { + return pt.FinalGetURI +} + +func (pt pollingTrackerBase) hasTerminated() bool { + return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) || strings.EqualFold(pt.State, operationSucceeded) +} + +func (pt pollingTrackerBase) hasFailed() bool { + return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) +} + +func (pt pollingTrackerBase) hasSucceeded() bool { + return strings.EqualFold(pt.State, operationSucceeded) +} + +func (pt pollingTrackerBase) latestResponse() *http.Response { + return pt.resp +} + +// error checking common to all trackers +func (pt pollingTrackerBase) baseCheckForErrors() error { + // for Azure-AsyncOperations the response body cannot be nil or empty + if pt.Pm == PollingAsyncOperation { + if pt.resp.Body == nil || pt.resp.ContentLength == 0 { + return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "for Azure-AsyncOperation response body cannot be nil") + } + if pt.rawBody["status"] == nil { + return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "missing status property in Azure-AsyncOperation response body") + } + } + return nil +} + +// default initialization of polling URL/method. each verb tracker will update this as required. +func (pt *pollingTrackerBase) initPollingMethod() error { + if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + return nil + } + if lh, err := getURLFromLocationHeader(pt.resp); err != nil { + return err + } else if lh != "" { + pt.URI = lh + pt.Pm = PollingLocation + return nil + } + // it's ok if we didn't find a polling header, this will be handled elsewhere + return nil +} + +// DELETE + +type pollingTrackerDelete struct { + pollingTrackerBase +} + +func (pt *pollingTrackerDelete) updatePollingMethod() error { + // for 201 the Location header is required + if pt.resp.StatusCode == http.StatusCreated { + if lh, err := getURLFromLocationHeader(pt.resp); err != nil { + return err + } else if lh == "" { + return autorest.NewError("pollingTrackerDelete", "updateHeaders", "missing Location header in 201 response") + } else { + pt.URI = lh + } + pt.Pm = PollingLocation + pt.FinalGetURI = pt.URI + } + // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary + if pt.resp.StatusCode == http.StatusAccepted { + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + // if the Location header is invalid and we already have a polling URL + // then we don't care if the Location header URL is malformed. + if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { + return err + } else if lh != "" { + if ao == "" { + pt.URI = lh + pt.Pm = PollingLocation + } + // when both headers are returned we use the value in the Location header for the final GET + pt.FinalGetURI = lh + } + // make sure a polling URL was found + if pt.URI == "" { + return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response") + } + } + return nil +} + +func (pt pollingTrackerDelete) checkForErrors() error { + return pt.baseCheckForErrors() +} + +func (pt pollingTrackerDelete) provisioningStateApplicable() bool { + return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent +} + +// PATCH + +type pollingTrackerPatch struct { + pollingTrackerBase +} + +func (pt *pollingTrackerPatch) updatePollingMethod() error { + // by default we can use the original URL for polling and final GET + if pt.URI == "" { + pt.URI = pt.resp.Request.URL.String() + } + if pt.FinalGetURI == "" { + pt.FinalGetURI = pt.resp.Request.URL.String() + } + if pt.Pm == PollingUnknown { + pt.Pm = PollingRequestURI + } + // for 201 it's permissible for no headers to be returned + if pt.resp.StatusCode == http.StatusCreated { + if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + } + // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary + // note the absence of the "final GET" mechanism for PATCH + if pt.resp.StatusCode == http.StatusAccepted { + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + if ao == "" { + if lh, err := getURLFromLocationHeader(pt.resp); err != nil { + return err + } else if lh == "" { + return autorest.NewError("pollingTrackerPatch", "updateHeaders", "didn't get any suitable polling URLs in 202 response") + } else { + pt.URI = lh + pt.Pm = PollingLocation + } + } + } + return nil +} + +func (pt pollingTrackerPatch) checkForErrors() error { + return pt.baseCheckForErrors() +} + +func (pt pollingTrackerPatch) provisioningStateApplicable() bool { + return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated +} + +// POST + +type pollingTrackerPost struct { + pollingTrackerBase +} + +func (pt *pollingTrackerPost) updatePollingMethod() error { + // 201 requires Location header + if pt.resp.StatusCode == http.StatusCreated { + if lh, err := getURLFromLocationHeader(pt.resp); err != nil { + return err + } else if lh == "" { + return autorest.NewError("pollingTrackerPost", "updateHeaders", "missing Location header in 201 response") + } else { + pt.URI = lh + pt.FinalGetURI = lh + pt.Pm = PollingLocation + } + } + // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary + if pt.resp.StatusCode == http.StatusAccepted { + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + // if the Location header is invalid and we already have a polling URL + // then we don't care if the Location header URL is malformed. + if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { + return err + } else if lh != "" { + if ao == "" { + pt.URI = lh + pt.Pm = PollingLocation + } + // when both headers are returned we use the value in the Location header for the final GET + pt.FinalGetURI = lh + } + // make sure a polling URL was found + if pt.URI == "" { + return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response") + } + } + return nil +} + +func (pt pollingTrackerPost) checkForErrors() error { + return pt.baseCheckForErrors() +} + +func (pt pollingTrackerPost) provisioningStateApplicable() bool { + return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent +} + +// PUT + +type pollingTrackerPut struct { + pollingTrackerBase +} + +func (pt *pollingTrackerPut) updatePollingMethod() error { + // by default we can use the original URL for polling and final GET + if pt.URI == "" { + pt.URI = pt.resp.Request.URL.String() + } + if pt.FinalGetURI == "" { + pt.FinalGetURI = pt.resp.Request.URL.String() + } + if pt.Pm == PollingUnknown { + pt.Pm = PollingRequestURI + } + // for 201 it's permissible for no headers to be returned + if pt.resp.StatusCode == http.StatusCreated { + if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + } + // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary + if pt.resp.StatusCode == http.StatusAccepted { + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } else if ao != "" { + pt.URI = ao + pt.Pm = PollingAsyncOperation + } + // if the Location header is invalid and we already have a polling URL + // then we don't care if the Location header URL is malformed. + if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { + return err + } else if lh != "" { + if ao == "" { + pt.URI = lh + pt.Pm = PollingLocation + } + } + // make sure a polling URL was found + if pt.URI == "" { + return autorest.NewError("pollingTrackerPut", "updateHeaders", "didn't get any suitable polling URLs in 202 response") + } + } + return nil +} + +func (pt pollingTrackerPut) checkForErrors() error { + err := pt.baseCheckForErrors() + if err != nil { + return err + } + // if there are no LRO headers then the body cannot be empty + ao, err := getURLFromAsyncOpHeader(pt.resp) + if err != nil { + return err + } + lh, err := getURLFromLocationHeader(pt.resp) + if err != nil { + return err + } + if ao == "" && lh == "" && len(pt.rawBody) == 0 { + return autorest.NewError("pollingTrackerPut", "checkForErrors", "the response did not contain a body") + } + return nil +} + +func (pt pollingTrackerPut) provisioningStateApplicable() bool { + return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated +} + +// creates a polling tracker based on the verb of the original request +func createPollingTracker(resp *http.Response) (pollingTracker, error) { + var pt pollingTracker + switch strings.ToUpper(resp.Request.Method) { + case http.MethodDelete: + pt = &pollingTrackerDelete{pollingTrackerBase: pollingTrackerBase{resp: resp}} + case http.MethodPatch: + pt = &pollingTrackerPatch{pollingTrackerBase: pollingTrackerBase{resp: resp}} + case http.MethodPost: + pt = &pollingTrackerPost{pollingTrackerBase: pollingTrackerBase{resp: resp}} + case http.MethodPut: + pt = &pollingTrackerPut{pollingTrackerBase: pollingTrackerBase{resp: resp}} + default: + return nil, autorest.NewError("azure", "createPollingTracker", "unsupported HTTP method %s", resp.Request.Method) + } + if err := pt.initializeState(); err != nil { + return pt, err + } + // this initializes the polling header values, we do this during creation in case the + // initial response send us invalid values; this way the API call will return a non-nil + // error (not doing this means the error shows up in Future.Done) + return pt, pt.updatePollingMethod() +} + +// gets the polling URL from the Azure-AsyncOperation header. +// ensures the URL is well-formed and absolute. +func getURLFromAsyncOpHeader(resp *http.Response) (string, error) { + s := resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation)) + if s == "" { + return "", nil + } + if !isValidURL(s) { + return "", autorest.NewError("azure", "getURLFromAsyncOpHeader", "invalid polling URL '%s'", s) + } + return s, nil +} + +// gets the polling URL from the Location header. +// ensures the URL is well-formed and absolute. +func getURLFromLocationHeader(resp *http.Response) (string, error) { + s := resp.Header.Get(http.CanonicalHeaderKey(autorest.HeaderLocation)) + if s == "" { + return "", nil + } + if !isValidURL(s) { + return "", autorest.NewError("azure", "getURLFromLocationHeader", "invalid polling URL '%s'", s) + } + return s, nil +} + +// verify that the URL is valid and absolute +func isValidURL(s string) bool { + u, err := url.Parse(s) + return err == nil && u.IsAbs() +} + +// PollingMethodType defines a type used for enumerating polling mechanisms. +type PollingMethodType string + +const ( + // PollingAsyncOperation indicates the polling method uses the Azure-AsyncOperation header. + PollingAsyncOperation PollingMethodType = "AsyncOperation" + + // PollingLocation indicates the polling method uses the Location header. + PollingLocation PollingMethodType = "Location" + + // PollingRequestURI indicates the polling method uses the original request URI. + PollingRequestURI PollingMethodType = "RequestURI" + + // PollingUnknown indicates an unknown polling method and is the default value. + PollingUnknown PollingMethodType = "" +) + +// AsyncOpIncompleteError is the type that's returned from a future that has not completed. +type AsyncOpIncompleteError struct { + // FutureType is the name of the type composed of a azure.Future. + FutureType string +} + +// Error returns an error message including the originating type name of the error. +func (e AsyncOpIncompleteError) Error() string { + return fmt.Sprintf("%s: asynchronous operation has not completed", e.FutureType) +} + +// NewAsyncOpIncompleteError creates a new AsyncOpIncompleteError with the specified parameters. +func NewAsyncOpIncompleteError(futureType string) AsyncOpIncompleteError { + return AsyncOpIncompleteError{ + FutureType: futureType, + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/auth.go b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/auth.go new file mode 100644 index 000000000..20855d4ab --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/auth.go @@ -0,0 +1,712 @@ +package auth + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "crypto/rsa" + "crypto/x509" + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "log" + "os" + "strings" + "unicode/utf16" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/azure/cli" + "github.com/dimchansky/utfbom" + "golang.org/x/crypto/pkcs12" +) + +// The possible keys in the Values map. +const ( + SubscriptionID = "AZURE_SUBSCRIPTION_ID" + TenantID = "AZURE_TENANT_ID" + ClientID = "AZURE_CLIENT_ID" + ClientSecret = "AZURE_CLIENT_SECRET" + CertificatePath = "AZURE_CERTIFICATE_PATH" + CertificatePassword = "AZURE_CERTIFICATE_PASSWORD" + Username = "AZURE_USERNAME" + Password = "AZURE_PASSWORD" + EnvironmentName = "AZURE_ENVIRONMENT" + Resource = "AZURE_AD_RESOURCE" + ActiveDirectoryEndpoint = "ActiveDirectoryEndpoint" + ResourceManagerEndpoint = "ResourceManagerEndpoint" + GraphResourceID = "GraphResourceID" + SQLManagementEndpoint = "SQLManagementEndpoint" + GalleryEndpoint = "GalleryEndpoint" + ManagementEndpoint = "ManagementEndpoint" +) + +// NewAuthorizerFromEnvironment creates an Authorizer configured from environment variables in the order: +// 1. Client credentials +// 2. Client certificate +// 3. Username password +// 4. MSI +func NewAuthorizerFromEnvironment() (autorest.Authorizer, error) { + settings, err := GetSettingsFromEnvironment() + if err != nil { + return nil, err + } + return settings.GetAuthorizer() +} + +// NewAuthorizerFromEnvironmentWithResource creates an Authorizer configured from environment variables in the order: +// 1. Client credentials +// 2. Client certificate +// 3. Username password +// 4. MSI +func NewAuthorizerFromEnvironmentWithResource(resource string) (autorest.Authorizer, error) { + settings, err := GetSettingsFromEnvironment() + if err != nil { + return nil, err + } + settings.Values[Resource] = resource + return settings.GetAuthorizer() +} + +// EnvironmentSettings contains the available authentication settings. +type EnvironmentSettings struct { + Values map[string]string + Environment azure.Environment +} + +// GetSettingsFromEnvironment returns the available authentication settings from the environment. +func GetSettingsFromEnvironment() (s EnvironmentSettings, err error) { + s = EnvironmentSettings{ + Values: map[string]string{}, + } + s.setValue(SubscriptionID) + s.setValue(TenantID) + s.setValue(ClientID) + s.setValue(ClientSecret) + s.setValue(CertificatePath) + s.setValue(CertificatePassword) + s.setValue(Username) + s.setValue(Password) + s.setValue(EnvironmentName) + s.setValue(Resource) + if v := s.Values[EnvironmentName]; v == "" { + s.Environment = azure.PublicCloud + } else { + s.Environment, err = azure.EnvironmentFromName(v) + } + if s.Values[Resource] == "" { + s.Values[Resource] = s.Environment.ResourceManagerEndpoint + } + return +} + +// GetSubscriptionID returns the available subscription ID or an empty string. +func (settings EnvironmentSettings) GetSubscriptionID() string { + return settings.Values[SubscriptionID] +} + +// adds the specified environment variable value to the Values map if it exists +func (settings EnvironmentSettings) setValue(key string) { + if v := os.Getenv(key); v != "" { + settings.Values[key] = v + } +} + +// helper to return client and tenant IDs +func (settings EnvironmentSettings) getClientAndTenant() (string, string) { + clientID := settings.Values[ClientID] + tenantID := settings.Values[TenantID] + return clientID, tenantID +} + +// GetClientCredentials creates a config object from the available client credentials. +// An error is returned if no client credentials are available. +func (settings EnvironmentSettings) GetClientCredentials() (ClientCredentialsConfig, error) { + secret := settings.Values[ClientSecret] + if secret == "" { + return ClientCredentialsConfig{}, errors.New("missing client secret") + } + clientID, tenantID := settings.getClientAndTenant() + config := NewClientCredentialsConfig(clientID, secret, tenantID) + config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint + config.Resource = settings.Values[Resource] + return config, nil +} + +// GetClientCertificate creates a config object from the available certificate credentials. +// An error is returned if no certificate credentials are available. +func (settings EnvironmentSettings) GetClientCertificate() (ClientCertificateConfig, error) { + certPath := settings.Values[CertificatePath] + if certPath == "" { + return ClientCertificateConfig{}, errors.New("missing certificate path") + } + certPwd := settings.Values[CertificatePassword] + clientID, tenantID := settings.getClientAndTenant() + config := NewClientCertificateConfig(certPath, certPwd, clientID, tenantID) + config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint + config.Resource = settings.Values[Resource] + return config, nil +} + +// GetUsernamePassword creates a config object from the available username/password credentials. +// An error is returned if no username/password credentials are available. +func (settings EnvironmentSettings) GetUsernamePassword() (UsernamePasswordConfig, error) { + username := settings.Values[Username] + password := settings.Values[Password] + if username == "" || password == "" { + return UsernamePasswordConfig{}, errors.New("missing username/password") + } + clientID, tenantID := settings.getClientAndTenant() + config := NewUsernamePasswordConfig(username, password, clientID, tenantID) + config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint + config.Resource = settings.Values[Resource] + return config, nil +} + +// GetMSI creates a MSI config object from the available client ID. +func (settings EnvironmentSettings) GetMSI() MSIConfig { + config := NewMSIConfig() + config.Resource = settings.Values[Resource] + config.ClientID = settings.Values[ClientID] + return config +} + +// GetDeviceFlow creates a device-flow config object from the available client and tenant IDs. +func (settings EnvironmentSettings) GetDeviceFlow() DeviceFlowConfig { + clientID, tenantID := settings.getClientAndTenant() + config := NewDeviceFlowConfig(clientID, tenantID) + config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint + config.Resource = settings.Values[Resource] + return config +} + +// GetAuthorizer creates an Authorizer configured from environment variables in the order: +// 1. Client credentials +// 2. Client certificate +// 3. Username password +// 4. MSI +func (settings EnvironmentSettings) GetAuthorizer() (autorest.Authorizer, error) { + //1.Client Credentials + if c, e := settings.GetClientCredentials(); e == nil { + return c.Authorizer() + } + + //2. Client Certificate + if c, e := settings.GetClientCertificate(); e == nil { + return c.Authorizer() + } + + //3. Username Password + if c, e := settings.GetUsernamePassword(); e == nil { + return c.Authorizer() + } + + // 4. MSI + return settings.GetMSI().Authorizer() +} + +// NewAuthorizerFromFile creates an Authorizer configured from a configuration file in the following order. +// 1. Client credentials +// 2. Client certificate +func NewAuthorizerFromFile(baseURI string) (autorest.Authorizer, error) { + settings, err := GetSettingsFromFile() + if err != nil { + return nil, err + } + if a, err := settings.ClientCredentialsAuthorizer(baseURI); err == nil { + return a, err + } + if a, err := settings.ClientCertificateAuthorizer(baseURI); err == nil { + return a, err + } + return nil, errors.New("auth file missing client and certificate credentials") +} + +// NewAuthorizerFromFileWithResource creates an Authorizer configured from a configuration file in the following order. +// 1. Client credentials +// 2. Client certificate +func NewAuthorizerFromFileWithResource(resource string) (autorest.Authorizer, error) { + s, err := GetSettingsFromFile() + if err != nil { + return nil, err + } + if a, err := s.ClientCredentialsAuthorizerWithResource(resource); err == nil { + return a, err + } + if a, err := s.ClientCertificateAuthorizerWithResource(resource); err == nil { + return a, err + } + return nil, errors.New("auth file missing client and certificate credentials") +} + +// NewAuthorizerFromCLI creates an Authorizer configured from Azure CLI 2.0 for local development scenarios. +func NewAuthorizerFromCLI() (autorest.Authorizer, error) { + settings, err := GetSettingsFromEnvironment() + if err != nil { + return nil, err + } + + if settings.Values[Resource] == "" { + settings.Values[Resource] = settings.Environment.ResourceManagerEndpoint + } + + return NewAuthorizerFromCLIWithResource(settings.Values[Resource]) +} + +// NewAuthorizerFromCLIWithResource creates an Authorizer configured from Azure CLI 2.0 for local development scenarios. +func NewAuthorizerFromCLIWithResource(resource string) (autorest.Authorizer, error) { + token, err := cli.GetTokenFromCLI(resource) + if err != nil { + return nil, err + } + + adalToken, err := token.ToADALToken() + if err != nil { + return nil, err + } + + return autorest.NewBearerAuthorizer(&adalToken), nil +} + +// GetSettingsFromFile returns the available authentication settings from an Azure CLI authentication file. +func GetSettingsFromFile() (FileSettings, error) { + s := FileSettings{} + fileLocation := os.Getenv("AZURE_AUTH_LOCATION") + if fileLocation == "" { + return s, errors.New("environment variable AZURE_AUTH_LOCATION is not set") + } + + contents, err := ioutil.ReadFile(fileLocation) + if err != nil { + return s, err + } + + // Auth file might be encoded + decoded, err := decode(contents) + if err != nil { + return s, err + } + + authFile := map[string]interface{}{} + err = json.Unmarshal(decoded, &authFile) + if err != nil { + return s, err + } + + s.Values = map[string]string{} + s.setKeyValue(ClientID, authFile["clientId"]) + s.setKeyValue(ClientSecret, authFile["clientSecret"]) + s.setKeyValue(CertificatePath, authFile["clientCertificate"]) + s.setKeyValue(CertificatePassword, authFile["clientCertificatePassword"]) + s.setKeyValue(SubscriptionID, authFile["subscriptionId"]) + s.setKeyValue(TenantID, authFile["tenantId"]) + s.setKeyValue(ActiveDirectoryEndpoint, authFile["activeDirectoryEndpointUrl"]) + s.setKeyValue(ResourceManagerEndpoint, authFile["resourceManagerEndpointUrl"]) + s.setKeyValue(GraphResourceID, authFile["activeDirectoryGraphResourceId"]) + s.setKeyValue(SQLManagementEndpoint, authFile["sqlManagementEndpointUrl"]) + s.setKeyValue(GalleryEndpoint, authFile["galleryEndpointUrl"]) + s.setKeyValue(ManagementEndpoint, authFile["managementEndpointUrl"]) + return s, nil +} + +// FileSettings contains the available authentication settings. +type FileSettings struct { + Values map[string]string +} + +// GetSubscriptionID returns the available subscription ID or an empty string. +func (settings FileSettings) GetSubscriptionID() string { + return settings.Values[SubscriptionID] +} + +// adds the specified value to the Values map if it isn't nil +func (settings FileSettings) setKeyValue(key string, val interface{}) { + if val != nil { + settings.Values[key] = val.(string) + } +} + +// returns the specified AAD endpoint or the public cloud endpoint if unspecified +func (settings FileSettings) getAADEndpoint() string { + if v, ok := settings.Values[ActiveDirectoryEndpoint]; ok { + return v + } + return azure.PublicCloud.ActiveDirectoryEndpoint +} + +// ServicePrincipalTokenFromClientCredentials creates a ServicePrincipalToken from the available client credentials. +func (settings FileSettings) ServicePrincipalTokenFromClientCredentials(baseURI string) (*adal.ServicePrincipalToken, error) { + resource, err := settings.getResourceForToken(baseURI) + if err != nil { + return nil, err + } + return settings.ServicePrincipalTokenFromClientCredentialsWithResource(resource) +} + +// ClientCredentialsAuthorizer creates an authorizer from the available client credentials. +func (settings FileSettings) ClientCredentialsAuthorizer(baseURI string) (autorest.Authorizer, error) { + resource, err := settings.getResourceForToken(baseURI) + if err != nil { + return nil, err + } + return settings.ClientCredentialsAuthorizerWithResource(resource) +} + +// ServicePrincipalTokenFromClientCredentialsWithResource creates a ServicePrincipalToken +// from the available client credentials and the specified resource. +func (settings FileSettings) ServicePrincipalTokenFromClientCredentialsWithResource(resource string) (*adal.ServicePrincipalToken, error) { + if _, ok := settings.Values[ClientSecret]; !ok { + return nil, errors.New("missing client secret") + } + config, err := adal.NewOAuthConfig(settings.getAADEndpoint(), settings.Values[TenantID]) + if err != nil { + return nil, err + } + return adal.NewServicePrincipalToken(*config, settings.Values[ClientID], settings.Values[ClientSecret], resource) +} + +func (settings FileSettings) clientCertificateConfigWithResource(resource string) (ClientCertificateConfig, error) { + if _, ok := settings.Values[CertificatePath]; !ok { + return ClientCertificateConfig{}, errors.New("missing certificate path") + } + cfg := NewClientCertificateConfig(settings.Values[CertificatePath], settings.Values[CertificatePassword], settings.Values[ClientID], settings.Values[TenantID]) + cfg.AADEndpoint = settings.getAADEndpoint() + cfg.Resource = resource + return cfg, nil +} + +// ClientCredentialsAuthorizerWithResource creates an authorizer from the available client credentials and the specified resource. +func (settings FileSettings) ClientCredentialsAuthorizerWithResource(resource string) (autorest.Authorizer, error) { + spToken, err := settings.ServicePrincipalTokenFromClientCredentialsWithResource(resource) + if err != nil { + return nil, err + } + return autorest.NewBearerAuthorizer(spToken), nil +} + +// ServicePrincipalTokenFromClientCertificate creates a ServicePrincipalToken from the available certificate credentials. +func (settings FileSettings) ServicePrincipalTokenFromClientCertificate(baseURI string) (*adal.ServicePrincipalToken, error) { + resource, err := settings.getResourceForToken(baseURI) + if err != nil { + return nil, err + } + return settings.ServicePrincipalTokenFromClientCertificateWithResource(resource) +} + +// ClientCertificateAuthorizer creates an authorizer from the available certificate credentials. +func (settings FileSettings) ClientCertificateAuthorizer(baseURI string) (autorest.Authorizer, error) { + resource, err := settings.getResourceForToken(baseURI) + if err != nil { + return nil, err + } + return settings.ClientCertificateAuthorizerWithResource(resource) +} + +// ServicePrincipalTokenFromClientCertificateWithResource creates a ServicePrincipalToken from the available certificate credentials. +func (settings FileSettings) ServicePrincipalTokenFromClientCertificateWithResource(resource string) (*adal.ServicePrincipalToken, error) { + cfg, err := settings.clientCertificateConfigWithResource(resource) + if err != nil { + return nil, err + } + return cfg.ServicePrincipalToken() +} + +// ClientCertificateAuthorizerWithResource creates an authorizer from the available certificate credentials and the specified resource. +func (settings FileSettings) ClientCertificateAuthorizerWithResource(resource string) (autorest.Authorizer, error) { + cfg, err := settings.clientCertificateConfigWithResource(resource) + if err != nil { + return nil, err + } + return cfg.Authorizer() +} + +func decode(b []byte) ([]byte, error) { + reader, enc := utfbom.Skip(bytes.NewReader(b)) + + switch enc { + case utfbom.UTF16LittleEndian: + u16 := make([]uint16, (len(b)/2)-1) + err := binary.Read(reader, binary.LittleEndian, &u16) + if err != nil { + return nil, err + } + return []byte(string(utf16.Decode(u16))), nil + case utfbom.UTF16BigEndian: + u16 := make([]uint16, (len(b)/2)-1) + err := binary.Read(reader, binary.BigEndian, &u16) + if err != nil { + return nil, err + } + return []byte(string(utf16.Decode(u16))), nil + } + return ioutil.ReadAll(reader) +} + +func (settings FileSettings) getResourceForToken(baseURI string) (string, error) { + // Compare dafault base URI from the SDK to the endpoints from the public cloud + // Base URI and token resource are the same string. This func finds the authentication + // file field that matches the SDK base URI. The SDK defines the public cloud + // endpoint as its default base URI + if !strings.HasSuffix(baseURI, "/") { + baseURI += "/" + } + switch baseURI { + case azure.PublicCloud.ServiceManagementEndpoint: + return settings.Values[ManagementEndpoint], nil + case azure.PublicCloud.ResourceManagerEndpoint: + return settings.Values[ResourceManagerEndpoint], nil + case azure.PublicCloud.ActiveDirectoryEndpoint: + return settings.Values[ActiveDirectoryEndpoint], nil + case azure.PublicCloud.GalleryEndpoint: + return settings.Values[GalleryEndpoint], nil + case azure.PublicCloud.GraphEndpoint: + return settings.Values[GraphResourceID], nil + } + return "", fmt.Errorf("auth: base URI not found in endpoints") +} + +// NewClientCredentialsConfig creates an AuthorizerConfig object configured to obtain an Authorizer through Client Credentials. +// Defaults to Public Cloud and Resource Manager Endpoint. +func NewClientCredentialsConfig(clientID string, clientSecret string, tenantID string) ClientCredentialsConfig { + return ClientCredentialsConfig{ + ClientID: clientID, + ClientSecret: clientSecret, + TenantID: tenantID, + Resource: azure.PublicCloud.ResourceManagerEndpoint, + AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, + } +} + +// NewClientCertificateConfig creates a ClientCertificateConfig object configured to obtain an Authorizer through client certificate. +// Defaults to Public Cloud and Resource Manager Endpoint. +func NewClientCertificateConfig(certificatePath string, certificatePassword string, clientID string, tenantID string) ClientCertificateConfig { + return ClientCertificateConfig{ + CertificatePath: certificatePath, + CertificatePassword: certificatePassword, + ClientID: clientID, + TenantID: tenantID, + Resource: azure.PublicCloud.ResourceManagerEndpoint, + AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, + } +} + +// NewUsernamePasswordConfig creates an UsernamePasswordConfig object configured to obtain an Authorizer through username and password. +// Defaults to Public Cloud and Resource Manager Endpoint. +func NewUsernamePasswordConfig(username string, password string, clientID string, tenantID string) UsernamePasswordConfig { + return UsernamePasswordConfig{ + Username: username, + Password: password, + ClientID: clientID, + TenantID: tenantID, + Resource: azure.PublicCloud.ResourceManagerEndpoint, + AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, + } +} + +// NewMSIConfig creates an MSIConfig object configured to obtain an Authorizer through MSI. +func NewMSIConfig() MSIConfig { + return MSIConfig{ + Resource: azure.PublicCloud.ResourceManagerEndpoint, + } +} + +// NewDeviceFlowConfig creates a DeviceFlowConfig object configured to obtain an Authorizer through device flow. +// Defaults to Public Cloud and Resource Manager Endpoint. +func NewDeviceFlowConfig(clientID string, tenantID string) DeviceFlowConfig { + return DeviceFlowConfig{ + ClientID: clientID, + TenantID: tenantID, + Resource: azure.PublicCloud.ResourceManagerEndpoint, + AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, + } +} + +//AuthorizerConfig provides an authorizer from the configuration provided. +type AuthorizerConfig interface { + Authorizer() (autorest.Authorizer, error) +} + +// ClientCredentialsConfig provides the options to get a bearer authorizer from client credentials. +type ClientCredentialsConfig struct { + ClientID string + ClientSecret string + TenantID string + AADEndpoint string + Resource string +} + +// ServicePrincipalToken creates a ServicePrincipalToken from client credentials. +func (ccc ClientCredentialsConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { + oauthConfig, err := adal.NewOAuthConfig(ccc.AADEndpoint, ccc.TenantID) + if err != nil { + return nil, err + } + return adal.NewServicePrincipalToken(*oauthConfig, ccc.ClientID, ccc.ClientSecret, ccc.Resource) +} + +// Authorizer gets the authorizer from client credentials. +func (ccc ClientCredentialsConfig) Authorizer() (autorest.Authorizer, error) { + spToken, err := ccc.ServicePrincipalToken() + if err != nil { + return nil, fmt.Errorf("failed to get oauth token from client credentials: %v", err) + } + return autorest.NewBearerAuthorizer(spToken), nil +} + +// ClientCertificateConfig provides the options to get a bearer authorizer from a client certificate. +type ClientCertificateConfig struct { + ClientID string + CertificatePath string + CertificatePassword string + TenantID string + AADEndpoint string + Resource string +} + +// ServicePrincipalToken creates a ServicePrincipalToken from client certificate. +func (ccc ClientCertificateConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { + oauthConfig, err := adal.NewOAuthConfig(ccc.AADEndpoint, ccc.TenantID) + if err != nil { + return nil, err + } + certData, err := ioutil.ReadFile(ccc.CertificatePath) + if err != nil { + return nil, fmt.Errorf("failed to read the certificate file (%s): %v", ccc.CertificatePath, err) + } + certificate, rsaPrivateKey, err := decodePkcs12(certData, ccc.CertificatePassword) + if err != nil { + return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err) + } + return adal.NewServicePrincipalTokenFromCertificate(*oauthConfig, ccc.ClientID, certificate, rsaPrivateKey, ccc.Resource) +} + +// Authorizer gets an authorizer object from client certificate. +func (ccc ClientCertificateConfig) Authorizer() (autorest.Authorizer, error) { + spToken, err := ccc.ServicePrincipalToken() + if err != nil { + return nil, fmt.Errorf("failed to get oauth token from certificate auth: %v", err) + } + return autorest.NewBearerAuthorizer(spToken), nil +} + +// DeviceFlowConfig provides the options to get a bearer authorizer using device flow authentication. +type DeviceFlowConfig struct { + ClientID string + TenantID string + AADEndpoint string + Resource string +} + +// Authorizer gets the authorizer from device flow. +func (dfc DeviceFlowConfig) Authorizer() (autorest.Authorizer, error) { + spToken, err := dfc.ServicePrincipalToken() + if err != nil { + return nil, fmt.Errorf("failed to get oauth token from device flow: %v", err) + } + return autorest.NewBearerAuthorizer(spToken), nil +} + +// ServicePrincipalToken gets the service principal token from device flow. +func (dfc DeviceFlowConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { + oauthConfig, err := adal.NewOAuthConfig(dfc.AADEndpoint, dfc.TenantID) + if err != nil { + return nil, err + } + oauthClient := &autorest.Client{} + deviceCode, err := adal.InitiateDeviceAuth(oauthClient, *oauthConfig, dfc.ClientID, dfc.Resource) + if err != nil { + return nil, fmt.Errorf("failed to start device auth flow: %s", err) + } + log.Println(*deviceCode.Message) + token, err := adal.WaitForUserCompletion(oauthClient, deviceCode) + if err != nil { + return nil, fmt.Errorf("failed to finish device auth flow: %s", err) + } + return adal.NewServicePrincipalTokenFromManualToken(*oauthConfig, dfc.ClientID, dfc.Resource, *token) +} + +func decodePkcs12(pkcs []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) { + privateKey, certificate, err := pkcs12.Decode(pkcs, password) + if err != nil { + return nil, nil, err + } + + rsaPrivateKey, isRsaKey := privateKey.(*rsa.PrivateKey) + if !isRsaKey { + return nil, nil, fmt.Errorf("PKCS#12 certificate must contain an RSA private key") + } + + return certificate, rsaPrivateKey, nil +} + +// UsernamePasswordConfig provides the options to get a bearer authorizer from a username and a password. +type UsernamePasswordConfig struct { + ClientID string + Username string + Password string + TenantID string + AADEndpoint string + Resource string +} + +// ServicePrincipalToken creates a ServicePrincipalToken from username and password. +func (ups UsernamePasswordConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { + oauthConfig, err := adal.NewOAuthConfig(ups.AADEndpoint, ups.TenantID) + if err != nil { + return nil, err + } + return adal.NewServicePrincipalTokenFromUsernamePassword(*oauthConfig, ups.ClientID, ups.Username, ups.Password, ups.Resource) +} + +// Authorizer gets the authorizer from a username and a password. +func (ups UsernamePasswordConfig) Authorizer() (autorest.Authorizer, error) { + spToken, err := ups.ServicePrincipalToken() + if err != nil { + return nil, fmt.Errorf("failed to get oauth token from username and password auth: %v", err) + } + return autorest.NewBearerAuthorizer(spToken), nil +} + +// MSIConfig provides the options to get a bearer authorizer through MSI. +type MSIConfig struct { + Resource string + ClientID string +} + +// Authorizer gets the authorizer from MSI. +func (mc MSIConfig) Authorizer() (autorest.Authorizer, error) { + msiEndpoint, err := adal.GetMSIVMEndpoint() + if err != nil { + return nil, err + } + + var spToken *adal.ServicePrincipalToken + if mc.ClientID == "" { + spToken, err = adal.NewServicePrincipalTokenFromMSI(msiEndpoint, mc.Resource) + if err != nil { + return nil, fmt.Errorf("failed to get oauth token from MSI: %v", err) + } + } else { + spToken, err = adal.NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, mc.Resource, mc.ClientID) + if err != nil { + return nil, fmt.Errorf("failed to get oauth token from MSI for user assigned identity: %v", err) + } + } + + return autorest.NewBearerAuthorizer(spToken), nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go.mod b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go.mod new file mode 100644 index 000000000..9605c9711 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go.mod @@ -0,0 +1,11 @@ +module github.com/Azure/go-autorest/autorest/azure/auth + +go 1.12 + +require ( + github.com/Azure/go-autorest/autorest v0.1.0 + github.com/Azure/go-autorest/autorest/adal v0.1.0 + github.com/Azure/go-autorest/autorest/azure/cli v0.1.0 + github.com/dimchansky/utfbom v1.1.0 + golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 +) diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go.sum b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go.sum new file mode 100644 index 000000000..39f37022a --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go.sum @@ -0,0 +1,153 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc= +contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= +github.com/Azure/go-autorest/autorest v0.1.0 h1:z68s0uL7bVfplrwwCUsYoMezUVQdym6EPOllAT02BtU= +github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg= +github.com/Azure/go-autorest/autorest/adal v0.1.0 h1:RSw/7EAullliqwkZvgIGDYZWQm1PGKXI8c4aY/87yuU= +github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= +github.com/Azure/go-autorest/autorest/azure/cli v0.1.0 h1:YTtBrcb6mhA+PoSW8WxFDoIIyjp13XqJeX80ssQtri4= +github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U= +github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc= +github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= +github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 h1:O5YqonU5IWby+w98jVUG9h7zlCWCcH4RHyPVReBmhzk= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e h1:nFYrTHrdrAOpShe27kaFHjsqYSEQ0KWqdWLu3xuZJts= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go new file mode 100644 index 000000000..3a0a439ff --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go @@ -0,0 +1,326 @@ +// Package azure provides Azure-specific implementations used with AutoRest. +// See the included examples for more detail. +package azure + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "regexp" + "strconv" + "strings" + + "github.com/Azure/go-autorest/autorest" +) + +const ( + // HeaderClientID is the Azure extension header to set a user-specified request ID. + HeaderClientID = "x-ms-client-request-id" + + // HeaderReturnClientID is the Azure extension header to set if the user-specified request ID + // should be included in the response. + HeaderReturnClientID = "x-ms-return-client-request-id" + + // HeaderRequestID is the Azure extension header of the service generated request ID returned + // in the response. + HeaderRequestID = "x-ms-request-id" +) + +// ServiceError encapsulates the error response from an Azure service. +// It adhears to the OData v4 specification for error responses. +type ServiceError struct { + Code string `json:"code"` + Message string `json:"message"` + Target *string `json:"target"` + Details []map[string]interface{} `json:"details"` + InnerError map[string]interface{} `json:"innererror"` + AdditionalInfo []map[string]interface{} `json:"additionalInfo"` +} + +func (se ServiceError) Error() string { + result := fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message) + + if se.Target != nil { + result += fmt.Sprintf(" Target=%q", *se.Target) + } + + if se.Details != nil { + d, err := json.Marshal(se.Details) + if err != nil { + result += fmt.Sprintf(" Details=%v", se.Details) + } + result += fmt.Sprintf(" Details=%v", string(d)) + } + + if se.InnerError != nil { + d, err := json.Marshal(se.InnerError) + if err != nil { + result += fmt.Sprintf(" InnerError=%v", se.InnerError) + } + result += fmt.Sprintf(" InnerError=%v", string(d)) + } + + if se.AdditionalInfo != nil { + d, err := json.Marshal(se.AdditionalInfo) + if err != nil { + result += fmt.Sprintf(" AdditionalInfo=%v", se.AdditionalInfo) + } + result += fmt.Sprintf(" AdditionalInfo=%v", string(d)) + } + + return result +} + +// UnmarshalJSON implements the json.Unmarshaler interface for the ServiceError type. +func (se *ServiceError) UnmarshalJSON(b []byte) error { + // per the OData v4 spec the details field must be an array of JSON objects. + // unfortunately not all services adhear to the spec and just return a single + // object instead of an array with one object. so we have to perform some + // shenanigans to accommodate both cases. + // http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793091 + + type serviceError1 struct { + Code string `json:"code"` + Message string `json:"message"` + Target *string `json:"target"` + Details []map[string]interface{} `json:"details"` + InnerError map[string]interface{} `json:"innererror"` + AdditionalInfo []map[string]interface{} `json:"additionalInfo"` + } + + type serviceError2 struct { + Code string `json:"code"` + Message string `json:"message"` + Target *string `json:"target"` + Details map[string]interface{} `json:"details"` + InnerError map[string]interface{} `json:"innererror"` + AdditionalInfo []map[string]interface{} `json:"additionalInfo"` + } + + se1 := serviceError1{} + err := json.Unmarshal(b, &se1) + if err == nil { + se.populate(se1.Code, se1.Message, se1.Target, se1.Details, se1.InnerError, se1.AdditionalInfo) + return nil + } + + se2 := serviceError2{} + err = json.Unmarshal(b, &se2) + if err == nil { + se.populate(se2.Code, se2.Message, se2.Target, nil, se2.InnerError, se2.AdditionalInfo) + se.Details = append(se.Details, se2.Details) + return nil + } + return err +} + +func (se *ServiceError) populate(code, message string, target *string, details []map[string]interface{}, inner map[string]interface{}, additional []map[string]interface{}) { + se.Code = code + se.Message = message + se.Target = target + se.Details = details + se.InnerError = inner + se.AdditionalInfo = additional +} + +// RequestError describes an error response returned by Azure service. +type RequestError struct { + autorest.DetailedError + + // The error returned by the Azure service. + ServiceError *ServiceError `json:"error"` + + // The request id (from the x-ms-request-id-header) of the request. + RequestID string +} + +// Error returns a human-friendly error message from service error. +func (e RequestError) Error() string { + return fmt.Sprintf("autorest/azure: Service returned an error. Status=%v %v", + e.StatusCode, e.ServiceError) +} + +// IsAzureError returns true if the passed error is an Azure Service error; false otherwise. +func IsAzureError(e error) bool { + _, ok := e.(*RequestError) + return ok +} + +// Resource contains details about an Azure resource. +type Resource struct { + SubscriptionID string + ResourceGroup string + Provider string + ResourceType string + ResourceName string +} + +// ParseResourceID parses a resource ID into a ResourceDetails struct. +// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-resource#return-value-4. +func ParseResourceID(resourceID string) (Resource, error) { + + const resourceIDPatternText = `(?i)subscriptions/(.+)/resourceGroups/(.+)/providers/(.+?)/(.+?)/(.+)` + resourceIDPattern := regexp.MustCompile(resourceIDPatternText) + match := resourceIDPattern.FindStringSubmatch(resourceID) + + if len(match) == 0 { + return Resource{}, fmt.Errorf("parsing failed for %s. Invalid resource Id format", resourceID) + } + + v := strings.Split(match[5], "/") + resourceName := v[len(v)-1] + + result := Resource{ + SubscriptionID: match[1], + ResourceGroup: match[2], + Provider: match[3], + ResourceType: match[4], + ResourceName: resourceName, + } + + return result, nil +} + +// NewErrorWithError creates a new Error conforming object from the +// passed packageType, method, statusCode of the given resp (UndefinedStatusCode +// if resp is nil), message, and original error. message is treated as a format +// string to which the optional args apply. +func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) RequestError { + if v, ok := original.(*RequestError); ok { + return *v + } + + statusCode := autorest.UndefinedStatusCode + if resp != nil { + statusCode = resp.StatusCode + } + return RequestError{ + DetailedError: autorest.DetailedError{ + Original: original, + PackageType: packageType, + Method: method, + StatusCode: statusCode, + Message: fmt.Sprintf(message, args...), + }, + } +} + +// WithReturningClientID returns a PrepareDecorator that adds an HTTP extension header of +// x-ms-client-request-id whose value is the passed, undecorated UUID (e.g., +// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). It also sets the x-ms-return-client-request-id +// header to true such that UUID accompanies the http.Response. +func WithReturningClientID(uuid string) autorest.PrepareDecorator { + preparer := autorest.CreatePreparer( + WithClientID(uuid), + WithReturnClientID(true)) + + return func(p autorest.Preparer) autorest.Preparer { + return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err != nil { + return r, err + } + return preparer.Prepare(r) + }) + } +} + +// WithClientID returns a PrepareDecorator that adds an HTTP extension header of +// x-ms-client-request-id whose value is passed, undecorated UUID (e.g., +// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). +func WithClientID(uuid string) autorest.PrepareDecorator { + return autorest.WithHeader(HeaderClientID, uuid) +} + +// WithReturnClientID returns a PrepareDecorator that adds an HTTP extension header of +// x-ms-return-client-request-id whose boolean value indicates if the value of the +// x-ms-client-request-id header should be included in the http.Response. +func WithReturnClientID(b bool) autorest.PrepareDecorator { + return autorest.WithHeader(HeaderReturnClientID, strconv.FormatBool(b)) +} + +// ExtractClientID extracts the client identifier from the x-ms-client-request-id header set on the +// http.Request sent to the service (and returned in the http.Response) +func ExtractClientID(resp *http.Response) string { + return autorest.ExtractHeaderValue(HeaderClientID, resp) +} + +// ExtractRequestID extracts the Azure server generated request identifier from the +// x-ms-request-id header. +func ExtractRequestID(resp *http.Response) string { + return autorest.ExtractHeaderValue(HeaderRequestID, resp) +} + +// WithErrorUnlessStatusCode returns a RespondDecorator that emits an +// azure.RequestError by reading the response body unless the response HTTP status code +// is among the set passed. +// +// If there is a chance service may return responses other than the Azure error +// format and the response cannot be parsed into an error, a decoding error will +// be returned containing the response body. In any case, the Responder will +// return an error if the status code is not satisfied. +// +// If this Responder returns an error, the response body will be replaced with +// an in-memory reader, which needs no further closing. +func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { + return func(r autorest.Responder) autorest.Responder { + return autorest.ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) { + var e RequestError + defer resp.Body.Close() + + // Copy and replace the Body in case it does not contain an error object. + // This will leave the Body available to the caller. + b, decodeErr := autorest.CopyAndDecode(autorest.EncodedAsJSON, resp.Body, &e) + resp.Body = ioutil.NopCloser(&b) + if decodeErr != nil { + return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr) + } + if e.ServiceError == nil { + // Check if error is unwrapped ServiceError + if err := json.Unmarshal(b.Bytes(), &e.ServiceError); err != nil { + return err + } + } + if e.ServiceError.Message == "" { + // if we're here it means the returned error wasn't OData v4 compliant. + // try to unmarshal the body as raw JSON in hopes of getting something. + rawBody := map[string]interface{}{} + if err := json.Unmarshal(b.Bytes(), &rawBody); err != nil { + return err + } + e.ServiceError = &ServiceError{ + Code: "Unknown", + Message: "Unknown service error", + } + if len(rawBody) > 0 { + e.ServiceError.Details = []map[string]interface{}{rawBody} + } + } + e.Response = resp + e.RequestID = ExtractRequestID(resp) + if e.StatusCode == nil { + e.StatusCode = resp.StatusCode + } + err = &e + } + return err + }) + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.mod b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.mod new file mode 100644 index 000000000..a147222b4 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.mod @@ -0,0 +1,10 @@ +module github.com/Azure/go-autorest/autorest/azure/cli + +go 1.12 + +require ( + github.com/Azure/go-autorest/autorest/adal v0.1.0 + github.com/Azure/go-autorest/autorest/date v0.1.0 + github.com/dimchansky/utfbom v1.1.0 + github.com/mitchellh/go-homedir v1.1.0 +) diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.sum b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.sum new file mode 100644 index 000000000..1d098cff2 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.sum @@ -0,0 +1,144 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc= +contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= +github.com/Azure/go-autorest/autorest/adal v0.1.0 h1:RSw/7EAullliqwkZvgIGDYZWQm1PGKXI8c4aY/87yuU= +github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= +github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc= +github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= +github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/profile.go b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/profile.go new file mode 100644 index 000000000..a336b958d --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/profile.go @@ -0,0 +1,79 @@ +package cli + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/dimchansky/utfbom" + "github.com/mitchellh/go-homedir" +) + +// Profile represents a Profile from the Azure CLI +type Profile struct { + InstallationID string `json:"installationId"` + Subscriptions []Subscription `json:"subscriptions"` +} + +// Subscription represents a Subscription from the Azure CLI +type Subscription struct { + EnvironmentName string `json:"environmentName"` + ID string `json:"id"` + IsDefault bool `json:"isDefault"` + Name string `json:"name"` + State string `json:"state"` + TenantID string `json:"tenantId"` + User *User `json:"user"` +} + +// User represents a User from the Azure CLI +type User struct { + Name string `json:"name"` + Type string `json:"type"` +} + +const azureProfileJSON = "azureProfile.json" + +// ProfilePath returns the path where the Azure Profile is stored from the Azure CLI +func ProfilePath() (string, error) { + if cfgDir := os.Getenv("AZURE_CONFIG_DIR"); cfgDir != "" { + return filepath.Join(cfgDir, azureProfileJSON), nil + } + return homedir.Expand("~/.azure/" + azureProfileJSON) +} + +// LoadProfile restores a Profile object from a file located at 'path'. +func LoadProfile(path string) (result Profile, err error) { + var contents []byte + contents, err = ioutil.ReadFile(path) + if err != nil { + err = fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) + return + } + reader := utfbom.SkipOnly(bytes.NewReader(contents)) + + dec := json.NewDecoder(reader) + if err = dec.Decode(&result); err != nil { + err = fmt.Errorf("failed to decode contents of file (%s) into a Profile representation: %v", path, err) + return + } + + return +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/token.go b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/token.go new file mode 100644 index 000000000..810075ba6 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/token.go @@ -0,0 +1,170 @@ +package cli + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "os/exec" + "regexp" + "runtime" + "strconv" + "time" + + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/autorest/date" + "github.com/mitchellh/go-homedir" +) + +// Token represents an AccessToken from the Azure CLI +type Token struct { + AccessToken string `json:"accessToken"` + Authority string `json:"_authority"` + ClientID string `json:"_clientId"` + ExpiresOn string `json:"expiresOn"` + IdentityProvider string `json:"identityProvider"` + IsMRRT bool `json:"isMRRT"` + RefreshToken string `json:"refreshToken"` + Resource string `json:"resource"` + TokenType string `json:"tokenType"` + UserID string `json:"userId"` +} + +// ToADALToken converts an Azure CLI `Token`` to an `adal.Token`` +func (t Token) ToADALToken() (converted adal.Token, err error) { + tokenExpirationDate, err := ParseExpirationDate(t.ExpiresOn) + if err != nil { + err = fmt.Errorf("Error parsing Token Expiration Date %q: %+v", t.ExpiresOn, err) + return + } + + difference := tokenExpirationDate.Sub(date.UnixEpoch()) + + converted = adal.Token{ + AccessToken: t.AccessToken, + Type: t.TokenType, + ExpiresIn: "3600", + ExpiresOn: json.Number(strconv.Itoa(int(difference.Seconds()))), + RefreshToken: t.RefreshToken, + Resource: t.Resource, + } + return +} + +// AccessTokensPath returns the path where access tokens are stored from the Azure CLI +// TODO(#199): add unit test. +func AccessTokensPath() (string, error) { + // Azure-CLI allows user to customize the path of access tokens thorugh environment variable. + var accessTokenPath = os.Getenv("AZURE_ACCESS_TOKEN_FILE") + var err error + + // Fallback logic to default path on non-cloud-shell environment. + // TODO(#200): remove the dependency on hard-coding path. + if accessTokenPath == "" { + accessTokenPath, err = homedir.Expand("~/.azure/accessTokens.json") + } + + return accessTokenPath, err +} + +// ParseExpirationDate parses either a Azure CLI or CloudShell date into a time object +func ParseExpirationDate(input string) (*time.Time, error) { + // CloudShell (and potentially the Azure CLI in future) + expirationDate, cloudShellErr := time.Parse(time.RFC3339, input) + if cloudShellErr != nil { + // Azure CLI (Python) e.g. 2017-08-31 19:48:57.998857 (plus the local timezone) + const cliFormat = "2006-01-02 15:04:05.999999" + expirationDate, cliErr := time.ParseInLocation(cliFormat, input, time.Local) + if cliErr == nil { + return &expirationDate, nil + } + + return nil, fmt.Errorf("Error parsing expiration date %q.\n\nCloudShell Error: \n%+v\n\nCLI Error:\n%+v", input, cloudShellErr, cliErr) + } + + return &expirationDate, nil +} + +// LoadTokens restores a set of Token objects from a file located at 'path'. +func LoadTokens(path string) ([]Token, error) { + file, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) + } + defer file.Close() + + var tokens []Token + + dec := json.NewDecoder(file) + if err = dec.Decode(&tokens); err != nil { + return nil, fmt.Errorf("failed to decode contents of file (%s) into a `cli.Token` representation: %v", path, err) + } + + return tokens, nil +} + +// GetTokenFromCLI gets a token using Azure CLI 2.0 for local development scenarios. +func GetTokenFromCLI(resource string) (*Token, error) { + // This is the path that a developer can set to tell this class what the install path for Azure CLI is. + const azureCLIPath = "AzureCLIPath" + + // The default install paths are used to find Azure CLI. This is for security, so that any path in the calling program's Path environment is not used to execute Azure CLI. + azureCLIDefaultPathWindows := fmt.Sprintf("%s\\Microsoft SDKs\\Azure\\CLI2\\wbin; %s\\Microsoft SDKs\\Azure\\CLI2\\wbin", os.Getenv("ProgramFiles(x86)"), os.Getenv("ProgramFiles")) + + // Default path for non-Windows. + const azureCLIDefaultPath = "/bin:/sbin:/usr/bin:/usr/local/bin" + + // Validate resource, since it gets sent as a command line argument to Azure CLI + const invalidResourceErrorTemplate = "Resource %s is not in expected format. Only alphanumeric characters, [dot], [colon], [hyphen], and [forward slash] are allowed." + match, err := regexp.MatchString("^[0-9a-zA-Z-.:/]+$", resource) + if err != nil { + return nil, err + } + if !match { + return nil, fmt.Errorf(invalidResourceErrorTemplate, resource) + } + + // Execute Azure CLI to get token + var cliCmd *exec.Cmd + if runtime.GOOS == "windows" { + cliCmd = exec.Command(fmt.Sprintf("%s\\system32\\cmd.exe", os.Getenv("windir"))) + cliCmd.Env = os.Environ() + cliCmd.Env = append(cliCmd.Env, fmt.Sprintf("PATH=%s;%s", os.Getenv(azureCLIPath), azureCLIDefaultPathWindows)) + cliCmd.Args = append(cliCmd.Args, "/c", "az") + } else { + cliCmd = exec.Command("az") + cliCmd.Env = os.Environ() + cliCmd.Env = append(cliCmd.Env, fmt.Sprintf("PATH=%s:%s", os.Getenv(azureCLIPath), azureCLIDefaultPath)) + } + cliCmd.Args = append(cliCmd.Args, "account", "get-access-token", "-o", "json", "--resource", resource) + + var stderr bytes.Buffer + cliCmd.Stderr = &stderr + + output, err := cliCmd.Output() + if err != nil { + return nil, fmt.Errorf("Invoking Azure CLI failed with the following error: %s", stderr.String()) + } + + tokenResponse := Token{} + err = json.Unmarshal(output, &tokenResponse) + if err != nil { + return nil, err + } + + return &tokenResponse, err +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go new file mode 100644 index 000000000..6c20b8179 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go @@ -0,0 +1,244 @@ +package azure + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strings" +) + +const ( + // EnvironmentFilepathName captures the name of the environment variable containing the path to the file + // to be used while populating the Azure Environment. + EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH" + + // NotAvailable is used for endpoints and resource IDs that are not available for a given cloud. + NotAvailable = "N/A" +) + +var environments = map[string]Environment{ + "AZURECHINACLOUD": ChinaCloud, + "AZUREGERMANCLOUD": GermanCloud, + "AZUREPUBLICCLOUD": PublicCloud, + "AZUREUSGOVERNMENTCLOUD": USGovernmentCloud, +} + +// ResourceIdentifier contains a set of Azure resource IDs. +type ResourceIdentifier struct { + Graph string `json:"graph"` + KeyVault string `json:"keyVault"` + Datalake string `json:"datalake"` + Batch string `json:"batch"` + OperationalInsights string `json:"operationalInsights"` + Storage string `json:"storage"` +} + +// Environment represents a set of endpoints for each of Azure's Clouds. +type Environment struct { + Name string `json:"name"` + ManagementPortalURL string `json:"managementPortalURL"` + PublishSettingsURL string `json:"publishSettingsURL"` + ServiceManagementEndpoint string `json:"serviceManagementEndpoint"` + ResourceManagerEndpoint string `json:"resourceManagerEndpoint"` + ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"` + GalleryEndpoint string `json:"galleryEndpoint"` + KeyVaultEndpoint string `json:"keyVaultEndpoint"` + GraphEndpoint string `json:"graphEndpoint"` + ServiceBusEndpoint string `json:"serviceBusEndpoint"` + BatchManagementEndpoint string `json:"batchManagementEndpoint"` + StorageEndpointSuffix string `json:"storageEndpointSuffix"` + SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"` + TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"` + KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"` + ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"` + ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"` + ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"` + ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"` + CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"` + TokenAudience string `json:"tokenAudience"` + ResourceIdentifiers ResourceIdentifier `json:"resourceIdentifiers"` +} + +var ( + // PublicCloud is the default public Azure cloud environment + PublicCloud = Environment{ + Name: "AzurePublicCloud", + ManagementPortalURL: "https://manage.windowsazure.com/", + PublishSettingsURL: "https://manage.windowsazure.com/publishsettings/index", + ServiceManagementEndpoint: "https://management.core.windows.net/", + ResourceManagerEndpoint: "https://management.azure.com/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", + GalleryEndpoint: "https://gallery.azure.com/", + KeyVaultEndpoint: "https://vault.azure.net/", + GraphEndpoint: "https://graph.windows.net/", + ServiceBusEndpoint: "https://servicebus.windows.net/", + BatchManagementEndpoint: "https://batch.core.windows.net/", + StorageEndpointSuffix: "core.windows.net", + SQLDatabaseDNSSuffix: "database.windows.net", + TrafficManagerDNSSuffix: "trafficmanager.net", + KeyVaultDNSSuffix: "vault.azure.net", + ServiceBusEndpointSuffix: "servicebus.windows.net", + ServiceManagementVMDNSSuffix: "cloudapp.net", + ResourceManagerVMDNSSuffix: "cloudapp.azure.com", + ContainerRegistryDNSSuffix: "azurecr.io", + CosmosDBDNSSuffix: "documents.azure.com", + TokenAudience: "https://management.azure.com/", + ResourceIdentifiers: ResourceIdentifier{ + Graph: "https://graph.windows.net/", + KeyVault: "https://vault.azure.net", + Datalake: "https://datalake.azure.net/", + Batch: "https://batch.core.windows.net/", + OperationalInsights: "https://api.loganalytics.io", + Storage: "https://storage.azure.com/", + }, + } + + // USGovernmentCloud is the cloud environment for the US Government + USGovernmentCloud = Environment{ + Name: "AzureUSGovernmentCloud", + ManagementPortalURL: "https://manage.windowsazure.us/", + PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index", + ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/", + ResourceManagerEndpoint: "https://management.usgovcloudapi.net/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.us/", + GalleryEndpoint: "https://gallery.usgovcloudapi.net/", + KeyVaultEndpoint: "https://vault.usgovcloudapi.net/", + GraphEndpoint: "https://graph.windows.net/", + ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/", + BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/", + StorageEndpointSuffix: "core.usgovcloudapi.net", + SQLDatabaseDNSSuffix: "database.usgovcloudapi.net", + TrafficManagerDNSSuffix: "usgovtrafficmanager.net", + KeyVaultDNSSuffix: "vault.usgovcloudapi.net", + ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net", + ServiceManagementVMDNSSuffix: "usgovcloudapp.net", + ResourceManagerVMDNSSuffix: "cloudapp.windowsazure.us", + ContainerRegistryDNSSuffix: "azurecr.us", + CosmosDBDNSSuffix: "documents.azure.us", + TokenAudience: "https://management.usgovcloudapi.net/", + ResourceIdentifiers: ResourceIdentifier{ + Graph: "https://graph.windows.net/", + KeyVault: "https://vault.usgovcloudapi.net", + Datalake: NotAvailable, + Batch: "https://batch.core.usgovcloudapi.net/", + OperationalInsights: "https://api.loganalytics.us", + Storage: "https://storage.azure.com/", + }, + } + + // ChinaCloud is the cloud environment operated in China + ChinaCloud = Environment{ + Name: "AzureChinaCloud", + ManagementPortalURL: "https://manage.chinacloudapi.com/", + PublishSettingsURL: "https://manage.chinacloudapi.com/publishsettings/index", + ServiceManagementEndpoint: "https://management.core.chinacloudapi.cn/", + ResourceManagerEndpoint: "https://management.chinacloudapi.cn/", + ActiveDirectoryEndpoint: "https://login.chinacloudapi.cn/", + GalleryEndpoint: "https://gallery.chinacloudapi.cn/", + KeyVaultEndpoint: "https://vault.azure.cn/", + GraphEndpoint: "https://graph.chinacloudapi.cn/", + ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/", + BatchManagementEndpoint: "https://batch.chinacloudapi.cn/", + StorageEndpointSuffix: "core.chinacloudapi.cn", + SQLDatabaseDNSSuffix: "database.chinacloudapi.cn", + TrafficManagerDNSSuffix: "trafficmanager.cn", + KeyVaultDNSSuffix: "vault.azure.cn", + ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn", + ServiceManagementVMDNSSuffix: "chinacloudapp.cn", + ResourceManagerVMDNSSuffix: "cloudapp.azure.cn", + ContainerRegistryDNSSuffix: "azurecr.cn", + CosmosDBDNSSuffix: "documents.azure.cn", + TokenAudience: "https://management.chinacloudapi.cn/", + ResourceIdentifiers: ResourceIdentifier{ + Graph: "https://graph.chinacloudapi.cn/", + KeyVault: "https://vault.azure.cn", + Datalake: NotAvailable, + Batch: "https://batch.chinacloudapi.cn/", + OperationalInsights: NotAvailable, + Storage: "https://storage.azure.com/", + }, + } + + // GermanCloud is the cloud environment operated in Germany + GermanCloud = Environment{ + Name: "AzureGermanCloud", + ManagementPortalURL: "http://portal.microsoftazure.de/", + PublishSettingsURL: "https://manage.microsoftazure.de/publishsettings/index", + ServiceManagementEndpoint: "https://management.core.cloudapi.de/", + ResourceManagerEndpoint: "https://management.microsoftazure.de/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.de/", + GalleryEndpoint: "https://gallery.cloudapi.de/", + KeyVaultEndpoint: "https://vault.microsoftazure.de/", + GraphEndpoint: "https://graph.cloudapi.de/", + ServiceBusEndpoint: "https://servicebus.cloudapi.de/", + BatchManagementEndpoint: "https://batch.cloudapi.de/", + StorageEndpointSuffix: "core.cloudapi.de", + SQLDatabaseDNSSuffix: "database.cloudapi.de", + TrafficManagerDNSSuffix: "azuretrafficmanager.de", + KeyVaultDNSSuffix: "vault.microsoftazure.de", + ServiceBusEndpointSuffix: "servicebus.cloudapi.de", + ServiceManagementVMDNSSuffix: "azurecloudapp.de", + ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de", + ContainerRegistryDNSSuffix: NotAvailable, + CosmosDBDNSSuffix: "documents.microsoftazure.de", + TokenAudience: "https://management.microsoftazure.de/", + ResourceIdentifiers: ResourceIdentifier{ + Graph: "https://graph.cloudapi.de/", + KeyVault: "https://vault.microsoftazure.de", + Datalake: NotAvailable, + Batch: "https://batch.cloudapi.de/", + OperationalInsights: NotAvailable, + Storage: "https://storage.azure.com/", + }, + } +) + +// EnvironmentFromName returns an Environment based on the common name specified. +func EnvironmentFromName(name string) (Environment, error) { + // IMPORTANT + // As per @radhikagupta5: + // This is technical debt, fundamentally here because Kubernetes is not currently accepting + // contributions to the providers. Once that is an option, the provider should be updated to + // directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation + // from this method based on the name that is provided to us. + if strings.EqualFold(name, "AZURESTACKCLOUD") { + return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName)) + } + + name = strings.ToUpper(name) + env, ok := environments[name] + if !ok { + return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name) + } + + return env, nil +} + +// EnvironmentFromFile loads an Environment from a configuration file available on disk. +// This function is particularly useful in the Hybrid Cloud model, where one must define their own +// endpoints. +func EnvironmentFromFile(location string) (unmarshaled Environment, err error) { + fileContents, err := ioutil.ReadFile(location) + if err != nil { + return + } + + err = json.Unmarshal(fileContents, &unmarshaled) + + return +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go b/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go new file mode 100644 index 000000000..507f9e95c --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go @@ -0,0 +1,245 @@ +package azure + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" + + "github.com/Azure/go-autorest/autorest" +) + +// Copyright 2017 Microsoft Corporation +// +// 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. + +type audience []string + +type authentication struct { + LoginEndpoint string `json:"loginEndpoint"` + Audiences audience `json:"audiences"` +} + +type environmentMetadataInfo struct { + GalleryEndpoint string `json:"galleryEndpoint"` + GraphEndpoint string `json:"graphEndpoint"` + PortalEndpoint string `json:"portalEndpoint"` + Authentication authentication `json:"authentication"` +} + +// EnvironmentProperty represent property names that clients can override +type EnvironmentProperty string + +const ( + // EnvironmentName ... + EnvironmentName EnvironmentProperty = "name" + // EnvironmentManagementPortalURL .. + EnvironmentManagementPortalURL EnvironmentProperty = "managementPortalURL" + // EnvironmentPublishSettingsURL ... + EnvironmentPublishSettingsURL EnvironmentProperty = "publishSettingsURL" + // EnvironmentServiceManagementEndpoint ... + EnvironmentServiceManagementEndpoint EnvironmentProperty = "serviceManagementEndpoint" + // EnvironmentResourceManagerEndpoint ... + EnvironmentResourceManagerEndpoint EnvironmentProperty = "resourceManagerEndpoint" + // EnvironmentActiveDirectoryEndpoint ... + EnvironmentActiveDirectoryEndpoint EnvironmentProperty = "activeDirectoryEndpoint" + // EnvironmentGalleryEndpoint ... + EnvironmentGalleryEndpoint EnvironmentProperty = "galleryEndpoint" + // EnvironmentKeyVaultEndpoint ... + EnvironmentKeyVaultEndpoint EnvironmentProperty = "keyVaultEndpoint" + // EnvironmentGraphEndpoint ... + EnvironmentGraphEndpoint EnvironmentProperty = "graphEndpoint" + // EnvironmentServiceBusEndpoint ... + EnvironmentServiceBusEndpoint EnvironmentProperty = "serviceBusEndpoint" + // EnvironmentBatchManagementEndpoint ... + EnvironmentBatchManagementEndpoint EnvironmentProperty = "batchManagementEndpoint" + // EnvironmentStorageEndpointSuffix ... + EnvironmentStorageEndpointSuffix EnvironmentProperty = "storageEndpointSuffix" + // EnvironmentSQLDatabaseDNSSuffix ... + EnvironmentSQLDatabaseDNSSuffix EnvironmentProperty = "sqlDatabaseDNSSuffix" + // EnvironmentTrafficManagerDNSSuffix ... + EnvironmentTrafficManagerDNSSuffix EnvironmentProperty = "trafficManagerDNSSuffix" + // EnvironmentKeyVaultDNSSuffix ... + EnvironmentKeyVaultDNSSuffix EnvironmentProperty = "keyVaultDNSSuffix" + // EnvironmentServiceBusEndpointSuffix ... + EnvironmentServiceBusEndpointSuffix EnvironmentProperty = "serviceBusEndpointSuffix" + // EnvironmentServiceManagementVMDNSSuffix ... + EnvironmentServiceManagementVMDNSSuffix EnvironmentProperty = "serviceManagementVMDNSSuffix" + // EnvironmentResourceManagerVMDNSSuffix ... + EnvironmentResourceManagerVMDNSSuffix EnvironmentProperty = "resourceManagerVMDNSSuffix" + // EnvironmentContainerRegistryDNSSuffix ... + EnvironmentContainerRegistryDNSSuffix EnvironmentProperty = "containerRegistryDNSSuffix" + // EnvironmentTokenAudience ... + EnvironmentTokenAudience EnvironmentProperty = "tokenAudience" +) + +// OverrideProperty represents property name and value that clients can override +type OverrideProperty struct { + Key EnvironmentProperty + Value string +} + +// EnvironmentFromURL loads an Environment from a URL +// This function is particularly useful in the Hybrid Cloud model, where one may define their own +// endpoints. +func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) { + var metadataEnvProperties environmentMetadataInfo + + if resourceManagerEndpoint == "" { + return environment, fmt.Errorf("Metadata resource manager endpoint is empty") + } + + if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil { + return environment, err + } + + // Give priority to user's override values + overrideProperties(&environment, properties) + + if environment.Name == "" { + environment.Name = "HybridEnvironment" + } + stampDNSSuffix := environment.StorageEndpointSuffix + if stampDNSSuffix == "" { + stampDNSSuffix = strings.TrimSuffix(strings.TrimPrefix(strings.Replace(resourceManagerEndpoint, strings.Split(resourceManagerEndpoint, ".")[0], "", 1), "."), "/") + environment.StorageEndpointSuffix = stampDNSSuffix + } + if environment.KeyVaultDNSSuffix == "" { + environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix) + } + if environment.KeyVaultEndpoint == "" { + environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix) + } + if environment.TokenAudience == "" { + environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0] + } + if environment.ActiveDirectoryEndpoint == "" { + environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint + } + if environment.ResourceManagerEndpoint == "" { + environment.ResourceManagerEndpoint = resourceManagerEndpoint + } + if environment.GalleryEndpoint == "" { + environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint + } + if environment.GraphEndpoint == "" { + environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint + } + + return environment, nil +} + +func overrideProperties(environment *Environment, properties []OverrideProperty) { + for _, property := range properties { + switch property.Key { + case EnvironmentName: + { + environment.Name = property.Value + } + case EnvironmentManagementPortalURL: + { + environment.ManagementPortalURL = property.Value + } + case EnvironmentPublishSettingsURL: + { + environment.PublishSettingsURL = property.Value + } + case EnvironmentServiceManagementEndpoint: + { + environment.ServiceManagementEndpoint = property.Value + } + case EnvironmentResourceManagerEndpoint: + { + environment.ResourceManagerEndpoint = property.Value + } + case EnvironmentActiveDirectoryEndpoint: + { + environment.ActiveDirectoryEndpoint = property.Value + } + case EnvironmentGalleryEndpoint: + { + environment.GalleryEndpoint = property.Value + } + case EnvironmentKeyVaultEndpoint: + { + environment.KeyVaultEndpoint = property.Value + } + case EnvironmentGraphEndpoint: + { + environment.GraphEndpoint = property.Value + } + case EnvironmentServiceBusEndpoint: + { + environment.ServiceBusEndpoint = property.Value + } + case EnvironmentBatchManagementEndpoint: + { + environment.BatchManagementEndpoint = property.Value + } + case EnvironmentStorageEndpointSuffix: + { + environment.StorageEndpointSuffix = property.Value + } + case EnvironmentSQLDatabaseDNSSuffix: + { + environment.SQLDatabaseDNSSuffix = property.Value + } + case EnvironmentTrafficManagerDNSSuffix: + { + environment.TrafficManagerDNSSuffix = property.Value + } + case EnvironmentKeyVaultDNSSuffix: + { + environment.KeyVaultDNSSuffix = property.Value + } + case EnvironmentServiceBusEndpointSuffix: + { + environment.ServiceBusEndpointSuffix = property.Value + } + case EnvironmentServiceManagementVMDNSSuffix: + { + environment.ServiceManagementVMDNSSuffix = property.Value + } + case EnvironmentResourceManagerVMDNSSuffix: + { + environment.ResourceManagerVMDNSSuffix = property.Value + } + case EnvironmentContainerRegistryDNSSuffix: + { + environment.ContainerRegistryDNSSuffix = property.Value + } + case EnvironmentTokenAudience: + { + environment.TokenAudience = property.Value + } + } + } +} + +func retrieveMetadataEnvironment(endpoint string) (environment environmentMetadataInfo, err error) { + client := autorest.NewClientWithUserAgent("") + managementEndpoint := fmt.Sprintf("%s%s", strings.TrimSuffix(endpoint, "/"), "/metadata/endpoints?api-version=1.0") + req, _ := http.NewRequest("GET", managementEndpoint, nil) + response, err := client.Do(req) + if err != nil { + return environment, err + } + defer response.Body.Close() + jsonResponse, err := ioutil.ReadAll(response.Body) + if err != nil { + return environment, err + } + err = json.Unmarshal(jsonResponse, &environment) + return environment, err +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go new file mode 100644 index 000000000..86ce9f2b5 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go @@ -0,0 +1,200 @@ +// Copyright 2017 Microsoft Corporation +// +// 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. + +package azure + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strings" + "time" + + "github.com/Azure/go-autorest/autorest" +) + +// DoRetryWithRegistration tries to register the resource provider in case it is unregistered. +// It also handles request retries +func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator { + return func(s autorest.Sender) autorest.Sender { + return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + rr := autorest.NewRetriableRequest(r) + for currentAttempt := 0; currentAttempt < client.RetryAttempts; currentAttempt++ { + err = rr.Prepare() + if err != nil { + return resp, err + } + + resp, err = autorest.SendWithSender(s, rr.Request(), + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), + ) + if err != nil { + return resp, err + } + + if resp.StatusCode != http.StatusConflict || client.SkipResourceProviderRegistration { + return resp, err + } + var re RequestError + err = autorest.Respond( + resp, + autorest.ByUnmarshallingJSON(&re), + ) + if err != nil { + return resp, err + } + err = re + + if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" { + regErr := register(client, r, re) + if regErr != nil { + return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %s", regErr, err) + } + } + } + return resp, err + }) + } +} + +func getProvider(re RequestError) (string, error) { + if re.ServiceError != nil && len(re.ServiceError.Details) > 0 { + return re.ServiceError.Details[0]["target"].(string), nil + } + return "", errors.New("provider was not found in the response") +} + +func register(client autorest.Client, originalReq *http.Request, re RequestError) error { + subID := getSubscription(originalReq.URL.Path) + if subID == "" { + return errors.New("missing parameter subscriptionID to register resource provider") + } + providerName, err := getProvider(re) + if err != nil { + return fmt.Errorf("missing parameter provider to register resource provider: %s", err) + } + newURL := url.URL{ + Scheme: originalReq.URL.Scheme, + Host: originalReq.URL.Host, + } + + // taken from the resources SDK + // with almost identical code, this sections are easier to mantain + // It is also not a good idea to import the SDK here + // https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L252 + pathParameters := map[string]interface{}{ + "resourceProviderNamespace": autorest.Encode("path", providerName), + "subscriptionId": autorest.Encode("path", subID), + } + + const APIVersion = "2016-09-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsPost(), + autorest.WithBaseURL(newURL.String()), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters), + autorest.WithQueryParameters(queryParameters), + ) + + req, err := preparer.Prepare(&http.Request{}) + if err != nil { + return err + } + req = req.WithContext(originalReq.Context()) + + resp, err := autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), + ) + if err != nil { + return err + } + + type Provider struct { + RegistrationState *string `json:"registrationState,omitempty"` + } + var provider Provider + + err = autorest.Respond( + resp, + WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&provider), + autorest.ByClosing(), + ) + if err != nil { + return err + } + + // poll for registered provisioning state + registrationStartTime := time.Now() + for err == nil && (client.PollingDuration == 0 || (client.PollingDuration != 0 && time.Since(registrationStartTime) < client.PollingDuration)) { + // taken from the resources SDK + // https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45 + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(newURL.String()), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters), + autorest.WithQueryParameters(queryParameters), + ) + req, err = preparer.Prepare(&http.Request{}) + if err != nil { + return err + } + req = req.WithContext(originalReq.Context()) + + resp, err := autorest.SendWithSender(client, req, + autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), + ) + if err != nil { + return err + } + + err = autorest.Respond( + resp, + WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&provider), + autorest.ByClosing(), + ) + if err != nil { + return err + } + + if provider.RegistrationState != nil && + *provider.RegistrationState == "Registered" { + break + } + + delayed := autorest.DelayWithRetryAfter(resp, originalReq.Context().Done()) + if !delayed && !autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Context().Done()) { + return originalReq.Context().Err() + } + } + if client.PollingDuration != 0 && !(time.Since(registrationStartTime) < client.PollingDuration) { + return errors.New("polling for resource provider registration has exceeded the polling duration") + } + return err +} + +func getSubscription(path string) string { + parts := strings.Split(path, "/") + for i, v := range parts { + if v == "subscriptions" && (i+1) < len(parts) { + return parts[i+1] + } + } + return "" +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/client.go b/vendor/github.com/Azure/go-autorest/autorest/client.go new file mode 100644 index 000000000..92da6adb2 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/client.go @@ -0,0 +1,324 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "crypto/tls" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "net/http/cookiejar" + "strings" + "time" + + "github.com/Azure/go-autorest/logger" + "github.com/Azure/go-autorest/tracing" +) + +const ( + // DefaultPollingDelay is a reasonable delay between polling requests. + DefaultPollingDelay = 60 * time.Second + + // DefaultPollingDuration is a reasonable total polling duration. + DefaultPollingDuration = 15 * time.Minute + + // DefaultRetryAttempts is number of attempts for retry status codes (5xx). + DefaultRetryAttempts = 3 + + // DefaultRetryDuration is the duration to wait between retries. + DefaultRetryDuration = 30 * time.Second +) + +var ( + // StatusCodesForRetry are a defined group of status code for which the client will retry + StatusCodesForRetry = []int{ + http.StatusRequestTimeout, // 408 + http.StatusTooManyRequests, // 429 + http.StatusInternalServerError, // 500 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 + } +) + +const ( + requestFormat = `HTTP Request Begin =================================================== +%s +===================================================== HTTP Request End +` + responseFormat = `HTTP Response Begin =================================================== +%s +===================================================== HTTP Response End +` +) + +// Response serves as the base for all responses from generated clients. It provides access to the +// last http.Response. +type Response struct { + *http.Response `json:"-"` +} + +// IsHTTPStatus returns true if the returned HTTP status code matches the provided status code. +// If there was no response (i.e. the underlying http.Response is nil) the return value is false. +func (r Response) IsHTTPStatus(statusCode int) bool { + if r.Response == nil { + return false + } + return r.Response.StatusCode == statusCode +} + +// HasHTTPStatus returns true if the returned HTTP status code matches one of the provided status codes. +// If there was no response (i.e. the underlying http.Response is nil) or not status codes are provided +// the return value is false. +func (r Response) HasHTTPStatus(statusCodes ...int) bool { + return ResponseHasStatusCode(r.Response, statusCodes...) +} + +// LoggingInspector implements request and response inspectors that log the full request and +// response to a supplied log. +type LoggingInspector struct { + Logger *log.Logger +} + +// WithInspection returns a PrepareDecorator that emits the http.Request to the supplied logger. The +// body is restored after being emitted. +// +// Note: Since it reads the entire Body, this decorator should not be used where body streaming is +// important. It is best used to trace JSON or similar body values. +func (li LoggingInspector) WithInspection() PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + var body, b bytes.Buffer + + defer r.Body.Close() + + r.Body = ioutil.NopCloser(io.TeeReader(r.Body, &body)) + if err := r.Write(&b); err != nil { + return nil, fmt.Errorf("Failed to write response: %v", err) + } + + li.Logger.Printf(requestFormat, b.String()) + + r.Body = ioutil.NopCloser(&body) + return p.Prepare(r) + }) + } +} + +// ByInspecting returns a RespondDecorator that emits the http.Response to the supplied logger. The +// body is restored after being emitted. +// +// Note: Since it reads the entire Body, this decorator should not be used where body streaming is +// important. It is best used to trace JSON or similar body values. +func (li LoggingInspector) ByInspecting() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + var body, b bytes.Buffer + defer resp.Body.Close() + resp.Body = ioutil.NopCloser(io.TeeReader(resp.Body, &body)) + if err := resp.Write(&b); err != nil { + return fmt.Errorf("Failed to write response: %v", err) + } + + li.Logger.Printf(responseFormat, b.String()) + + resp.Body = ioutil.NopCloser(&body) + return r.Respond(resp) + }) + } +} + +// Client is the base for autorest generated clients. It provides default, "do nothing" +// implementations of an Authorizer, RequestInspector, and ResponseInspector. It also returns the +// standard, undecorated http.Client as a default Sender. +// +// Generated clients should also use Error (see NewError and NewErrorWithError) for errors and +// return responses that compose with Response. +// +// Most customization of generated clients is best achieved by supplying a custom Authorizer, custom +// RequestInspector, and / or custom ResponseInspector. Users may log requests, implement circuit +// breakers (see https://msdn.microsoft.com/en-us/library/dn589784.aspx) or otherwise influence +// sending the request by providing a decorated Sender. +type Client struct { + Authorizer Authorizer + Sender Sender + RequestInspector PrepareDecorator + ResponseInspector RespondDecorator + + // PollingDelay sets the polling frequency used in absence of a Retry-After HTTP header + PollingDelay time.Duration + + // PollingDuration sets the maximum polling time after which an error is returned. + // Setting this to zero will use the provided context to control the duration. + PollingDuration time.Duration + + // RetryAttempts sets the default number of retry attempts for client. + RetryAttempts int + + // RetryDuration sets the delay duration for retries. + RetryDuration time.Duration + + // UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent + // through the Do method. + UserAgent string + + Jar http.CookieJar + + // Set to true to skip attempted registration of resource providers (false by default). + SkipResourceProviderRegistration bool +} + +// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed +// string. +func NewClientWithUserAgent(ua string) Client { + return newClient(ua, tls.RenegotiateNever) +} + +// ClientOptions contains various Client configuration options. +type ClientOptions struct { + // UserAgent is an optional user-agent string to append to the default user agent. + UserAgent string + + // Renegotiation is an optional setting to control client-side TLS renegotiation. + Renegotiation tls.RenegotiationSupport +} + +// NewClientWithOptions returns an instance of a Client with the specified values. +func NewClientWithOptions(options ClientOptions) Client { + return newClient(options.UserAgent, options.Renegotiation) +} + +func newClient(ua string, renegotiation tls.RenegotiationSupport) Client { + c := Client{ + PollingDelay: DefaultPollingDelay, + PollingDuration: DefaultPollingDuration, + RetryAttempts: DefaultRetryAttempts, + RetryDuration: DefaultRetryDuration, + UserAgent: UserAgent(), + } + c.Sender = c.sender(renegotiation) + c.AddToUserAgent(ua) + return c +} + +// AddToUserAgent adds an extension to the current user agent +func (c *Client) AddToUserAgent(extension string) error { + if extension != "" { + c.UserAgent = fmt.Sprintf("%s %s", c.UserAgent, extension) + return nil + } + return fmt.Errorf("Extension was empty, User Agent stayed as %s", c.UserAgent) +} + +// Do implements the Sender interface by invoking the active Sender after applying authorization. +// If Sender is not set, it uses a new instance of http.Client. In both cases it will, if UserAgent +// is set, apply set the User-Agent header. +func (c Client) Do(r *http.Request) (*http.Response, error) { + if r.UserAgent() == "" { + r, _ = Prepare(r, + WithUserAgent(c.UserAgent)) + } + // NOTE: c.WithInspection() must be last in the list so that it can inspect all preceding operations + r, err := Prepare(r, + c.WithAuthorization(), + c.WithInspection()) + if err != nil { + var resp *http.Response + if detErr, ok := err.(DetailedError); ok { + // if the authorization failed (e.g. invalid credentials) there will + // be a response associated with the error, be sure to return it. + resp = detErr.Response + } + return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed") + } + logger.Instance.WriteRequest(r, logger.Filter{ + Header: func(k string, v []string) (bool, []string) { + // remove the auth token from the log + if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "Ocp-Apim-Subscription-Key") { + v = []string{"**REDACTED**"} + } + return true, v + }, + }) + resp, err := SendWithSender(c.sender(tls.RenegotiateNever), r) + logger.Instance.WriteResponse(resp, logger.Filter{}) + Respond(resp, c.ByInspecting()) + return resp, err +} + +// sender returns the Sender to which to send requests. +func (c Client) sender(renengotiation tls.RenegotiationSupport) Sender { + if c.Sender == nil { + // Use behaviour compatible with DefaultTransport, but require TLS minimum version. + var defaultTransport = http.DefaultTransport.(*http.Transport) + transport := tracing.Transport + // for non-default values of TLS renegotiation create a new tracing transport. + // updating tracing.Transport affects all clients which is not what we want. + if renengotiation != tls.RenegotiateNever { + transport = tracing.NewTransport() + } + transport.Base = &http.Transport{ + Proxy: defaultTransport.Proxy, + DialContext: defaultTransport.DialContext, + MaxIdleConns: defaultTransport.MaxIdleConns, + IdleConnTimeout: defaultTransport.IdleConnTimeout, + TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout, + ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout, + TLSClientConfig: &tls.Config{ + MinVersion: tls.VersionTLS12, + Renegotiation: renengotiation, + }, + } + j, _ := cookiejar.New(nil) + return &http.Client{Jar: j, Transport: transport} + } + + return c.Sender +} + +// WithAuthorization is a convenience method that returns the WithAuthorization PrepareDecorator +// from the current Authorizer. If not Authorizer is set, it uses the NullAuthorizer. +func (c Client) WithAuthorization() PrepareDecorator { + return c.authorizer().WithAuthorization() +} + +// authorizer returns the Authorizer to use. +func (c Client) authorizer() Authorizer { + if c.Authorizer == nil { + return NullAuthorizer{} + } + return c.Authorizer +} + +// WithInspection is a convenience method that passes the request to the supplied RequestInspector, +// if present, or returns the WithNothing PrepareDecorator otherwise. +func (c Client) WithInspection() PrepareDecorator { + if c.RequestInspector == nil { + return WithNothing() + } + return c.RequestInspector +} + +// ByInspecting is a convenience method that passes the response to the supplied ResponseInspector, +// if present, or returns the ByIgnoring RespondDecorator otherwise. +func (c Client) ByInspecting() RespondDecorator { + if c.ResponseInspector == nil { + return ByIgnoring() + } + return c.ResponseInspector +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/date.go b/vendor/github.com/Azure/go-autorest/autorest/date/date.go new file mode 100644 index 000000000..c45710656 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/date.go @@ -0,0 +1,96 @@ +/* +Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/) +defined date formats: Date and DateTime. Both types may, in most cases, be used in lieu of +time.Time types. And both convert to time.Time through a ToTime method. +*/ +package date + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "fmt" + "time" +) + +const ( + fullDate = "2006-01-02" + fullDateJSON = `"2006-01-02"` + dateFormat = "%04d-%02d-%02d" + jsonFormat = `"%04d-%02d-%02d"` +) + +// Date defines a type similar to time.Time but assumes a layout of RFC3339 full-date (i.e., +// 2006-01-02). +type Date struct { + time.Time +} + +// ParseDate create a new Date from the passed string. +func ParseDate(date string) (d Date, err error) { + return parseDate(date, fullDate) +} + +func parseDate(date string, format string) (Date, error) { + d, err := time.Parse(format, date) + return Date{Time: d}, err +} + +// MarshalBinary preserves the Date as a byte array conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d Date) MarshalBinary() ([]byte, error) { + return d.MarshalText() +} + +// UnmarshalBinary reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d *Date) UnmarshalBinary(data []byte) error { + return d.UnmarshalText(data) +} + +// MarshalJSON preserves the Date as a JSON string conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d Date) MarshalJSON() (json []byte, err error) { + return []byte(fmt.Sprintf(jsonFormat, d.Year(), d.Month(), d.Day())), nil +} + +// UnmarshalJSON reconstitutes the Date from a JSON string conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d *Date) UnmarshalJSON(data []byte) (err error) { + d.Time, err = time.Parse(fullDateJSON, string(data)) + return err +} + +// MarshalText preserves the Date as a byte array conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d Date) MarshalText() (text []byte, err error) { + return []byte(fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())), nil +} + +// UnmarshalText reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., +// 2006-01-02). +func (d *Date) UnmarshalText(data []byte) (err error) { + d.Time, err = time.Parse(fullDate, string(data)) + return err +} + +// String returns the Date formatted as an RFC3339 full-date string (i.e., 2006-01-02). +func (d Date) String() string { + return fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day()) +} + +// ToTime returns a Date as a time.Time +func (d Date) ToTime() time.Time { + return d.Time +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/go.mod b/vendor/github.com/Azure/go-autorest/autorest/date/go.mod new file mode 100644 index 000000000..13a1e9803 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/go.mod @@ -0,0 +1,3 @@ +module github.com/Azure/go-autorest/autorest/date + +go 1.12 diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/time.go b/vendor/github.com/Azure/go-autorest/autorest/date/time.go new file mode 100644 index 000000000..b453fad04 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/time.go @@ -0,0 +1,103 @@ +package date + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "regexp" + "time" +) + +// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases. +const ( + azureUtcFormatJSON = `"2006-01-02T15:04:05.999999999"` + azureUtcFormat = "2006-01-02T15:04:05.999999999" + rfc3339JSON = `"` + time.RFC3339Nano + `"` + rfc3339 = time.RFC3339Nano + tzOffsetRegex = `(Z|z|\+|-)(\d+:\d+)*"*$` +) + +// Time defines a type similar to time.Time but assumes a layout of RFC3339 date-time (i.e., +// 2006-01-02T15:04:05Z). +type Time struct { + time.Time +} + +// MarshalBinary preserves the Time as a byte array conforming to RFC3339 date-time (i.e., +// 2006-01-02T15:04:05Z). +func (t Time) MarshalBinary() ([]byte, error) { + return t.Time.MarshalText() +} + +// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC3339 date-time +// (i.e., 2006-01-02T15:04:05Z). +func (t *Time) UnmarshalBinary(data []byte) error { + return t.UnmarshalText(data) +} + +// MarshalJSON preserves the Time as a JSON string conforming to RFC3339 date-time (i.e., +// 2006-01-02T15:04:05Z). +func (t Time) MarshalJSON() (json []byte, err error) { + return t.Time.MarshalJSON() +} + +// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC3339 date-time +// (i.e., 2006-01-02T15:04:05Z). +func (t *Time) UnmarshalJSON(data []byte) (err error) { + timeFormat := azureUtcFormatJSON + match, err := regexp.Match(tzOffsetRegex, data) + if err != nil { + return err + } else if match { + timeFormat = rfc3339JSON + } + t.Time, err = ParseTime(timeFormat, string(data)) + return err +} + +// MarshalText preserves the Time as a byte array conforming to RFC3339 date-time (i.e., +// 2006-01-02T15:04:05Z). +func (t Time) MarshalText() (text []byte, err error) { + return t.Time.MarshalText() +} + +// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC3339 date-time +// (i.e., 2006-01-02T15:04:05Z). +func (t *Time) UnmarshalText(data []byte) (err error) { + timeFormat := azureUtcFormat + match, err := regexp.Match(tzOffsetRegex, data) + if err != nil { + return err + } else if match { + timeFormat = rfc3339 + } + t.Time, err = ParseTime(timeFormat, string(data)) + return err +} + +// String returns the Time formatted as an RFC3339 date-time string (i.e., +// 2006-01-02T15:04:05Z). +func (t Time) String() string { + // Note: time.Time.String does not return an RFC3339 compliant string, time.Time.MarshalText does. + b, err := t.MarshalText() + if err != nil { + return "" + } + return string(b) +} + +// ToTime returns a Time as a time.Time +func (t Time) ToTime() time.Time { + return t.Time +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go new file mode 100644 index 000000000..48fb39ba9 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go @@ -0,0 +1,100 @@ +package date + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "errors" + "time" +) + +const ( + rfc1123JSON = `"` + time.RFC1123 + `"` + rfc1123 = time.RFC1123 +) + +// TimeRFC1123 defines a type similar to time.Time but assumes a layout of RFC1123 date-time (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +type TimeRFC1123 struct { + time.Time +} + +// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC1123 date-time +// (i.e., Mon, 02 Jan 2006 15:04:05 MST). +func (t *TimeRFC1123) UnmarshalJSON(data []byte) (err error) { + t.Time, err = ParseTime(rfc1123JSON, string(data)) + if err != nil { + return err + } + return nil +} + +// MarshalJSON preserves the Time as a JSON string conforming to RFC1123 date-time (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +func (t TimeRFC1123) MarshalJSON() ([]byte, error) { + if y := t.Year(); y < 0 || y >= 10000 { + return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]") + } + b := []byte(t.Format(rfc1123JSON)) + return b, nil +} + +// MarshalText preserves the Time as a byte array conforming to RFC1123 date-time (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +func (t TimeRFC1123) MarshalText() ([]byte, error) { + if y := t.Year(); y < 0 || y >= 10000 { + return nil, errors.New("Time.MarshalText: year outside of range [0,9999]") + } + + b := []byte(t.Format(rfc1123)) + return b, nil +} + +// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC1123 date-time +// (i.e., Mon, 02 Jan 2006 15:04:05 MST). +func (t *TimeRFC1123) UnmarshalText(data []byte) (err error) { + t.Time, err = ParseTime(rfc1123, string(data)) + if err != nil { + return err + } + return nil +} + +// MarshalBinary preserves the Time as a byte array conforming to RFC1123 date-time (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +func (t TimeRFC1123) MarshalBinary() ([]byte, error) { + return t.MarshalText() +} + +// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC1123 date-time +// (i.e., Mon, 02 Jan 2006 15:04:05 MST). +func (t *TimeRFC1123) UnmarshalBinary(data []byte) error { + return t.UnmarshalText(data) +} + +// ToTime returns a Time as a time.Time +func (t TimeRFC1123) ToTime() time.Time { + return t.Time +} + +// String returns the Time formatted as an RFC1123 date-time string (i.e., +// Mon, 02 Jan 2006 15:04:05 MST). +func (t TimeRFC1123) String() string { + // Note: time.Time.String does not return an RFC1123 compliant string, time.Time.MarshalText does. + b, err := t.MarshalText() + if err != nil { + return "" + } + return string(b) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go b/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go new file mode 100644 index 000000000..7073959b2 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go @@ -0,0 +1,123 @@ +package date + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "time" +) + +// unixEpoch is the moment in time that should be treated as timestamp 0. +var unixEpoch = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC) + +// UnixTime marshals and unmarshals a time that is represented as the number +// of seconds (ignoring skip-seconds) since the Unix Epoch. +type UnixTime time.Time + +// Duration returns the time as a Duration since the UnixEpoch. +func (t UnixTime) Duration() time.Duration { + return time.Time(t).Sub(unixEpoch) +} + +// NewUnixTimeFromSeconds creates a UnixTime as a number of seconds from the UnixEpoch. +func NewUnixTimeFromSeconds(seconds float64) UnixTime { + return NewUnixTimeFromDuration(time.Duration(seconds * float64(time.Second))) +} + +// NewUnixTimeFromNanoseconds creates a UnixTime as a number of nanoseconds from the UnixEpoch. +func NewUnixTimeFromNanoseconds(nanoseconds int64) UnixTime { + return NewUnixTimeFromDuration(time.Duration(nanoseconds)) +} + +// NewUnixTimeFromDuration creates a UnixTime as a duration of time since the UnixEpoch. +func NewUnixTimeFromDuration(dur time.Duration) UnixTime { + return UnixTime(unixEpoch.Add(dur)) +} + +// UnixEpoch retreives the moment considered the Unix Epoch. I.e. The time represented by '0' +func UnixEpoch() time.Time { + return unixEpoch +} + +// MarshalJSON preserves the UnixTime as a JSON number conforming to Unix Timestamp requirements. +// (i.e. the number of seconds since midnight January 1st, 1970 not considering leap seconds.) +func (t UnixTime) MarshalJSON() ([]byte, error) { + buffer := &bytes.Buffer{} + enc := json.NewEncoder(buffer) + err := enc.Encode(float64(time.Time(t).UnixNano()) / 1e9) + if err != nil { + return nil, err + } + return buffer.Bytes(), nil +} + +// UnmarshalJSON reconstitures a UnixTime saved as a JSON number of the number of seconds since +// midnight January 1st, 1970. +func (t *UnixTime) UnmarshalJSON(text []byte) error { + dec := json.NewDecoder(bytes.NewReader(text)) + + var secondsSinceEpoch float64 + if err := dec.Decode(&secondsSinceEpoch); err != nil { + return err + } + + *t = NewUnixTimeFromSeconds(secondsSinceEpoch) + + return nil +} + +// MarshalText stores the number of seconds since the Unix Epoch as a textual floating point number. +func (t UnixTime) MarshalText() ([]byte, error) { + cast := time.Time(t) + return cast.MarshalText() +} + +// UnmarshalText populates a UnixTime with a value stored textually as a floating point number of seconds since the Unix Epoch. +func (t *UnixTime) UnmarshalText(raw []byte) error { + var unmarshaled time.Time + + if err := unmarshaled.UnmarshalText(raw); err != nil { + return err + } + + *t = UnixTime(unmarshaled) + return nil +} + +// MarshalBinary converts a UnixTime into a binary.LittleEndian float64 of nanoseconds since the epoch. +func (t UnixTime) MarshalBinary() ([]byte, error) { + buf := &bytes.Buffer{} + + payload := int64(t.Duration()) + + if err := binary.Write(buf, binary.LittleEndian, &payload); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +// UnmarshalBinary converts a from a binary.LittleEndian float64 of nanoseconds since the epoch into a UnixTime. +func (t *UnixTime) UnmarshalBinary(raw []byte) error { + var nanosecondsSinceEpoch int64 + + if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &nanosecondsSinceEpoch); err != nil { + return err + } + *t = NewUnixTimeFromNanoseconds(nanosecondsSinceEpoch) + return nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go new file mode 100644 index 000000000..12addf0eb --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go @@ -0,0 +1,25 @@ +package date + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "strings" + "time" +) + +// ParseTime to parse Time string to specified format. +func ParseTime(format string, t string) (d time.Time, err error) { + return time.Parse(format, strings.ToUpper(t)) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/error.go b/vendor/github.com/Azure/go-autorest/autorest/error.go new file mode 100644 index 000000000..f724f3332 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/error.go @@ -0,0 +1,98 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "fmt" + "net/http" +) + +const ( + // UndefinedStatusCode is used when HTTP status code is not available for an error. + UndefinedStatusCode = 0 +) + +// DetailedError encloses a error with details of the package, method, and associated HTTP +// status code (if any). +type DetailedError struct { + Original error + + // PackageType is the package type of the object emitting the error. For types, the value + // matches that produced the the '%T' format specifier of the fmt package. For other elements, + // such as functions, it is just the package name (e.g., "autorest"). + PackageType string + + // Method is the name of the method raising the error. + Method string + + // StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error. + StatusCode interface{} + + // Message is the error message. + Message string + + // Service Error is the response body of failed API in bytes + ServiceError []byte + + // Response is the response object that was returned during failure if applicable. + Response *http.Response +} + +// NewError creates a new Error conforming object from the passed packageType, method, and +// message. message is treated as a format string to which the optional args apply. +func NewError(packageType string, method string, message string, args ...interface{}) DetailedError { + return NewErrorWithError(nil, packageType, method, nil, message, args...) +} + +// NewErrorWithResponse creates a new Error conforming object from the passed +// packageType, method, statusCode of the given resp (UndefinedStatusCode if +// resp is nil), and message. message is treated as a format string to which the +// optional args apply. +func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { + return NewErrorWithError(nil, packageType, method, resp, message, args...) +} + +// NewErrorWithError creates a new Error conforming object from the +// passed packageType, method, statusCode of the given resp (UndefinedStatusCode +// if resp is nil), message, and original error. message is treated as a format +// string to which the optional args apply. +func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { + if v, ok := original.(DetailedError); ok { + return v + } + + statusCode := UndefinedStatusCode + if resp != nil { + statusCode = resp.StatusCode + } + + return DetailedError{ + Original: original, + PackageType: packageType, + Method: method, + StatusCode: statusCode, + Message: fmt.Sprintf(message, args...), + Response: resp, + } +} + +// Error returns a formatted containing all available details (i.e., PackageType, Method, +// StatusCode, Message, and original error (if any)). +func (e DetailedError) Error() string { + if e.Original == nil { + return fmt.Sprintf("%s#%s: %s: StatusCode=%d", e.PackageType, e.Method, e.Message, e.StatusCode) + } + return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/go.mod b/vendor/github.com/Azure/go-autorest/autorest/go.mod new file mode 100644 index 000000000..6b7c7f276 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/go.mod @@ -0,0 +1,12 @@ +module github.com/Azure/go-autorest/autorest + +go 1.12 + +require ( + github.com/Azure/go-autorest/autorest/adal v0.2.0 + github.com/Azure/go-autorest/autorest/mocks v0.1.0 + github.com/Azure/go-autorest/logger v0.1.0 + github.com/Azure/go-autorest/tracing v0.1.0 + go.opencensus.io v0.20.2 + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 +) diff --git a/vendor/github.com/Azure/go-autorest/autorest/go.sum b/vendor/github.com/Azure/go-autorest/autorest/go.sum new file mode 100644 index 000000000..a6848303f --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/go.sum @@ -0,0 +1,143 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc= +contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= +github.com/Azure/go-autorest/autorest/adal v0.2.0 h1:7IBDu1jgh+ADHXnEYExkV9RE/ztOOlxdACkkPRthGKw= +github.com/Azure/go-autorest/autorest/adal v0.2.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= +github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.1.0 h1:TRBxC5Pj/fIuh4Qob0ZpkggbfT8RC0SubHbpV3p4/Vc= +github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= +github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/Azure/go-autorest/autorest/preparer.go b/vendor/github.com/Azure/go-autorest/autorest/preparer.go new file mode 100644 index 000000000..489140224 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/preparer.go @@ -0,0 +1,526 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "mime/multipart" + "net/http" + "net/url" + "strings" +) + +const ( + mimeTypeJSON = "application/json" + mimeTypeOctetStream = "application/octet-stream" + mimeTypeFormPost = "application/x-www-form-urlencoded" + + headerAuthorization = "Authorization" + headerAuxAuthorization = "x-ms-authorization-auxiliary" + headerContentType = "Content-Type" + headerUserAgent = "User-Agent" +) + +// Preparer is the interface that wraps the Prepare method. +// +// Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations +// must ensure to not share or hold per-invocation state since Preparers may be shared and re-used. +type Preparer interface { + Prepare(*http.Request) (*http.Request, error) +} + +// PreparerFunc is a method that implements the Preparer interface. +type PreparerFunc func(*http.Request) (*http.Request, error) + +// Prepare implements the Preparer interface on PreparerFunc. +func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) { + return pf(r) +} + +// PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the +// http.Request and pass it along or, first, pass the http.Request along then affect the result. +type PrepareDecorator func(Preparer) Preparer + +// CreatePreparer creates, decorates, and returns a Preparer. +// Without decorators, the returned Preparer returns the passed http.Request unmodified. +// Preparers are safe to share and re-use. +func CreatePreparer(decorators ...PrepareDecorator) Preparer { + return DecoratePreparer( + Preparer(PreparerFunc(func(r *http.Request) (*http.Request, error) { return r, nil })), + decorators...) +} + +// DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it +// applies to the Preparer. Decorators are applied in the order received, but their affect upon the +// request depends on whether they are a pre-decorator (change the http.Request and then pass it +// along) or a post-decorator (pass the http.Request along and alter it on return). +func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer { + for _, decorate := range decorators { + p = decorate(p) + } + return p +} + +// Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators. +// It creates a Preparer from the decorators which it then applies to the passed http.Request. +func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error) { + if r == nil { + return nil, NewError("autorest", "Prepare", "Invoked without an http.Request") + } + return CreatePreparer(decorators...).Prepare(r) +} + +// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed +// http.Request. +func WithNothing() PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + return p.Prepare(r) + }) + } +} + +// WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to +// the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before +// adding the header. +func WithHeader(header string, value string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.Header == nil { + r.Header = make(http.Header) + } + r.Header.Set(http.CanonicalHeaderKey(header), value) + } + return r, err + }) + } +} + +// WithHeaders returns a PrepareDecorator that sets the specified HTTP headers of the http.Request to +// the passed value. It canonicalizes the passed headers name (via http.CanonicalHeaderKey) before +// adding them. +func WithHeaders(headers map[string]interface{}) PrepareDecorator { + h := ensureValueStrings(headers) + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.Header == nil { + r.Header = make(http.Header) + } + + for name, value := range h { + r.Header.Set(http.CanonicalHeaderKey(name), value) + } + } + return r, err + }) + } +} + +// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose +// value is "Bearer " followed by the supplied token. +func WithBearerAuthorization(token string) PrepareDecorator { + return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", token)) +} + +// AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value +// is the passed contentType. +func AsContentType(contentType string) PrepareDecorator { + return WithHeader(headerContentType, contentType) +} + +// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the +// passed string. +func WithUserAgent(ua string) PrepareDecorator { + return WithHeader(headerUserAgent, ua) +} + +// AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is +// "application/x-www-form-urlencoded". +func AsFormURLEncoded() PrepareDecorator { + return AsContentType(mimeTypeFormPost) +} + +// AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is +// "application/json". +func AsJSON() PrepareDecorator { + return AsContentType(mimeTypeJSON) +} + +// AsOctetStream returns a PrepareDecorator that adds the "application/octet-stream" Content-Type header. +func AsOctetStream() PrepareDecorator { + return AsContentType(mimeTypeOctetStream) +} + +// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The +// decorator does not validate that the passed method string is a known HTTP method. +func WithMethod(method string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r.Method = method + return p.Prepare(r) + }) + } +} + +// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE. +func AsDelete() PrepareDecorator { return WithMethod("DELETE") } + +// AsGet returns a PrepareDecorator that sets the HTTP method to GET. +func AsGet() PrepareDecorator { return WithMethod("GET") } + +// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD. +func AsHead() PrepareDecorator { return WithMethod("HEAD") } + +// AsMerge returns a PrepareDecorator that sets the HTTP method to MERGE. +func AsMerge() PrepareDecorator { return WithMethod("MERGE") } + +// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS. +func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") } + +// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH. +func AsPatch() PrepareDecorator { return WithMethod("PATCH") } + +// AsPost returns a PrepareDecorator that sets the HTTP method to POST. +func AsPost() PrepareDecorator { return WithMethod("POST") } + +// AsPut returns a PrepareDecorator that sets the HTTP method to PUT. +func AsPut() PrepareDecorator { return WithMethod("PUT") } + +// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed +// from the supplied baseUrl. +func WithBaseURL(baseURL string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + var u *url.URL + if u, err = url.Parse(baseURL); err != nil { + return r, err + } + if u.Scheme == "" { + err = fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) + } + if err == nil { + r.URL = u + } + } + return r, err + }) + } +} + +// WithBytes returns a PrepareDecorator that takes a list of bytes +// which passes the bytes directly to the body +func WithBytes(input *[]byte) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if input == nil { + return r, fmt.Errorf("Input Bytes was nil") + } + + r.ContentLength = int64(len(*input)) + r.Body = ioutil.NopCloser(bytes.NewReader(*input)) + } + return r, err + }) + } +} + +// WithCustomBaseURL returns a PrepareDecorator that replaces brace-enclosed keys within the +// request base URL (i.e., http.Request.URL) with the corresponding values from the passed map. +func WithCustomBaseURL(baseURL string, urlParameters map[string]interface{}) PrepareDecorator { + parameters := ensureValueStrings(urlParameters) + for key, value := range parameters { + baseURL = strings.Replace(baseURL, "{"+key+"}", value, -1) + } + return WithBaseURL(baseURL) +} + +// WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the +// http.Request body. +func WithFormData(v url.Values) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + s := v.Encode() + + if r.Header == nil { + r.Header = make(http.Header) + } + r.Header.Set(http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost) + r.ContentLength = int64(len(s)) + r.Body = ioutil.NopCloser(strings.NewReader(s)) + } + return r, err + }) + } +} + +// WithMultiPartFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) form parameters +// into the http.Request body. +func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + var body bytes.Buffer + writer := multipart.NewWriter(&body) + for key, value := range formDataParameters { + if rc, ok := value.(io.ReadCloser); ok { + var fd io.Writer + if fd, err = writer.CreateFormFile(key, key); err != nil { + return r, err + } + if _, err = io.Copy(fd, rc); err != nil { + return r, err + } + } else { + if err = writer.WriteField(key, ensureValueString(value)); err != nil { + return r, err + } + } + } + if err = writer.Close(); err != nil { + return r, err + } + if r.Header == nil { + r.Header = make(http.Header) + } + r.Header.Set(http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType()) + r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) + r.ContentLength = int64(body.Len()) + return r, err + } + return r, err + }) + } +} + +// WithFile returns a PrepareDecorator that sends file in request body. +func WithFile(f io.ReadCloser) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + b, err := ioutil.ReadAll(f) + if err != nil { + return r, err + } + r.Body = ioutil.NopCloser(bytes.NewReader(b)) + r.ContentLength = int64(len(b)) + } + return r, err + }) + } +} + +// WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request +// and sets the Content-Length header. +func WithBool(v bool) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithFloat32 returns a PrepareDecorator that encodes the passed float32 into the body of the +// request and sets the Content-Length header. +func WithFloat32(v float32) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithFloat64 returns a PrepareDecorator that encodes the passed float64 into the body of the +// request and sets the Content-Length header. +func WithFloat64(v float64) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithInt32 returns a PrepareDecorator that encodes the passed int32 into the body of the request +// and sets the Content-Length header. +func WithInt32(v int32) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithInt64 returns a PrepareDecorator that encodes the passed int64 into the body of the request +// and sets the Content-Length header. +func WithInt64(v int64) PrepareDecorator { + return WithString(fmt.Sprintf("%v", v)) +} + +// WithString returns a PrepareDecorator that encodes the passed string into the body of the request +// and sets the Content-Length header. +func WithString(v string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + r.ContentLength = int64(len(v)) + r.Body = ioutil.NopCloser(strings.NewReader(v)) + } + return r, err + }) + } +} + +// WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the +// request and sets the Content-Length header. +func WithJSON(v interface{}) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + b, err := json.Marshal(v) + if err == nil { + r.ContentLength = int64(len(b)) + r.Body = ioutil.NopCloser(bytes.NewReader(b)) + } + } + return r, err + }) + } +} + +// WithXML returns a PrepareDecorator that encodes the data passed as XML into the body of the +// request and sets the Content-Length header. +func WithXML(v interface{}) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + b, err := xml.Marshal(v) + if err == nil { + // we have to tack on an XML header + withHeader := xml.Header + string(b) + bytesWithHeader := []byte(withHeader) + + r.ContentLength = int64(len(bytesWithHeader)) + r.Body = ioutil.NopCloser(bytes.NewReader(bytesWithHeader)) + } + } + return r, err + }) + } +} + +// WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path +// is absolute (that is, it begins with a "/"), it replaces the existing path. +func WithPath(path string) PrepareDecorator { + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.URL == nil { + return r, NewError("autorest", "WithPath", "Invoked with a nil URL") + } + if r.URL, err = parseURL(r.URL, path); err != nil { + return r, err + } + } + return r, err + }) + } +} + +// WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the +// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The +// values will be escaped (aka URL encoded) before insertion into the path. +func WithEscapedPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { + parameters := escapeValueStrings(ensureValueStrings(pathParameters)) + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.URL == nil { + return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL") + } + for key, value := range parameters { + path = strings.Replace(path, "{"+key+"}", value, -1) + } + if r.URL, err = parseURL(r.URL, path); err != nil { + return r, err + } + } + return r, err + }) + } +} + +// WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the +// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. +func WithPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { + parameters := ensureValueStrings(pathParameters) + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.URL == nil { + return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL") + } + for key, value := range parameters { + path = strings.Replace(path, "{"+key+"}", value, -1) + } + + if r.URL, err = parseURL(r.URL, path); err != nil { + return r, err + } + } + return r, err + }) + } +} + +func parseURL(u *url.URL, path string) (*url.URL, error) { + p := strings.TrimRight(u.String(), "/") + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + return url.Parse(p + path) +} + +// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters +// given in the supplied map (i.e., key=value). +func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator { + parameters := ensureValueStrings(queryParameters) + return func(p Preparer) Preparer { + return PreparerFunc(func(r *http.Request) (*http.Request, error) { + r, err := p.Prepare(r) + if err == nil { + if r.URL == nil { + return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL") + } + + v := r.URL.Query() + for key, value := range parameters { + d, err := url.QueryUnescape(value) + if err != nil { + return r, err + } + v.Add(key, d) + } + r.URL.RawQuery = v.Encode() + } + return r, err + }) + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/responder.go b/vendor/github.com/Azure/go-autorest/autorest/responder.go new file mode 100644 index 000000000..349e1963a --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/responder.go @@ -0,0 +1,269 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "net/http" + "strings" +) + +// Responder is the interface that wraps the Respond method. +// +// Respond accepts and reacts to an http.Response. Implementations must ensure to not share or hold +// state since Responders may be shared and re-used. +type Responder interface { + Respond(*http.Response) error +} + +// ResponderFunc is a method that implements the Responder interface. +type ResponderFunc func(*http.Response) error + +// Respond implements the Responder interface on ResponderFunc. +func (rf ResponderFunc) Respond(r *http.Response) error { + return rf(r) +} + +// RespondDecorator takes and possibly decorates, by wrapping, a Responder. Decorators may react to +// the http.Response and pass it along or, first, pass the http.Response along then react. +type RespondDecorator func(Responder) Responder + +// CreateResponder creates, decorates, and returns a Responder. Without decorators, the returned +// Responder returns the passed http.Response unmodified. Responders may or may not be safe to share +// and re-used: It depends on the applied decorators. For example, a standard decorator that closes +// the response body is fine to share whereas a decorator that reads the body into a passed struct +// is not. +// +// To prevent memory leaks, ensure that at least one Responder closes the response body. +func CreateResponder(decorators ...RespondDecorator) Responder { + return DecorateResponder( + Responder(ResponderFunc(func(r *http.Response) error { return nil })), + decorators...) +} + +// DecorateResponder accepts a Responder and a, possibly empty, set of RespondDecorators, which it +// applies to the Responder. Decorators are applied in the order received, but their affect upon the +// request depends on whether they are a pre-decorator (react to the http.Response and then pass it +// along) or a post-decorator (pass the http.Response along and then react). +func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder { + for _, decorate := range decorators { + r = decorate(r) + } + return r +} + +// Respond accepts an http.Response and a, possibly empty, set of RespondDecorators. +// It creates a Responder from the decorators it then applies to the passed http.Response. +func Respond(r *http.Response, decorators ...RespondDecorator) error { + if r == nil { + return nil + } + return CreateResponder(decorators...).Respond(r) +} + +// ByIgnoring returns a RespondDecorator that ignores the passed http.Response passing it unexamined +// to the next RespondDecorator. +func ByIgnoring() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + return r.Respond(resp) + }) + } +} + +// ByCopying copies the contents of the http.Response Body into the passed bytes.Buffer as +// the Body is read. +func ByCopying(b *bytes.Buffer) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil && resp != nil && resp.Body != nil { + resp.Body = TeeReadCloser(resp.Body, b) + } + return err + }) + } +} + +// ByDiscardingBody returns a RespondDecorator that first invokes the passed Responder after which +// it copies the remaining bytes (if any) in the response body to ioutil.Discard. Since the passed +// Responder is invoked prior to discarding the response body, the decorator may occur anywhere +// within the set. +func ByDiscardingBody() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil && resp != nil && resp.Body != nil { + if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil { + return fmt.Errorf("Error discarding the response body: %v", err) + } + } + return err + }) + } +} + +// ByClosing returns a RespondDecorator that first invokes the passed Responder after which it +// closes the response body. Since the passed Responder is invoked prior to closing the response +// body, the decorator may occur anywhere within the set. +func ByClosing() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if resp != nil && resp.Body != nil { + if err := resp.Body.Close(); err != nil { + return fmt.Errorf("Error closing the response body: %v", err) + } + } + return err + }) + } +} + +// ByClosingIfError returns a RespondDecorator that first invokes the passed Responder after which +// it closes the response if the passed Responder returns an error and the response body exists. +func ByClosingIfError() RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err != nil && resp != nil && resp.Body != nil { + if err := resp.Body.Close(); err != nil { + return fmt.Errorf("Error closing the response body: %v", err) + } + } + return err + }) + } +} + +// ByUnmarshallingBytes returns a RespondDecorator that copies the Bytes returned in the +// response Body into the value pointed to by v. +func ByUnmarshallingBytes(v *[]byte) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil { + bytes, errInner := ioutil.ReadAll(resp.Body) + if errInner != nil { + err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) + } else { + *v = bytes + } + } + return err + }) + } +} + +// ByUnmarshallingJSON returns a RespondDecorator that decodes a JSON document returned in the +// response Body into the value pointed to by v. +func ByUnmarshallingJSON(v interface{}) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil { + b, errInner := ioutil.ReadAll(resp.Body) + // Some responses might include a BOM, remove for successful unmarshalling + b = bytes.TrimPrefix(b, []byte("\xef\xbb\xbf")) + if errInner != nil { + err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) + } else if len(strings.Trim(string(b), " ")) > 0 { + errInner = json.Unmarshal(b, v) + if errInner != nil { + err = fmt.Errorf("Error occurred unmarshalling JSON - Error = '%v' JSON = '%s'", errInner, string(b)) + } + } + } + return err + }) + } +} + +// ByUnmarshallingXML returns a RespondDecorator that decodes a XML document returned in the +// response Body into the value pointed to by v. +func ByUnmarshallingXML(v interface{}) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil { + b, errInner := ioutil.ReadAll(resp.Body) + if errInner != nil { + err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) + } else { + errInner = xml.Unmarshal(b, v) + if errInner != nil { + err = fmt.Errorf("Error occurred unmarshalling Xml - Error = '%v' Xml = '%s'", errInner, string(b)) + } + } + } + return err + }) + } +} + +// WithErrorUnlessStatusCode returns a RespondDecorator that emits an error unless the response +// StatusCode is among the set passed. On error, response body is fully read into a buffer and +// presented in the returned error, as well as in the response body. +func WithErrorUnlessStatusCode(codes ...int) RespondDecorator { + return func(r Responder) Responder { + return ResponderFunc(func(resp *http.Response) error { + err := r.Respond(resp) + if err == nil && !ResponseHasStatusCode(resp, codes...) { + derr := NewErrorWithResponse("autorest", "WithErrorUnlessStatusCode", resp, "%v %v failed with %s", + resp.Request.Method, + resp.Request.URL, + resp.Status) + if resp.Body != nil { + defer resp.Body.Close() + b, _ := ioutil.ReadAll(resp.Body) + derr.ServiceError = b + resp.Body = ioutil.NopCloser(bytes.NewReader(b)) + } + err = derr + } + return err + }) + } +} + +// WithErrorUnlessOK returns a RespondDecorator that emits an error if the response StatusCode is +// anything other than HTTP 200. +func WithErrorUnlessOK() RespondDecorator { + return WithErrorUnlessStatusCode(http.StatusOK) +} + +// ExtractHeader extracts all values of the specified header from the http.Response. It returns an +// empty string slice if the passed http.Response is nil or the header does not exist. +func ExtractHeader(header string, resp *http.Response) []string { + if resp != nil && resp.Header != nil { + return resp.Header[http.CanonicalHeaderKey(header)] + } + return nil +} + +// ExtractHeaderValue extracts the first value of the specified header from the http.Response. It +// returns an empty string if the passed http.Response is nil or the header does not exist. +func ExtractHeaderValue(header string, resp *http.Response) string { + h := ExtractHeader(header, resp) + if len(h) > 0 { + return h[0] + } + return "" +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go new file mode 100644 index 000000000..fa11dbed7 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go @@ -0,0 +1,52 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "io" + "io/ioutil" + "net/http" +) + +// NewRetriableRequest returns a wrapper around an HTTP request that support retry logic. +func NewRetriableRequest(req *http.Request) *RetriableRequest { + return &RetriableRequest{req: req} +} + +// Request returns the wrapped HTTP request. +func (rr *RetriableRequest) Request() *http.Request { + return rr.req +} + +func (rr *RetriableRequest) prepareFromByteReader() (err error) { + // fall back to making a copy (only do this once) + b := []byte{} + if rr.req.ContentLength > 0 { + b = make([]byte, rr.req.ContentLength) + _, err = io.ReadFull(rr.req.Body, b) + if err != nil { + return err + } + } else { + b, err = ioutil.ReadAll(rr.req.Body) + if err != nil { + return err + } + } + rr.br = bytes.NewReader(b) + rr.req.Body = ioutil.NopCloser(rr.br) + return err +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go new file mode 100644 index 000000000..7143cc61b --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go @@ -0,0 +1,54 @@ +// +build !go1.8 + +// Copyright 2017 Microsoft Corporation +// +// 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. + +package autorest + +import ( + "bytes" + "io/ioutil" + "net/http" +) + +// RetriableRequest provides facilities for retrying an HTTP request. +type RetriableRequest struct { + req *http.Request + br *bytes.Reader +} + +// Prepare signals that the request is about to be sent. +func (rr *RetriableRequest) Prepare() (err error) { + // preserve the request body; this is to support retry logic as + // the underlying transport will always close the reqeust body + if rr.req.Body != nil { + if rr.br != nil { + _, err = rr.br.Seek(0, 0 /*io.SeekStart*/) + rr.req.Body = ioutil.NopCloser(rr.br) + } + if err != nil { + return err + } + if rr.br == nil { + // fall back to making a copy (only do this once) + err = rr.prepareFromByteReader() + } + } + return err +} + +func removeRequestBody(req *http.Request) { + req.Body = nil + req.ContentLength = 0 +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go new file mode 100644 index 000000000..ae15c6bf9 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go @@ -0,0 +1,66 @@ +// +build go1.8 + +// Copyright 2017 Microsoft Corporation +// +// 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. + +package autorest + +import ( + "bytes" + "io" + "io/ioutil" + "net/http" +) + +// RetriableRequest provides facilities for retrying an HTTP request. +type RetriableRequest struct { + req *http.Request + rc io.ReadCloser + br *bytes.Reader +} + +// Prepare signals that the request is about to be sent. +func (rr *RetriableRequest) Prepare() (err error) { + // preserve the request body; this is to support retry logic as + // the underlying transport will always close the reqeust body + if rr.req.Body != nil { + if rr.rc != nil { + rr.req.Body = rr.rc + } else if rr.br != nil { + _, err = rr.br.Seek(0, io.SeekStart) + rr.req.Body = ioutil.NopCloser(rr.br) + } + if err != nil { + return err + } + if rr.req.GetBody != nil { + // this will allow us to preserve the body without having to + // make a copy. note we need to do this on each iteration + rr.rc, err = rr.req.GetBody() + if err != nil { + return err + } + } else if rr.br == nil { + // fall back to making a copy (only do this once) + err = rr.prepareFromByteReader() + } + } + return err +} + +func removeRequestBody(req *http.Request) { + req.Body = nil + req.GetBody = nil + req.ContentLength = 0 +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go new file mode 100644 index 000000000..b918833fa --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/sender.go @@ -0,0 +1,382 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "context" + "fmt" + "log" + "math" + "net/http" + "strconv" + "time" + + "github.com/Azure/go-autorest/tracing" +) + +// used as a key type in context.WithValue() +type ctxSendDecorators struct{} + +// WithSendDecorators adds the specified SendDecorators to the provided context. +func WithSendDecorators(ctx context.Context, sendDecorator []SendDecorator) context.Context { + return context.WithValue(ctx, ctxSendDecorators{}, sendDecorator) +} + +// GetSendDecorators returns the SendDecorators in the provided context or the provided default SendDecorators. +func GetSendDecorators(ctx context.Context, defaultSendDecorators ...SendDecorator) []SendDecorator { + inCtx := ctx.Value(ctxSendDecorators{}) + if sd, ok := inCtx.([]SendDecorator); ok { + return sd + } + return defaultSendDecorators +} + +// Sender is the interface that wraps the Do method to send HTTP requests. +// +// The standard http.Client conforms to this interface. +type Sender interface { + Do(*http.Request) (*http.Response, error) +} + +// SenderFunc is a method that implements the Sender interface. +type SenderFunc func(*http.Request) (*http.Response, error) + +// Do implements the Sender interface on SenderFunc. +func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { + return sf(r) +} + +// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the +// http.Request and pass it along or, first, pass the http.Request along then react to the +// http.Response result. +type SendDecorator func(Sender) Sender + +// CreateSender creates, decorates, and returns, as a Sender, the default http.Client. +func CreateSender(decorators ...SendDecorator) Sender { + return DecorateSender(&http.Client{}, decorators...) +} + +// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to +// the Sender. Decorators are applied in the order received, but their affect upon the request +// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a +// post-decorator (pass the http.Request along and react to the results in http.Response). +func DecorateSender(s Sender, decorators ...SendDecorator) Sender { + for _, decorate := range decorators { + s = decorate(s) + } + return s +} + +// Send sends, by means of the default http.Client, the passed http.Request, returning the +// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which +// it will apply the http.Client before invoking the Do method. +// +// Send is a convenience method and not recommended for production. Advanced users should use +// SendWithSender, passing and sharing their own Sender (e.g., instance of http.Client). +// +// Send will not poll or retry requests. +func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error) { + return SendWithSender(&http.Client{Transport: tracing.Transport}, r, decorators...) +} + +// SendWithSender sends the passed http.Request, through the provided Sender, returning the +// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which +// it will apply the http.Client before invoking the Do method. +// +// SendWithSender will not poll or retry requests. +func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*http.Response, error) { + return DecorateSender(s, decorators...).Do(r) +} + +// AfterDelay returns a SendDecorator that delays for the passed time.Duration before +// invoking the Sender. The delay may be terminated by closing the optional channel on the +// http.Request. If canceled, no further Senders are invoked. +func AfterDelay(d time.Duration) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + if !DelayForBackoff(d, 0, r.Context().Done()) { + return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay") + } + return s.Do(r) + }) + } +} + +// AsIs returns a SendDecorator that invokes the passed Sender without modifying the http.Request. +func AsIs() SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + return s.Do(r) + }) + } +} + +// DoCloseIfError returns a SendDecorator that first invokes the passed Sender after which +// it closes the response if the passed Sender returns an error and the response body exists. +func DoCloseIfError() SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + resp, err := s.Do(r) + if err != nil { + Respond(resp, ByDiscardingBody(), ByClosing()) + } + return resp, err + }) + } +} + +// DoErrorIfStatusCode returns a SendDecorator that emits an error if the response StatusCode is +// among the set passed. Since these are artificial errors, the response body may still require +// closing. +func DoErrorIfStatusCode(codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + resp, err := s.Do(r) + if err == nil && ResponseHasStatusCode(resp, codes...) { + err = NewErrorWithResponse("autorest", "DoErrorIfStatusCode", resp, "%v %v failed with %s", + resp.Request.Method, + resp.Request.URL, + resp.Status) + } + return resp, err + }) + } +} + +// DoErrorUnlessStatusCode returns a SendDecorator that emits an error unless the response +// StatusCode is among the set passed. Since these are artificial errors, the response body +// may still require closing. +func DoErrorUnlessStatusCode(codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + resp, err := s.Do(r) + if err == nil && !ResponseHasStatusCode(resp, codes...) { + err = NewErrorWithResponse("autorest", "DoErrorUnlessStatusCode", resp, "%v %v failed with %s", + resp.Request.Method, + resp.Request.URL, + resp.Status) + } + return resp, err + }) + } +} + +// DoPollForStatusCodes returns a SendDecorator that polls if the http.Response contains one of the +// passed status codes. It expects the http.Response to contain a Location header providing the +// URL at which to poll (using GET) and will poll until the time passed is equal to or greater than +// the supplied duration. It will delay between requests for the duration specified in the +// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by +// closing the optional channel on the http.Request. +func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + resp, err = s.Do(r) + + if err == nil && ResponseHasStatusCode(resp, codes...) { + r, err = NewPollingRequestWithContext(r.Context(), resp) + + for err == nil && ResponseHasStatusCode(resp, codes...) { + Respond(resp, + ByDiscardingBody(), + ByClosing()) + resp, err = SendWithSender(s, r, + AfterDelay(GetRetryAfter(resp, delay))) + } + } + + return resp, err + }) + } +} + +// DoRetryForAttempts returns a SendDecorator that retries a failed request for up to the specified +// number of attempts, exponentially backing off between requests using the supplied backoff +// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on +// the http.Request. +func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + rr := NewRetriableRequest(r) + for attempt := 0; attempt < attempts; attempt++ { + err = rr.Prepare() + if err != nil { + return resp, err + } + resp, err = s.Do(rr.Request()) + if err == nil { + return resp, err + } + if !DelayForBackoff(backoff, attempt, r.Context().Done()) { + return nil, r.Context().Err() + } + } + return resp, err + }) + } +} + +// DoRetryForStatusCodes returns a SendDecorator that retries for specified statusCodes for up to the specified +// number of attempts, exponentially backing off between requests using the supplied backoff +// time.Duration (which may be zero). Retrying may be canceled by cancelling the context on the http.Request. +// NOTE: Code http.StatusTooManyRequests (429) will *not* be counted against the number of attempts. +func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + return doRetryForStatusCodesImpl(s, r, false, attempts, backoff, 0, codes...) + }) + } +} + +// DoRetryForStatusCodesWithCap returns a SendDecorator that retries for specified statusCodes for up to the +// specified number of attempts, exponentially backing off between requests using the supplied backoff +// time.Duration (which may be zero). To cap the maximum possible delay between iterations specify a value greater +// than zero for cap. Retrying may be canceled by cancelling the context on the http.Request. +func DoRetryForStatusCodesWithCap(attempts int, backoff, cap time.Duration, codes ...int) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + return doRetryForStatusCodesImpl(s, r, true, attempts, backoff, cap, codes...) + }) + } +} + +func doRetryForStatusCodesImpl(s Sender, r *http.Request, count429 bool, attempts int, backoff, cap time.Duration, codes ...int) (resp *http.Response, err error) { + rr := NewRetriableRequest(r) + // Increment to add the first call (attempts denotes number of retries) + for attempt := 0; attempt < attempts+1; { + err = rr.Prepare() + if err != nil { + return + } + resp, err = s.Do(rr.Request()) + // if the error isn't temporary don't bother retrying + if err != nil && !IsTemporaryNetworkError(err) { + return + } + // we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication + // resp and err will both have a value, so in this case we don't want to retry as it will never succeed. + if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) { + return resp, err + } + delayed := DelayWithRetryAfter(resp, r.Context().Done()) + if !delayed && !DelayForBackoffWithCap(backoff, cap, attempt, r.Context().Done()) { + return resp, r.Context().Err() + } + // when count429 == false don't count a 429 against the number + // of attempts so that we continue to retry until it succeeds + if count429 || (resp == nil || resp.StatusCode != http.StatusTooManyRequests) { + attempt++ + } + } + return resp, err +} + +// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header. +// The value of Retry-After can be either the number of seconds or a date in RFC1123 format. +// The function returns true after successfully waiting for the specified duration. If there is +// no Retry-After header or the wait is cancelled the return value is false. +func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool { + if resp == nil { + return false + } + var dur time.Duration + ra := resp.Header.Get("Retry-After") + if retryAfter, _ := strconv.Atoi(ra); retryAfter > 0 { + dur = time.Duration(retryAfter) * time.Second + } else if t, err := time.Parse(time.RFC1123, ra); err == nil { + dur = t.Sub(time.Now()) + } + if dur > 0 { + select { + case <-time.After(dur): + return true + case <-cancel: + return false + } + } + return false +} + +// DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal +// to or greater than the specified duration, exponentially backing off between requests using the +// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the +// optional channel on the http.Request. +func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { + rr := NewRetriableRequest(r) + end := time.Now().Add(d) + for attempt := 0; time.Now().Before(end); attempt++ { + err = rr.Prepare() + if err != nil { + return resp, err + } + resp, err = s.Do(rr.Request()) + if err == nil { + return resp, err + } + if !DelayForBackoff(backoff, attempt, r.Context().Done()) { + return nil, r.Context().Err() + } + } + return resp, err + }) + } +} + +// WithLogging returns a SendDecorator that implements simple before and after logging of the +// request. +func WithLogging(logger *log.Logger) SendDecorator { + return func(s Sender) Sender { + return SenderFunc(func(r *http.Request) (*http.Response, error) { + logger.Printf("Sending %s %s", r.Method, r.URL) + resp, err := s.Do(r) + if err != nil { + logger.Printf("%s %s received error '%v'", r.Method, r.URL, err) + } else { + logger.Printf("%s %s received %s", r.Method, r.URL, resp.Status) + } + return resp, err + }) + } +} + +// DelayForBackoff invokes time.After for the supplied backoff duration raised to the power of +// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set +// to zero for no delay. The delay may be canceled by closing the passed channel. If terminated early, +// returns false. +// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt +// count. +func DelayForBackoff(backoff time.Duration, attempt int, cancel <-chan struct{}) bool { + return DelayForBackoffWithCap(backoff, 0, attempt, cancel) +} + +// DelayForBackoffWithCap invokes time.After for the supplied backoff duration raised to the power of +// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set +// to zero for no delay. To cap the maximum possible delay specify a value greater than zero for cap. +// The delay may be canceled by closing the passed channel. If terminated early, returns false. +// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt +// count. +func DelayForBackoffWithCap(backoff, cap time.Duration, attempt int, cancel <-chan struct{}) bool { + d := time.Duration(backoff.Seconds()*math.Pow(2, float64(attempt))) * time.Second + if cap > 0 && d > cap { + d = cap + } + select { + case <-time.After(d): + return true + case <-cancel: + return false + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/to/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/to/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/convert.go b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go new file mode 100644 index 000000000..86694bd25 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go @@ -0,0 +1,152 @@ +/* +Package to provides helpers to ease working with pointer values of marshalled structures. +*/ +package to + +// Copyright 2017 Microsoft Corporation +// +// 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. + +// String returns a string value for the passed string pointer. It returns the empty string if the +// pointer is nil. +func String(s *string) string { + if s != nil { + return *s + } + return "" +} + +// StringPtr returns a pointer to the passed string. +func StringPtr(s string) *string { + return &s +} + +// StringSlice returns a string slice value for the passed string slice pointer. It returns a nil +// slice if the pointer is nil. +func StringSlice(s *[]string) []string { + if s != nil { + return *s + } + return nil +} + +// StringSlicePtr returns a pointer to the passed string slice. +func StringSlicePtr(s []string) *[]string { + return &s +} + +// StringMap returns a map of strings built from the map of string pointers. The empty string is +// used for nil pointers. +func StringMap(msp map[string]*string) map[string]string { + ms := make(map[string]string, len(msp)) + for k, sp := range msp { + if sp != nil { + ms[k] = *sp + } else { + ms[k] = "" + } + } + return ms +} + +// StringMapPtr returns a pointer to a map of string pointers built from the passed map of strings. +func StringMapPtr(ms map[string]string) *map[string]*string { + msp := make(map[string]*string, len(ms)) + for k, s := range ms { + msp[k] = StringPtr(s) + } + return &msp +} + +// Bool returns a bool value for the passed bool pointer. It returns false if the pointer is nil. +func Bool(b *bool) bool { + if b != nil { + return *b + } + return false +} + +// BoolPtr returns a pointer to the passed bool. +func BoolPtr(b bool) *bool { + return &b +} + +// Int returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int(i *int) int { + if i != nil { + return *i + } + return 0 +} + +// IntPtr returns a pointer to the passed int. +func IntPtr(i int) *int { + return &i +} + +// Int32 returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int32(i *int32) int32 { + if i != nil { + return *i + } + return 0 +} + +// Int32Ptr returns a pointer to the passed int32. +func Int32Ptr(i int32) *int32 { + return &i +} + +// Int64 returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int64(i *int64) int64 { + if i != nil { + return *i + } + return 0 +} + +// Int64Ptr returns a pointer to the passed int64. +func Int64Ptr(i int64) *int64 { + return &i +} + +// Float32 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. +func Float32(i *float32) float32 { + if i != nil { + return *i + } + return 0.0 +} + +// Float32Ptr returns a pointer to the passed float32. +func Float32Ptr(i float32) *float32 { + return &i +} + +// Float64 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. +func Float64(i *float64) float64 { + if i != nil { + return *i + } + return 0.0 +} + +// Float64Ptr returns a pointer to the passed float64. +func Float64Ptr(i float64) *float64 { + return &i +} + +// ByteSlicePtr returns a pointer to the passed byte slice. +func ByteSlicePtr(b []byte) *[]byte { + return &b +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/go.mod b/vendor/github.com/Azure/go-autorest/autorest/to/go.mod new file mode 100644 index 000000000..a2054be36 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/to/go.mod @@ -0,0 +1,3 @@ +module github.com/Azure/go-autorest/autorest/to + +go 1.12 diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go new file mode 100644 index 000000000..08cf11c11 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/utility.go @@ -0,0 +1,228 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "net" + "net/http" + "net/url" + "reflect" + "strings" + + "github.com/Azure/go-autorest/autorest/adal" +) + +// EncodedAs is a series of constants specifying various data encodings +type EncodedAs string + +const ( + // EncodedAsJSON states that data is encoded as JSON + EncodedAsJSON EncodedAs = "JSON" + + // EncodedAsXML states that data is encoded as Xml + EncodedAsXML EncodedAs = "XML" +) + +// Decoder defines the decoding method json.Decoder and xml.Decoder share +type Decoder interface { + Decode(v interface{}) error +} + +// NewDecoder creates a new decoder appropriate to the passed encoding. +// encodedAs specifies the type of encoding and r supplies the io.Reader containing the +// encoded data. +func NewDecoder(encodedAs EncodedAs, r io.Reader) Decoder { + if encodedAs == EncodedAsJSON { + return json.NewDecoder(r) + } else if encodedAs == EncodedAsXML { + return xml.NewDecoder(r) + } + return nil +} + +// CopyAndDecode decodes the data from the passed io.Reader while making a copy. Having a copy +// is especially useful if there is a chance the data will fail to decode. +// encodedAs specifies the expected encoding, r provides the io.Reader to the data, and v +// is the decoding destination. +func CopyAndDecode(encodedAs EncodedAs, r io.Reader, v interface{}) (bytes.Buffer, error) { + b := bytes.Buffer{} + return b, NewDecoder(encodedAs, io.TeeReader(r, &b)).Decode(v) +} + +// TeeReadCloser returns a ReadCloser that writes to w what it reads from rc. +// It utilizes io.TeeReader to copy the data read and has the same behavior when reading. +// Further, when it is closed, it ensures that rc is closed as well. +func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser { + return &teeReadCloser{rc, io.TeeReader(rc, w)} +} + +type teeReadCloser struct { + rc io.ReadCloser + r io.Reader +} + +func (t *teeReadCloser) Read(p []byte) (int, error) { + return t.r.Read(p) +} + +func (t *teeReadCloser) Close() error { + return t.rc.Close() +} + +func containsInt(ints []int, n int) bool { + for _, i := range ints { + if i == n { + return true + } + } + return false +} + +func escapeValueStrings(m map[string]string) map[string]string { + for key, value := range m { + m[key] = url.QueryEscape(value) + } + return m +} + +func ensureValueStrings(mapOfInterface map[string]interface{}) map[string]string { + mapOfStrings := make(map[string]string) + for key, value := range mapOfInterface { + mapOfStrings[key] = ensureValueString(value) + } + return mapOfStrings +} + +func ensureValueString(value interface{}) string { + if value == nil { + return "" + } + switch v := value.(type) { + case string: + return v + case []byte: + return string(v) + default: + return fmt.Sprintf("%v", v) + } +} + +// MapToValues method converts map[string]interface{} to url.Values. +func MapToValues(m map[string]interface{}) url.Values { + v := url.Values{} + for key, value := range m { + x := reflect.ValueOf(value) + if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { + for i := 0; i < x.Len(); i++ { + v.Add(key, ensureValueString(x.Index(i))) + } + } else { + v.Add(key, ensureValueString(value)) + } + } + return v +} + +// AsStringSlice method converts interface{} to []string. This expects a +//that the parameter passed to be a slice or array of a type that has the underlying +//type a string. +func AsStringSlice(s interface{}) ([]string, error) { + v := reflect.ValueOf(s) + if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { + return nil, NewError("autorest", "AsStringSlice", "the value's type is not an array.") + } + stringSlice := make([]string, 0, v.Len()) + + for i := 0; i < v.Len(); i++ { + stringSlice = append(stringSlice, v.Index(i).String()) + } + return stringSlice, nil +} + +// String method converts interface v to string. If interface is a list, it +// joins list elements using the separator. Note that only sep[0] will be used for +// joining if any separator is specified. +func String(v interface{}, sep ...string) string { + if len(sep) == 0 { + return ensureValueString(v) + } + stringSlice, ok := v.([]string) + if ok == false { + var err error + stringSlice, err = AsStringSlice(v) + if err != nil { + panic(fmt.Sprintf("autorest: Couldn't convert value to a string %s.", err)) + } + } + return ensureValueString(strings.Join(stringSlice, sep[0])) +} + +// Encode method encodes url path and query parameters. +func Encode(location string, v interface{}, sep ...string) string { + s := String(v, sep...) + switch strings.ToLower(location) { + case "path": + return pathEscape(s) + case "query": + return queryEscape(s) + default: + return s + } +} + +func pathEscape(s string) string { + return strings.Replace(url.QueryEscape(s), "+", "%20", -1) +} + +func queryEscape(s string) string { + return url.QueryEscape(s) +} + +// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't). +// This is mainly useful for long-running operations that use the Azure-AsyncOperation +// header, so we change the initial PUT into a GET to retrieve the final result. +func ChangeToGet(req *http.Request) *http.Request { + req.Method = "GET" + req.Body = nil + req.ContentLength = 0 + req.Header.Del("Content-Length") + return req +} + +// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError +// interface. If err is a DetailedError it will walk the chain of Original errors. +func IsTokenRefreshError(err error) bool { + if _, ok := err.(adal.TokenRefreshError); ok { + return true + } + if de, ok := err.(DetailedError); ok { + return IsTokenRefreshError(de.Original) + } + return false +} + +// IsTemporaryNetworkError returns true if the specified error is a temporary network error or false +// if it's not. If the error doesn't implement the net.Error interface the return value is true. +func IsTemporaryNetworkError(err error) bool { + if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) { + return true + } + return false +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/validation/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/validation/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/validation/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/autorest/validation/error.go b/vendor/github.com/Azure/go-autorest/autorest/validation/error.go new file mode 100644 index 000000000..fed156dbf --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/validation/error.go @@ -0,0 +1,48 @@ +package validation + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "fmt" +) + +// Error is the type that's returned when the validation of an APIs arguments constraints fails. +type Error struct { + // PackageType is the package type of the object emitting the error. For types, the value + // matches that produced the the '%T' format specifier of the fmt package. For other elements, + // such as functions, it is just the package name (e.g., "autorest"). + PackageType string + + // Method is the name of the method raising the error. + Method string + + // Message is the error message. + Message string +} + +// Error returns a string containing the details of the validation failure. +func (e Error) Error() string { + return fmt.Sprintf("%s#%s: Invalid input: %s", e.PackageType, e.Method, e.Message) +} + +// NewError creates a new Error object with the specified parameters. +// message is treated as a format string to which the optional args apply. +func NewError(packageType string, method string, message string, args ...interface{}) Error { + return Error{ + PackageType: packageType, + Method: method, + Message: fmt.Sprintf(message, args...), + } +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/validation/go.mod b/vendor/github.com/Azure/go-autorest/autorest/validation/go.mod new file mode 100644 index 000000000..c44c51ff6 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/validation/go.mod @@ -0,0 +1,5 @@ +module github.com/Azure/go-autorest/autorest/validation + +go 1.12 + +require github.com/stretchr/testify v1.3.0 diff --git a/vendor/github.com/Azure/go-autorest/autorest/validation/go.sum b/vendor/github.com/Azure/go-autorest/autorest/validation/go.sum new file mode 100644 index 000000000..4347755af --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/validation/go.sum @@ -0,0 +1,7 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go b/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go new file mode 100644 index 000000000..65899b69b --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/validation/validation.go @@ -0,0 +1,400 @@ +/* +Package validation provides methods for validating parameter value using reflection. +*/ +package validation + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "fmt" + "reflect" + "regexp" + "strings" +) + +// Constraint stores constraint name, target field name +// Rule and chain validations. +type Constraint struct { + + // Target field name for validation. + Target string + + // Constraint name e.g. minLength, MaxLength, Pattern, etc. + Name string + + // Rule for constraint e.g. greater than 10, less than 5 etc. + Rule interface{} + + // Chain Validations for struct type + Chain []Constraint +} + +// Validation stores parameter-wise validation. +type Validation struct { + TargetValue interface{} + Constraints []Constraint +} + +// Constraint list +const ( + Empty = "Empty" + Null = "Null" + ReadOnly = "ReadOnly" + Pattern = "Pattern" + MaxLength = "MaxLength" + MinLength = "MinLength" + MaxItems = "MaxItems" + MinItems = "MinItems" + MultipleOf = "MultipleOf" + UniqueItems = "UniqueItems" + InclusiveMaximum = "InclusiveMaximum" + ExclusiveMaximum = "ExclusiveMaximum" + ExclusiveMinimum = "ExclusiveMinimum" + InclusiveMinimum = "InclusiveMinimum" +) + +// Validate method validates constraints on parameter +// passed in validation array. +func Validate(m []Validation) error { + for _, item := range m { + v := reflect.ValueOf(item.TargetValue) + for _, constraint := range item.Constraints { + var err error + switch v.Kind() { + case reflect.Ptr: + err = validatePtr(v, constraint) + case reflect.String: + err = validateString(v, constraint) + case reflect.Struct: + err = validateStruct(v, constraint) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + err = validateInt(v, constraint) + case reflect.Float32, reflect.Float64: + err = validateFloat(v, constraint) + case reflect.Array, reflect.Slice, reflect.Map: + err = validateArrayMap(v, constraint) + default: + err = createError(v, constraint, fmt.Sprintf("unknown type %v", v.Kind())) + } + + if err != nil { + return err + } + } + } + return nil +} + +func validateStruct(x reflect.Value, v Constraint, name ...string) error { + //Get field name from target name which is in format a.b.c + s := strings.Split(v.Target, ".") + f := x.FieldByName(s[len(s)-1]) + if isZero(f) { + return createError(x, v, fmt.Sprintf("field %q doesn't exist", v.Target)) + } + + return Validate([]Validation{ + { + TargetValue: getInterfaceValue(f), + Constraints: []Constraint{v}, + }, + }) +} + +func validatePtr(x reflect.Value, v Constraint) error { + if v.Name == ReadOnly { + if !x.IsNil() { + return createError(x.Elem(), v, "readonly parameter; must send as nil or empty in request") + } + return nil + } + if x.IsNil() { + return checkNil(x, v) + } + if v.Chain != nil { + return Validate([]Validation{ + { + TargetValue: getInterfaceValue(x.Elem()), + Constraints: v.Chain, + }, + }) + } + return nil +} + +func validateInt(x reflect.Value, v Constraint) error { + i := x.Int() + r, ok := toInt64(v.Rule) + if !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule)) + } + switch v.Name { + case MultipleOf: + if i%r != 0 { + return createError(x, v, fmt.Sprintf("value must be a multiple of %v", r)) + } + case ExclusiveMinimum: + if i <= r { + return createError(x, v, fmt.Sprintf("value must be greater than %v", r)) + } + case ExclusiveMaximum: + if i >= r { + return createError(x, v, fmt.Sprintf("value must be less than %v", r)) + } + case InclusiveMinimum: + if i < r { + return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r)) + } + case InclusiveMaximum: + if i > r { + return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r)) + } + default: + return createError(x, v, fmt.Sprintf("constraint %v is not applicable for type integer", v.Name)) + } + return nil +} + +func validateFloat(x reflect.Value, v Constraint) error { + f := x.Float() + r, ok := v.Rule.(float64) + if !ok { + return createError(x, v, fmt.Sprintf("rule must be float value for %v constraint; got: %v", v.Name, v.Rule)) + } + switch v.Name { + case ExclusiveMinimum: + if f <= r { + return createError(x, v, fmt.Sprintf("value must be greater than %v", r)) + } + case ExclusiveMaximum: + if f >= r { + return createError(x, v, fmt.Sprintf("value must be less than %v", r)) + } + case InclusiveMinimum: + if f < r { + return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r)) + } + case InclusiveMaximum: + if f > r { + return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r)) + } + default: + return createError(x, v, fmt.Sprintf("constraint %s is not applicable for type float", v.Name)) + } + return nil +} + +func validateString(x reflect.Value, v Constraint) error { + s := x.String() + switch v.Name { + case Empty: + if len(s) == 0 { + return checkEmpty(x, v) + } + case Pattern: + reg, err := regexp.Compile(v.Rule.(string)) + if err != nil { + return createError(x, v, err.Error()) + } + if !reg.MatchString(s) { + return createError(x, v, fmt.Sprintf("value doesn't match pattern %v", v.Rule)) + } + case MaxLength: + if _, ok := v.Rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule)) + } + if len(s) > v.Rule.(int) { + return createError(x, v, fmt.Sprintf("value length must be less than or equal to %v", v.Rule)) + } + case MinLength: + if _, ok := v.Rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule)) + } + if len(s) < v.Rule.(int) { + return createError(x, v, fmt.Sprintf("value length must be greater than or equal to %v", v.Rule)) + } + case ReadOnly: + if len(s) > 0 { + return createError(reflect.ValueOf(s), v, "readonly parameter; must send as nil or empty in request") + } + default: + return createError(x, v, fmt.Sprintf("constraint %s is not applicable to string type", v.Name)) + } + + if v.Chain != nil { + return Validate([]Validation{ + { + TargetValue: getInterfaceValue(x), + Constraints: v.Chain, + }, + }) + } + return nil +} + +func validateArrayMap(x reflect.Value, v Constraint) error { + switch v.Name { + case Null: + if x.IsNil() { + return checkNil(x, v) + } + case Empty: + if x.IsNil() || x.Len() == 0 { + return checkEmpty(x, v) + } + case MaxItems: + if _, ok := v.Rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.Name, v.Rule)) + } + if x.Len() > v.Rule.(int) { + return createError(x, v, fmt.Sprintf("maximum item limit is %v; got: %v", v.Rule, x.Len())) + } + case MinItems: + if _, ok := v.Rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.Name, v.Rule)) + } + if x.Len() < v.Rule.(int) { + return createError(x, v, fmt.Sprintf("minimum item limit is %v; got: %v", v.Rule, x.Len())) + } + case UniqueItems: + if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { + if !checkForUniqueInArray(x) { + return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.Target, x)) + } + } else if x.Kind() == reflect.Map { + if !checkForUniqueInMap(x) { + return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.Target, x)) + } + } else { + return createError(x, v, fmt.Sprintf("type must be array, slice or map for constraint %v; got: %v", v.Name, x.Kind())) + } + case ReadOnly: + if x.Len() != 0 { + return createError(x, v, "readonly parameter; must send as nil or empty in request") + } + case Pattern: + reg, err := regexp.Compile(v.Rule.(string)) + if err != nil { + return createError(x, v, err.Error()) + } + keys := x.MapKeys() + for _, k := range keys { + if !reg.MatchString(k.String()) { + return createError(k, v, fmt.Sprintf("map key doesn't match pattern %v", v.Rule)) + } + } + default: + return createError(x, v, fmt.Sprintf("constraint %v is not applicable to array, slice and map type", v.Name)) + } + + if v.Chain != nil { + return Validate([]Validation{ + { + TargetValue: getInterfaceValue(x), + Constraints: v.Chain, + }, + }) + } + return nil +} + +func checkNil(x reflect.Value, v Constraint) error { + if _, ok := v.Rule.(bool); !ok { + return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.Name, v.Rule)) + } + if v.Rule.(bool) { + return createError(x, v, "value can not be null; required parameter") + } + return nil +} + +func checkEmpty(x reflect.Value, v Constraint) error { + if _, ok := v.Rule.(bool); !ok { + return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.Name, v.Rule)) + } + + if v.Rule.(bool) { + return createError(x, v, "value can not be null or empty; required parameter") + } + return nil +} + +func checkForUniqueInArray(x reflect.Value) bool { + if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 { + return false + } + arrOfInterface := make([]interface{}, x.Len()) + + for i := 0; i < x.Len(); i++ { + arrOfInterface[i] = x.Index(i).Interface() + } + + m := make(map[interface{}]bool) + for _, val := range arrOfInterface { + if m[val] { + return false + } + m[val] = true + } + return true +} + +func checkForUniqueInMap(x reflect.Value) bool { + if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 { + return false + } + mapOfInterface := make(map[interface{}]interface{}, x.Len()) + + keys := x.MapKeys() + for _, k := range keys { + mapOfInterface[k.Interface()] = x.MapIndex(k).Interface() + } + + m := make(map[interface{}]bool) + for _, val := range mapOfInterface { + if m[val] { + return false + } + m[val] = true + } + return true +} + +func getInterfaceValue(x reflect.Value) interface{} { + if x.Kind() == reflect.Invalid { + return nil + } + return x.Interface() +} + +func isZero(x interface{}) bool { + return x == reflect.Zero(reflect.TypeOf(x)).Interface() +} + +func createError(x reflect.Value, v Constraint, err string) error { + return fmt.Errorf("autorest/validation: validation failed: parameter=%s constraint=%s value=%#v details: %s", + v.Target, v.Name, getInterfaceValue(x), err) +} + +func toInt64(v interface{}) (int64, bool) { + if i64, ok := v.(int64); ok { + return i64, true + } + // older generators emit max constants as int, so if int64 fails fall back to int + if i32, ok := v.(int); ok { + return int64(i32), true + } + return 0, false +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/version.go b/vendor/github.com/Azure/go-autorest/autorest/version.go new file mode 100644 index 000000000..ec7e84817 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/version.go @@ -0,0 +1,41 @@ +package autorest + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "fmt" + "runtime" +) + +const number = "v12.3.0" + +var ( + userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s", + runtime.Version(), + runtime.GOARCH, + runtime.GOOS, + number, + ) +) + +// UserAgent returns a string containing the Go version, system architecture and OS, and the go-autorest version. +func UserAgent() string { + return userAgent +} + +// Version returns the semantic version (see http://semver.org). +func Version() string { + return number +} diff --git a/vendor/github.com/Azure/go-autorest/logger/LICENSE b/vendor/github.com/Azure/go-autorest/logger/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/logger/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/logger/go.mod b/vendor/github.com/Azure/go-autorest/logger/go.mod new file mode 100644 index 000000000..f22ed56bc --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/logger/go.mod @@ -0,0 +1,3 @@ +module github.com/Azure/go-autorest/logger + +go 1.12 diff --git a/vendor/github.com/Azure/go-autorest/logger/logger.go b/vendor/github.com/Azure/go-autorest/logger/logger.go new file mode 100644 index 000000000..da09f394c --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/logger/logger.go @@ -0,0 +1,328 @@ +package logger + +// Copyright 2017 Microsoft Corporation +// +// 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. + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + "strings" + "sync" + "time" +) + +// LevelType tells a logger the minimum level to log. When code reports a log entry, +// the LogLevel indicates the level of the log entry. The logger only records entries +// whose level is at least the level it was told to log. See the Log* constants. +// For example, if a logger is configured with LogError, then LogError, LogPanic, +// and LogFatal entries will be logged; lower level entries are ignored. +type LevelType uint32 + +const ( + // LogNone tells a logger not to log any entries passed to it. + LogNone LevelType = iota + + // LogFatal tells a logger to log all LogFatal entries passed to it. + LogFatal + + // LogPanic tells a logger to log all LogPanic and LogFatal entries passed to it. + LogPanic + + // LogError tells a logger to log all LogError, LogPanic and LogFatal entries passed to it. + LogError + + // LogWarning tells a logger to log all LogWarning, LogError, LogPanic and LogFatal entries passed to it. + LogWarning + + // LogInfo tells a logger to log all LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it. + LogInfo + + // LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it. + LogDebug +) + +const ( + logNone = "NONE" + logFatal = "FATAL" + logPanic = "PANIC" + logError = "ERROR" + logWarning = "WARNING" + logInfo = "INFO" + logDebug = "DEBUG" + logUnknown = "UNKNOWN" +) + +// ParseLevel converts the specified string into the corresponding LevelType. +func ParseLevel(s string) (lt LevelType, err error) { + switch strings.ToUpper(s) { + case logFatal: + lt = LogFatal + case logPanic: + lt = LogPanic + case logError: + lt = LogError + case logWarning: + lt = LogWarning + case logInfo: + lt = LogInfo + case logDebug: + lt = LogDebug + default: + err = fmt.Errorf("bad log level '%s'", s) + } + return +} + +// String implements the stringer interface for LevelType. +func (lt LevelType) String() string { + switch lt { + case LogNone: + return logNone + case LogFatal: + return logFatal + case LogPanic: + return logPanic + case LogError: + return logError + case LogWarning: + return logWarning + case LogInfo: + return logInfo + case LogDebug: + return logDebug + default: + return logUnknown + } +} + +// Filter defines functions for filtering HTTP request/response content. +type Filter struct { + // URL returns a potentially modified string representation of a request URL. + URL func(u *url.URL) string + + // Header returns a potentially modified set of values for the specified key. + // To completely exclude the header key/values return false. + Header func(key string, val []string) (bool, []string) + + // Body returns a potentially modified request/response body. + Body func(b []byte) []byte +} + +func (f Filter) processURL(u *url.URL) string { + if f.URL == nil { + return u.String() + } + return f.URL(u) +} + +func (f Filter) processHeader(k string, val []string) (bool, []string) { + if f.Header == nil { + return true, val + } + return f.Header(k, val) +} + +func (f Filter) processBody(b []byte) []byte { + if f.Body == nil { + return b + } + return f.Body(b) +} + +// Writer defines methods for writing to a logging facility. +type Writer interface { + // Writeln writes the specified message with the standard log entry header and new-line character. + Writeln(level LevelType, message string) + + // Writef writes the specified format specifier with the standard log entry header and no new-line character. + Writef(level LevelType, format string, a ...interface{}) + + // WriteRequest writes the specified HTTP request to the logger if the log level is greater than + // or equal to LogInfo. The request body, if set, is logged at level LogDebug or higher. + // Custom filters can be specified to exclude URL, header, and/or body content from the log. + // By default no request content is excluded. + WriteRequest(req *http.Request, filter Filter) + + // WriteResponse writes the specified HTTP response to the logger if the log level is greater than + // or equal to LogInfo. The response body, if set, is logged at level LogDebug or higher. + // Custom filters can be specified to exclude URL, header, and/or body content from the log. + // By default no response content is excluded. + WriteResponse(resp *http.Response, filter Filter) +} + +// Instance is the default log writer initialized during package init. +// This can be replaced with a custom implementation as required. +var Instance Writer + +// default log level +var logLevel = LogNone + +// Level returns the value specified in AZURE_GO_AUTOREST_LOG_LEVEL. +// If no value was specified the default value is LogNone. +// Custom loggers can call this to retrieve the configured log level. +func Level() LevelType { + return logLevel +} + +func init() { + // separated for testing purposes + initDefaultLogger() +} + +func initDefaultLogger() { + // init with nilLogger so callers don't have to do a nil check on Default + Instance = nilLogger{} + llStr := strings.ToLower(os.Getenv("AZURE_GO_SDK_LOG_LEVEL")) + if llStr == "" { + return + } + var err error + logLevel, err = ParseLevel(llStr) + if err != nil { + fmt.Fprintf(os.Stderr, "go-autorest: failed to parse log level: %s\n", err.Error()) + return + } + if logLevel == LogNone { + return + } + // default to stderr + dest := os.Stderr + lfStr := os.Getenv("AZURE_GO_SDK_LOG_FILE") + if strings.EqualFold(lfStr, "stdout") { + dest = os.Stdout + } else if lfStr != "" { + lf, err := os.Create(lfStr) + if err == nil { + dest = lf + } else { + fmt.Fprintf(os.Stderr, "go-autorest: failed to create log file, using stderr: %s\n", err.Error()) + } + } + Instance = fileLogger{ + logLevel: logLevel, + mu: &sync.Mutex{}, + logFile: dest, + } +} + +// the nil logger does nothing +type nilLogger struct{} + +func (nilLogger) Writeln(LevelType, string) {} + +func (nilLogger) Writef(LevelType, string, ...interface{}) {} + +func (nilLogger) WriteRequest(*http.Request, Filter) {} + +func (nilLogger) WriteResponse(*http.Response, Filter) {} + +// A File is used instead of a Logger so the stream can be flushed after every write. +type fileLogger struct { + logLevel LevelType + mu *sync.Mutex // for synchronizing writes to logFile + logFile *os.File +} + +func (fl fileLogger) Writeln(level LevelType, message string) { + fl.Writef(level, "%s\n", message) +} + +func (fl fileLogger) Writef(level LevelType, format string, a ...interface{}) { + if fl.logLevel >= level { + fl.mu.Lock() + defer fl.mu.Unlock() + fmt.Fprintf(fl.logFile, "%s %s", entryHeader(level), fmt.Sprintf(format, a...)) + fl.logFile.Sync() + } +} + +func (fl fileLogger) WriteRequest(req *http.Request, filter Filter) { + if req == nil || fl.logLevel < LogInfo { + return + } + b := &bytes.Buffer{} + fmt.Fprintf(b, "%s REQUEST: %s %s\n", entryHeader(LogInfo), req.Method, filter.processURL(req.URL)) + // dump headers + for k, v := range req.Header { + if ok, mv := filter.processHeader(k, v); ok { + fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ",")) + } + } + if fl.shouldLogBody(req.Header, req.Body) { + // dump body + body, err := ioutil.ReadAll(req.Body) + if err == nil { + fmt.Fprintln(b, string(filter.processBody(body))) + if nc, ok := req.Body.(io.Seeker); ok { + // rewind to the beginning + nc.Seek(0, io.SeekStart) + } else { + // recreate the body + req.Body = ioutil.NopCloser(bytes.NewReader(body)) + } + } else { + fmt.Fprintf(b, "failed to read body: %v\n", err) + } + } + fl.mu.Lock() + defer fl.mu.Unlock() + fmt.Fprint(fl.logFile, b.String()) + fl.logFile.Sync() +} + +func (fl fileLogger) WriteResponse(resp *http.Response, filter Filter) { + if resp == nil || fl.logLevel < LogInfo { + return + } + b := &bytes.Buffer{} + fmt.Fprintf(b, "%s RESPONSE: %d %s\n", entryHeader(LogInfo), resp.StatusCode, filter.processURL(resp.Request.URL)) + // dump headers + for k, v := range resp.Header { + if ok, mv := filter.processHeader(k, v); ok { + fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ",")) + } + } + if fl.shouldLogBody(resp.Header, resp.Body) { + // dump body + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err == nil { + fmt.Fprintln(b, string(filter.processBody(body))) + resp.Body = ioutil.NopCloser(bytes.NewReader(body)) + } else { + fmt.Fprintf(b, "failed to read body: %v\n", err) + } + } + fl.mu.Lock() + defer fl.mu.Unlock() + fmt.Fprint(fl.logFile, b.String()) + fl.logFile.Sync() +} + +// returns true if the provided body should be included in the log +func (fl fileLogger) shouldLogBody(header http.Header, body io.ReadCloser) bool { + ct := header.Get("Content-Type") + return fl.logLevel >= LogDebug && body != nil && !strings.Contains(ct, "application/octet-stream") +} + +// creates standard header for log entries, it contains a timestamp and the log level +func entryHeader(level LevelType) string { + // this format provides a fixed number of digits so the size of the timestamp is constant + return fmt.Sprintf("(%s) %s:", time.Now().Format("2006-01-02T15:04:05.0000000Z07:00"), level.String()) +} diff --git a/vendor/github.com/Azure/go-autorest/tracing/LICENSE b/vendor/github.com/Azure/go-autorest/tracing/LICENSE new file mode 100644 index 000000000..b9d6a27ea --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/tracing/LICENSE @@ -0,0 +1,191 @@ + + 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 + + Copyright 2015 Microsoft Corporation + + 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. diff --git a/vendor/github.com/Azure/go-autorest/tracing/go.mod b/vendor/github.com/Azure/go-autorest/tracing/go.mod new file mode 100644 index 000000000..b066b3e6e --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/tracing/go.mod @@ -0,0 +1,8 @@ +module github.com/Azure/go-autorest/tracing + +go 1.12 + +require ( + contrib.go.opencensus.io/exporter/ocagent v0.4.12 + go.opencensus.io v0.20.2 +) diff --git a/vendor/github.com/Azure/go-autorest/tracing/go.sum b/vendor/github.com/Azure/go-autorest/tracing/go.sum new file mode 100644 index 000000000..4e5548c91 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/tracing/go.sum @@ -0,0 +1,130 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +contrib.go.opencensus.io/exporter/ocagent v0.4.12 h1:jGFvw3l57ViIVEPKKEUXPcLYIXJmQxLUh6ey1eJhwyc= +contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= +github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE= +github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2 h1:NAfh7zF0/3/HqtMvJNZ/RFrSlCE6ZTlHmKfhL/Dm1Jk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/api v0.3.1 h1:oJra/lMfmtm13/rgY/8i3MzjFWYXvQIAKjQ3HqofMk8= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.19.1 h1:TrBcJ1yqAl1G++wO39nD/qtgpsW9/1+QGrluyMGEYgM= +google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/Azure/go-autorest/tracing/tracing.go b/vendor/github.com/Azure/go-autorest/tracing/tracing.go new file mode 100644 index 000000000..28951c284 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/tracing/tracing.go @@ -0,0 +1,195 @@ +package tracing + +// Copyright 2018 Microsoft Corporation +// +// 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. + +import ( + "context" + "fmt" + "net/http" + "os" + + "contrib.go.opencensus.io/exporter/ocagent" + "go.opencensus.io/plugin/ochttp" + "go.opencensus.io/plugin/ochttp/propagation/tracecontext" + "go.opencensus.io/stats/view" + "go.opencensus.io/trace" +) + +var ( + // Transport is the default tracing RoundTripper. The custom options setter will control + // if traces are being emitted or not. + Transport = NewTransport() + + // enabled is the flag for marking if tracing is enabled. + enabled = false + + // Sampler is the tracing sampler. If tracing is disabled it will never sample. Otherwise + // it will be using the parent sampler or the default. + sampler = trace.NeverSample() + + // Views for metric instrumentation. + views = map[string]*view.View{} + + // the trace exporter + traceExporter trace.Exporter +) + +func init() { + enableFromEnv() +} + +func enableFromEnv() { + _, ok := os.LookupEnv("AZURE_SDK_TRACING_ENABLED") + _, legacyOk := os.LookupEnv("AZURE_SDK_TRACING_ENABELD") + if ok || legacyOk { + agentEndpoint, ok := os.LookupEnv("OCAGENT_TRACE_EXPORTER_ENDPOINT") + + if ok { + EnableWithAIForwarding(agentEndpoint) + } else { + Enable() + } + } +} + +// NewTransport returns a new instance of a tracing-aware RoundTripper. +func NewTransport() *ochttp.Transport { + return &ochttp.Transport{ + Propagation: &tracecontext.HTTPFormat{}, + GetStartOptions: getStartOptions, + } +} + +// IsEnabled returns true if monitoring is enabled for the sdk. +func IsEnabled() bool { + return enabled +} + +// Enable will start instrumentation for metrics and traces. +func Enable() error { + enabled = true + sampler = nil + + err := initStats() + return err +} + +// Disable will disable instrumentation for metrics and traces. +func Disable() { + disableStats() + sampler = trace.NeverSample() + if traceExporter != nil { + trace.UnregisterExporter(traceExporter) + } + enabled = false +} + +// EnableWithAIForwarding will start instrumentation and will connect to app insights forwarder +// exporter making the metrics and traces available in app insights. +func EnableWithAIForwarding(agentEndpoint string) (err error) { + err = Enable() + if err != nil { + return err + } + + traceExporter, err := ocagent.NewExporter(ocagent.WithInsecure(), ocagent.WithAddress(agentEndpoint)) + if err != nil { + return err + } + trace.RegisterExporter(traceExporter) + return +} + +// getStartOptions is the custom options setter for the ochttp package. +func getStartOptions(*http.Request) trace.StartOptions { + return trace.StartOptions{ + Sampler: sampler, + } +} + +// initStats registers the views for the http metrics +func initStats() (err error) { + clientViews := []*view.View{ + ochttp.ClientCompletedCount, + ochttp.ClientRoundtripLatencyDistribution, + ochttp.ClientReceivedBytesDistribution, + ochttp.ClientSentBytesDistribution, + } + for _, cv := range clientViews { + vn := fmt.Sprintf("Azure/go-autorest/tracing-%s", cv.Name) + views[vn] = cv.WithName(vn) + err = view.Register(views[vn]) + if err != nil { + return err + } + } + return +} + +// disableStats will unregister the previously registered metrics +func disableStats() { + for _, v := range views { + view.Unregister(v) + } +} + +// StartSpan starts a trace span +func StartSpan(ctx context.Context, name string) context.Context { + ctx, _ = trace.StartSpan(ctx, name, trace.WithSampler(sampler)) + return ctx +} + +// EndSpan ends a previously started span stored in the context +func EndSpan(ctx context.Context, httpStatusCode int, err error) { + span := trace.FromContext(ctx) + + if span == nil { + return + } + + if err != nil { + span.SetStatus(trace.Status{Message: err.Error(), Code: toTraceStatusCode(httpStatusCode)}) + } + span.End() +} + +// toTraceStatusCode converts HTTP Codes to OpenCensus codes as defined +// at https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/HTTP.md#status +func toTraceStatusCode(httpStatusCode int) int32 { + switch { + case http.StatusOK <= httpStatusCode && httpStatusCode < http.StatusBadRequest: + return trace.StatusCodeOK + case httpStatusCode == http.StatusBadRequest: + return trace.StatusCodeInvalidArgument + case httpStatusCode == http.StatusUnauthorized: // 401 is actually unauthenticated. + return trace.StatusCodeUnauthenticated + case httpStatusCode == http.StatusForbidden: + return trace.StatusCodePermissionDenied + case httpStatusCode == http.StatusNotFound: + return trace.StatusCodeNotFound + case httpStatusCode == http.StatusTooManyRequests: + return trace.StatusCodeResourceExhausted + case httpStatusCode == 499: + return trace.StatusCodeCancelled + case httpStatusCode == http.StatusNotImplemented: + return trace.StatusCodeUnimplemented + case httpStatusCode == http.StatusServiceUnavailable: + return trace.StatusCodeUnavailable + case httpStatusCode == http.StatusGatewayTimeout: + return trace.StatusCodeDeadlineExceeded + default: + return trace.StatusCodeUnknown + } +} diff --git a/vendor/github.com/OpenDNS/vegadns2client/.gitignore b/vendor/github.com/OpenDNS/vegadns2client/.gitignore new file mode 100644 index 000000000..91efe8f7f --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/.gitignore @@ -0,0 +1,4 @@ +.vscode +.coverage +vendor +Gopkg* diff --git a/vendor/github.com/OpenDNS/vegadns2client/LICENSE b/vendor/github.com/OpenDNS/vegadns2client/LICENSE new file mode 100644 index 000000000..f9361e31c --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/LICENSE @@ -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. diff --git a/vendor/github.com/OpenDNS/vegadns2client/Makefile b/vendor/github.com/OpenDNS/vegadns2client/Makefile new file mode 100644 index 000000000..eee2c5f9f --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/Makefile @@ -0,0 +1,13 @@ +build: + go build -v . + +test: + mkdir -p .coverage + go vet -v + go get -u github.com/golang/lint/golint + golint -set_exit_status + go test -v -cover -coverprofile .coverage/cover.out + go tool cover -html=.coverage/cover.out -o .coverage/index.html + @echo "" + @echo "To see test coverage, try:" + @echo "open .coverage/index.html" diff --git a/vendor/github.com/OpenDNS/vegadns2client/README.md b/vendor/github.com/OpenDNS/vegadns2client/README.md new file mode 100644 index 000000000..e0ab1211c --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/README.md @@ -0,0 +1,76 @@ +# vegadns2client +vegadns2client is a go client for [VegaDNS-API](https://github.com/shupp/VegaDNS-API). This is an incomplete client, initially intended to support [lego](https://github.com/xenolf/lego). + +## Example Usage + +### An example of looking up the auth zone for a hostname: + +```go +package main + +import ( + "fmt" + "github.com/opendns/vegadns2client" +) + +func main() { + v := vegadns2client.NewVegaDNSClient("http://localhost:5000") + v.APIKey = "mykey" + v.APISecret = "mysecret" + + authZone, domainID, err := v.GetAuthZone("example.com") + fmt.Println(authZone, domainID, err) +} +``` + +Which will output the following: + +``` +2018/02/22 16:11:48 tmpHostname for i = 1: example.com +2018/02/22 16:11:48 {ok 1 [{active example.com 2 0}]} +2018/02/22 16:11:48 Found zone: example.com + Shortened to foobar.com +foobar.com +``` + +### An example of creating and deleting a TXT record + +```go +package main + +import ( + "fmt" + "github.com/opendns/vegadns2client" +) + +func main() { + v := vegadns2client.NewVegaDNSClient("http://localhost:5000") + v.APIKey = "mykey" + v.APISecret = "mysecret" + + authZone, domainID, err := v.GetAuthZone("example.com") + fmt.Println(authZone, domainID, err) + + result := v.CreateTXT(domainID, "_acme-challenge.example.com", "test challenge", 25) + fmt.Println(result) + + recordID, err := v.GetRecordID(domainID, "_acme-challenge.example.com", "TXT") + fmt.Println(recordID, err) + + err = v.DeleteRecord(recordID) + fmt.Println(err) +} +``` + +Which will output the following: + +``` +2018/02/26 14:59:53 tmpHostname for i = 1: example.com +2018/02/26 14:59:53 {ok 1 [{active example.com 1 0}]} +2018/02/26 14:59:53 Found zone: example.com + Shortened to example.com +example.com 1 + +3 + +``` diff --git a/vendor/github.com/OpenDNS/vegadns2client/client.go b/vendor/github.com/OpenDNS/vegadns2client/client.go new file mode 100644 index 000000000..21096568a --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/client.go @@ -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() +} diff --git a/vendor/github.com/OpenDNS/vegadns2client/domains.go b/vendor/github.com/OpenDNS/vegadns2client/domains.go new file mode 100644 index 000000000..b9713f4ed --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/domains.go @@ -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) +} diff --git a/vendor/github.com/OpenDNS/vegadns2client/main.go b/vendor/github.com/OpenDNS/vegadns2client/main.go new file mode 100644 index 000000000..0d3e79a61 --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/main.go @@ -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{}, + } +} diff --git a/vendor/github.com/OpenDNS/vegadns2client/records.go b/vendor/github.com/OpenDNS/vegadns2client/records.go new file mode 100644 index 000000000..36bd8d906 --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/records.go @@ -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 +} diff --git a/vendor/github.com/OpenDNS/vegadns2client/tokens.go b/vendor/github.com/OpenDNS/vegadns2client/tokens.go new file mode 100644 index 000000000..9e7706b09 --- /dev/null +++ b/vendor/github.com/OpenDNS/vegadns2client/tokens.go @@ -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) +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/LICENSE b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/LICENSE new file mode 100644 index 000000000..8dada3eda --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/LICENSE @@ -0,0 +1,201 @@ + 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. diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/README.md b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/README.md new file mode 100644 index 000000000..b21723b7c --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/README.md @@ -0,0 +1,3 @@ +# Akamai Client + +A golang package which helps facilitate making HTTP requests to [Akamai OPEN APIs](https://developer.akamai.com) \ No newline at end of file diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/api.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/api.go new file mode 100644 index 000000000..d20ce434e --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/api.go @@ -0,0 +1,36 @@ +package client + +import ( + "encoding/json" +) + +// Resource is the "base" type for all API resources +type Resource struct { + Complete chan bool `json:"-"` +} + +// Init initializes the Complete channel, if it is necessary +// need to create a resource specific Init(), make sure to +// initialize the channel. +func (resource *Resource) Init() { + resource.Complete = make(chan bool, 1) +} + +// PostUnmarshalJSON is a default implementation of the +// PostUnmarshalJSON hook that simply calls Init() and +// sends true to the Complete channel. This is overridden +// in many resources, in particular those that represent +// collections, and have to initialize sub-resources also. +func (resource *Resource) PostUnmarshalJSON() error { + resource.Init() + resource.Complete <- true + return nil +} + +// GetJSON returns the raw (indented) JSON (as []bytes) +func (resource *Resource) GetJSON() ([]byte, error) { + return json.MarshalIndent(resource, "", " ") +} + +// JSONBody is a generic struct for temporary JSON unmarshalling. +type JSONBody map[string]interface{} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/client.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/client.go new file mode 100644 index 000000000..188233ad8 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/client.go @@ -0,0 +1,154 @@ +// Package client is a simple library for http.Client to sign Akamai OPEN Edgegrid API requests +package client + +import ( + "bytes" + "errors" + "github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid" + "github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1" + "io" + "io/ioutil" + "mime/multipart" + "net/http" + "net/url" + "os" + "path/filepath" + "runtime" + "strings" +) + +var ( + libraryVersion = "0.6.2" + // UserAgent is the User-Agent value sent for all requests + UserAgent = "Akamai-Open-Edgegrid-golang/" + libraryVersion + " golang/" + strings.TrimPrefix(runtime.Version(), "go") + // Client is the *http.Client to use + Client = http.DefaultClient +) + +// NewRequest creates an HTTP request that can be sent to Akamai APIs. A relative URL can be provided in path, which will be resolved to the +// Host specified in Config. If body is specified, it will be sent as the request body. +func NewRequest(config edgegrid.Config, method, path string, body io.Reader) (*http.Request, error) { + var ( + baseURL *url.URL + err error + ) + + if strings.HasPrefix(config.Host, "https://") { + baseURL, err = url.Parse(config.Host) + } else { + baseURL, err = url.Parse("https://" + config.Host) + } + + if err != nil { + return nil, err + } + + rel, err := url.Parse(strings.TrimPrefix(path, "/")) + if err != nil { + return nil, err + } + + u := baseURL.ResolveReference(rel) + if config.AccountKey != "" { + q := u.Query() + q.Add("accountSwitchKey", config.AccountKey) + u.RawQuery = q.Encode() + } + + req, err := http.NewRequest(method, u.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("User-Agent", UserAgent) + + return req, nil +} + +// NewJSONRequest creates an HTTP request that can be sent to the Akamai APIs with a JSON body +// The JSON body is encoded and the Content-Type/Accept headers are set automatically. +func NewJSONRequest(config edgegrid.Config, method, path string, body interface{}) (*http.Request, error) { + var req *http.Request + var err error + if body != nil { + jsonBody, err := jsonhooks.Marshal(body) + if err != nil { + return nil, err + } + buf := bytes.NewReader(jsonBody) + req, err = NewRequest(config, method, path, buf) + } else { + req, err = NewRequest(config, method, path, nil) + } + + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Accept", "application/json,*/*") + + return req, nil +} + +// NewMultiPartFormDataRequest creates an HTTP request that uploads a file to the Akamai API +func NewMultiPartFormDataRequest(config edgegrid.Config, uriPath, filePath string, otherFormParams map[string]string) (*http.Request, error) { + file, err := os.Open(filePath) + if err != nil { + return nil, err + } + defer file.Close() + + body := &bytes.Buffer{} + writer := multipart.NewWriter(body) + // TODO: make this field name configurable + part, err := writer.CreateFormFile("importFile", filepath.Base(filePath)) + if err != nil { + return nil, err + } + _, err = io.Copy(part, file) + + for key, val := range otherFormParams { + _ = writer.WriteField(key, val) + } + err = writer.Close() + if err != nil { + return nil, err + } + + req, err := NewRequest(config, "POST", uriPath, body) + req.Header.Set("Content-Type", writer.FormDataContentType()) + return req, err +} + +// Do performs a given HTTP Request, signed with the Akamai OPEN Edgegrid +// Authorization header. An edgegrid.Response or an error is returned. +func Do(config edgegrid.Config, req *http.Request) (*http.Response, error) { + Client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + req = edgegrid.AddRequestHeader(config, req) + return nil + } + + req = edgegrid.AddRequestHeader(config, req) + res, err := Client.Do(req) + if err != nil { + return nil, err + } + + return res, nil +} + +// BodyJSON unmarshals the Response.Body into a given data structure +func BodyJSON(r *http.Response, data interface{}) error { + if data == nil { + return errors.New("You must pass in an interface{}") + } + + body, err := ioutil.ReadAll(r.Body) + if err != nil { + return err + } + err = jsonhooks.Unmarshal(body, data) + + return err +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/errors.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/errors.go new file mode 100644 index 000000000..05b852473 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/errors.go @@ -0,0 +1,107 @@ +package client + +import ( + "fmt" + "io/ioutil" + "net/http" + "strings" + + "github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1" +) + +// APIError exposes an Akamai OPEN Edgegrid Error +type APIError struct { + error + Type string `json:"type"` + Title string `json:"title"` + Status int `json:"status"` + Detail string `json:"detail"` + Errors []APIErrorDetail `json:"errors"` + Problems []APIErrorDetail `json:"problems"` + Instance string `json:"instance"` + Method string `json:"method"` + ServerIP string `json:"serverIp"` + ClientIP string `json:"clientIp"` + RequestID string `json:"requestId"` + RequestTime string `json:"requestTime"` + Response *http.Response `json:"-"` + RawBody string `json:"-"` +} + +type APIErrorDetail struct { + Type string `json:"type"` + Title string `json:"title"` + Detail string `json:"detail"` + RejectedValue string `json:"rejectedValue"` +} + +func (error APIError) Error() string { + var errorDetails string + if len(error.Errors) > 0 { + for _, e := range error.Errors { + errorDetails = fmt.Sprintf("%s \n %s", errorDetails, e) + } + } + if len(error.Problems) > 0 { + for _, e := range error.Problems { + errorDetails = fmt.Sprintf("%s \n %s", errorDetails, e) + } + } + return strings.TrimSpace(fmt.Sprintf("API Error: %d %s %s More Info %s\n %s", error.Status, error.Title, error.Detail, error.Type, errorDetails)) +} + +// NewAPIError creates a new API error based on a Response, +// or http.Response-like. +func NewAPIError(response *http.Response) APIError { + // TODO: handle this error + body, _ := ioutil.ReadAll(response.Body) + + return NewAPIErrorFromBody(response, body) +} + +// NewAPIErrorFromBody creates a new API error, allowing you to pass in a body +// +// This function is intended to be used after the body has already been read for +// other purposes. +func NewAPIErrorFromBody(response *http.Response, body []byte) APIError { + error := APIError{} + if err := jsonhooks.Unmarshal(body, &error); err == nil { + error.Status = response.StatusCode + error.Title = response.Status + } + + error.Response = response + error.RawBody = string(body) + + return error +} + +// IsInformational determines if a response was informational (1XX status) +func IsInformational(r *http.Response) bool { + return r.StatusCode > 99 && r.StatusCode < 200 +} + +// IsSuccess determines if a response was successful (2XX status) +func IsSuccess(r *http.Response) bool { + return r.StatusCode > 199 && r.StatusCode < 300 +} + +// IsRedirection determines if a response was a redirect (3XX status) +func IsRedirection(r *http.Response) bool { + return r.StatusCode > 299 && r.StatusCode < 400 +} + +// IsClientError determines if a response was a client error (4XX status) +func IsClientError(r *http.Response) bool { + return r.StatusCode > 399 && r.StatusCode < 500 +} + +// IsServerError determines if a response was a server error (5XX status) +func IsServerError(r *http.Response) bool { + return r.StatusCode > 499 && r.StatusCode < 600 +} + +// IsError determines if the response was a client or server error (4XX or 5XX status) +func IsError(r *http.Response) bool { + return r.StatusCode > 399 && r.StatusCode < 600 +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/README.md b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/README.md new file mode 100644 index 000000000..800db0c4a --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/README.md @@ -0,0 +1,2 @@ +# Akamai Config DNS (Zone Record Management) +A golang package that talks to the [Akamai OPEN Config DNS API](https://developer.akamai.com/api/luna/config-dns/overview.html). \ No newline at end of file diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/errors.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/errors.go new file mode 100644 index 000000000..06eed5daa --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/errors.go @@ -0,0 +1,125 @@ +package dns + +import ( + "fmt" +) + +type ConfigDNSError interface { + error + Network() bool + NotFound() bool + FailedToSave() bool + ValidationFailed() bool +} + +func IsConfigDNSError(e error) bool { + _, ok := e.(ConfigDNSError) + return ok +} + +type ZoneError struct { + zoneName string + httpErrorMessage string + apiErrorMessage string + err error +} + +func (e *ZoneError) Network() bool { + if e.httpErrorMessage != "" { + return true + } + return false +} + +func (e *ZoneError) NotFound() bool { + if e.err == nil && e.httpErrorMessage == "" && e.apiErrorMessage == "" { + return true + } + return false +} + +func (e *ZoneError) FailedToSave() bool { + return false +} + +func (e *ZoneError) ValidationFailed() bool { + if e.apiErrorMessage != "" { + return true + } + return false +} + +func (e *ZoneError) Error() string { + if e.Network() { + return fmt.Sprintf("Zone \"%s\" network error: [%s]", e.zoneName, e.httpErrorMessage) + } + + if e.NotFound() { + return fmt.Sprintf("Zone \"%s\" not found.", e.zoneName) + } + + if e.FailedToSave() { + return fmt.Sprintf("Zone \"%s\" failed to save: [%s]", e.zoneName, e.err.Error()) + } + + if e.ValidationFailed() { + return fmt.Sprintf("Zone \"%s\" validation failed: [%s]", e.zoneName, e.apiErrorMessage) + } + + if e.err != nil { + return e.err.Error() + } + + return "" +} + +type RecordError struct { + fieldName string + httpErrorMessage string + err error +} + +func (e *RecordError) Network() bool { + if e.httpErrorMessage != "" { + return true + } + return false +} + +func (e *RecordError) NotFound() bool { + return false +} + +func (e *RecordError) FailedToSave() bool { + if e.fieldName == "" { + return true + } + return false +} + +func (e *RecordError) ValidationFailed() bool { + if e.fieldName != "" { + return true + } + return false +} + +func (e *RecordError) Error() string { + if e.Network() { + return fmt.Sprintf("Record network error: [%s]", e.httpErrorMessage) + } + + if e.NotFound() { + return fmt.Sprintf("Record not found.") + } + + if e.FailedToSave() { + return fmt.Sprintf("Record failed to save: [%s]", e.err.Error()) + } + + if e.ValidationFailed() { + return fmt.Sprintf("Record validation failed for field [%s]", e.fieldName) + } + + return "" +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/record.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/record.go new file mode 100644 index 000000000..7a32fe6b7 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/record.go @@ -0,0 +1,1739 @@ +package dns + +import ( + "strings" + "time" +) + +// All record types (below) must implement the DNSRecord interface +// This allows the record to be used dynamically in slices - see the Zone struct definition in zone.go +// +// The record types implemented and their fields are as defined here +// https://developer.akamai.com/api/luna/config-dns/data.html +type DNSRecord interface { + // Get the list of allowed fields for this type + GetAllowedFields() []string + // Set a field on the struct, which check for valid fields + SetField(name string, value interface{}) error + // Translate struct properties to a map + ToMap() map[string]interface{} +} + +type ARecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` +} + +func NewARecord() *ARecord { + return &ARecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + }, + } +} + +func (record *ARecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *ARecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *ARecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + } +} + +type AaaaRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` +} + +func NewAaaaRecord() *AaaaRecord { + return &AaaaRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + }, + } +} + +func (record *AaaaRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *AaaaRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *AaaaRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + } +} + +type AfsdbRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` + Subtype int `json:"subtype,omitempty"` +} + +func NewAfsdbRecord() *AfsdbRecord { + return &AfsdbRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + "subtype", + }, + } +} + +func (record *AfsdbRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *AfsdbRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + case "subtype": + v, ok := value.(int) + if ok { + record.Subtype = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *AfsdbRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + "subtype": record.Subtype, + } +} + +type CnameRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` +} + +func NewCnameRecord() *CnameRecord { + return &CnameRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + }, + } +} + +func (record *CnameRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *CnameRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *CnameRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + } +} + +type DnskeyRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Flags int `json:"flags,omitempty"` + Protocol int `json:"protocol,omitempty"` + Algorithm int `json:"algorithm,omitempty"` + Key string `json:"key,omitempty"` +} + +func NewDnskeyRecord() *DnskeyRecord { + return &DnskeyRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "flags", + "protocol", + "algorithm", + "key", + }, + } +} + +func (record *DnskeyRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *DnskeyRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "flags": + v, ok := value.(int) + if ok { + record.Flags = v + return nil + } + case "protocol": + v, ok := value.(int) + if ok { + record.Protocol = v + return nil + } + case "algorithm": + v, ok := value.(int) + if ok { + record.Algorithm = v + return nil + } + case "key": + v, ok := value.(string) + if ok { + record.Key = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *DnskeyRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "flags": record.Flags, + "protocol": record.Protocol, + "algorithm": record.Algorithm, + "key": record.Key, + } +} + +type DsRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Keytag int `json:"keytag,omitempty"` + Algorithm int `json:"algorithm,omitempty"` + DigestType int `json:"digest_type,omitempty"` + Digest string `json:"digest,omitempty"` +} + +func NewDsRecord() *DsRecord { + return &DsRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "keytag", + "algorithm", + "digesttype", + "digest", + }, + } +} + +func (record *DsRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *DsRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "keytag": + v, ok := value.(int) + if ok { + record.Keytag = v + return nil + } + case "algorithm": + v, ok := value.(int) + if ok { + record.Algorithm = v + return nil + } + case "digesttype": + v, ok := value.(int) + if ok { + record.DigestType = v + return nil + } + case "digest": + v, ok := value.(string) + if ok { + record.Digest = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *DsRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "keytag": record.Keytag, + "algorithm": record.Algorithm, + "digesttype": record.DigestType, + "digest": record.DigestType, + } +} + +type HinfoRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Hardware string `json:"hardware,omitempty"` + Software string `json:"software,omitempty"` +} + +func NewHinfoRecord() *HinfoRecord { + return &HinfoRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "hardware", + "software", + }, + } +} + +func (record *HinfoRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *HinfoRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "hardware": + v, ok := value.(string) + if ok { + record.Hardware = v + return nil + } + case "software": + v, ok := value.(string) + if ok { + record.Software = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *HinfoRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "hardware": record.Hardware, + "software": record.Software, + } +} + +type LocRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` +} + +func NewLocRecord() *LocRecord { + return &LocRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + }, + } +} + +func (record *LocRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *LocRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *LocRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + } +} + +type MxRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` + Priority int `json:"priority,omitempty"` +} + +func NewMxRecord() *MxRecord { + return &MxRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + "priority", + }, + } +} + +func (record *MxRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *MxRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + case "priority": + v, ok := value.(int) + if ok { + record.Priority = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *MxRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + "priority": record.Priority, + } +} + +type NaptrRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Order uint16 `json:"order,omitempty"` + Preference uint16 `json:"preference,omitempty"` + Flags string `json:"flags,omitempty"` + Service string `json:"service,omitempty"` + Regexp string `json:"regexp,omitempty"` + Replacement string `json:"replacement,omitempty"` +} + +func NewNaptrRecord() *NaptrRecord { + return &NaptrRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "order", + "preference", + "flags", + "service", + "regexp", + "replacement", + }, + } +} + +func (record *NaptrRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *NaptrRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "order": + v, ok := value.(uint16) + if ok { + record.Order = v + return nil + } + case "preference": + v, ok := value.(uint16) + if ok { + record.Preference = v + return nil + } + case "flags": + v, ok := value.(string) + if ok { + record.Flags = v + return nil + } + case "service": + v, ok := value.(string) + if ok { + record.Service = v + return nil + } + case "regexp": + v, ok := value.(string) + if ok { + record.Regexp = v + return nil + } + case "replacement": + v, ok := value.(string) + if ok { + record.Replacement = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *NaptrRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "order": record.Order, + "preference": record.Preference, + "flags": record.Flags, + "service": record.Service, + "regexp": record.Regexp, + "replacement": record.Replacement, + } +} + +type NsRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` +} + +func NewNsRecord() *NsRecord { + return &NsRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + }, + } +} + +func (record *NsRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *NsRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *NsRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + } +} + +type Nsec3Record struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Algorithm int `json:"algorithm,omitempty"` + Flags int `json:"flags,omitempty"` + Iterations int `json:"iterations,omitempty"` + Salt string `json:"salt,omitempty"` + NextHashedOwnerName string `json:"next_hashed_owner_name,omitempty"` + TypeBitmaps string `json:"type_bitmaps,omitempty"` +} + +func NewNsec3Record() *Nsec3Record { + return &Nsec3Record{ + fieldMap: []string{ + "name", + "ttl", + "active", + "algorithm", + "flags", + "iterations", + "salt", + "nexthashedownername", + "typebitmaps", + }, + } +} + +func (record *Nsec3Record) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *Nsec3Record) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "algorithm": + v, ok := value.(int) + if ok { + record.Algorithm = v + return nil + } + case "flags": + v, ok := value.(int) + if ok { + record.Flags = v + return nil + } + case "iterations": + v, ok := value.(int) + if ok { + record.Iterations = v + return nil + } + case "salt": + v, ok := value.(string) + if ok { + record.Salt = v + return nil + } + case "nexthashedownername": + v, ok := value.(string) + if ok { + record.NextHashedOwnerName = v + return nil + } + case "typebitmaps": + v, ok := value.(string) + if ok { + record.TypeBitmaps = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *Nsec3Record) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "algorithm": record.Algorithm, + "flags": record.Flags, + "iterations": record.Iterations, + "salt": record.Salt, + "nexthashedownername": record.NextHashedOwnerName, + "typebitmaps": record.TypeBitmaps, + } +} + +type Nsec3paramRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Algorithm int `json:"algorithm,omitempty"` + Flags int `json:"flags,omitempty"` + Iterations int `json:"iterations,omitempty"` + Salt string `json:"salt,omitempty"` +} + +func NewNsec3paramRecord() *Nsec3paramRecord { + return &Nsec3paramRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "algorithm", + "flags", + "iterations", + "salt", + }, + } +} + +func (record *Nsec3paramRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *Nsec3paramRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "algorithm": + v, ok := value.(int) + if ok { + record.Algorithm = v + return nil + } + case "flags": + v, ok := value.(int) + if ok { + record.Flags = v + return nil + } + case "iterations": + v, ok := value.(int) + if ok { + record.Iterations = v + return nil + } + case "salt": + v, ok := value.(string) + if ok { + record.Salt = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *Nsec3paramRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "algorithm": record.Algorithm, + "flags": record.Flags, + "iterations": record.Iterations, + "salt": record.Salt, + } +} + +type PtrRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` +} + +func NewPtrRecord() *PtrRecord { + return &PtrRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + }, + } +} + +func (record *PtrRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *PtrRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *PtrRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + } +} + +type RpRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Mailbox string `json:"mailbox,omitempty"` + Txt string `json:"txt,omitempty"` +} + +func NewRpRecord() *RpRecord { + return &RpRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "mailbox", + "txt", + }, + } +} + +func (record *RpRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *RpRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "mailbox": + v, ok := value.(string) + if ok { + record.Mailbox = v + return nil + } + case "txt": + v, ok := value.(string) + if ok { + record.Txt = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *RpRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "mailbox": record.Mailbox, + "txt": record.Txt, + } +} + +type RrsigRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + TypeCovered string `json:"type_covered,omitempty"` + Algorithm int `json:"algorithm,omitempty"` + OriginalTTL int `json:"original_ttl,omitempty"` + Expiration string `json:"expiration,omitempty"` + Inception string `json:"inception,omitempty"` + Keytag int `json:"keytag,omitempty"` + Signer string `json:"signer,omitempty"` + Signature string `json:"signature,omitempty"` + Labels int `json:"labels,omitempty"` +} + +func NewRrsigRecord() *RrsigRecord { + return &RrsigRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "typecovered", + "algorithm", + "originalttl", + "expiration", + "inception", + "keytag", + "signer", + "signature", + "labels", + }, + } +} + +func (record *RrsigRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *RrsigRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "typecovered": + v, ok := value.(string) + if ok { + record.TypeCovered = v + return nil + } + case "algorithm": + v, ok := value.(int) + if ok { + record.Algorithm = v + return nil + } + case "originalttl": + v, ok := value.(int) + if ok { + record.OriginalTTL = v + return nil + } + case "expiration": + v, ok := value.(string) + if ok { + record.Expiration = v + return nil + } + case "inception": + v, ok := value.(string) + if ok { + record.Inception = v + return nil + } + case "keytag": + v, ok := value.(int) + if ok { + record.Keytag = v + return nil + } + case "signer": + v, ok := value.(string) + if ok { + record.Signer = v + return nil + } + case "signature": + v, ok := value.(string) + if ok { + record.Signature = v + return nil + } + case "labels": + v, ok := value.(int) + if ok { + record.Labels = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *RrsigRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "typecovered": record.TypeCovered, + "algorithm": record.Algorithm, + "originalttl": record.OriginalTTL, + "expiration": record.Expiration, + "inception": record.Inception, + "keytag": record.Keytag, + "signer": record.Signer, + "signature": record.Signature, + "labels": record.Labels, + } +} + +type SoaRecord struct { + fieldMap []string `json:"-"` + originalSerial uint `json:"-"` + TTL int `json:"ttl,omitempty"` + Originserver string `json:"originserver,omitempty"` + Contact string `json:"contact,omitempty"` + Serial uint `json:"serial,omitempty"` + Refresh int `json:"refresh,omitempty"` + Retry int `json:"retry,omitempty"` + Expire int `json:"expire,omitempty"` + Minimum uint `json:"minimum,omitempty"` +} + +func NewSoaRecord() *SoaRecord { + r := &SoaRecord{ + fieldMap: []string{ + "ttl", + "originserver", + "contact", + "serial", + "refresh", + "retry", + "expire", + "minimum", + }, + } + r.SetField("serial", int(time.Now().Unix())) + return r +} + +func (record *SoaRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *SoaRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "originserver": + v, ok := value.(string) + if ok { + record.Originserver = v + return nil + } + case "contact": + v, ok := value.(string) + if ok { + record.Contact = v + return nil + } + case "serial": + v, ok := value.(uint) + if ok { + record.Serial = v + return nil + } + case "refresh": + v, ok := value.(int) + if ok { + record.Refresh = v + return nil + } + case "retry": + v, ok := value.(int) + if ok { + record.Retry = v + return nil + } + case "expire": + v, ok := value.(int) + if ok { + record.Expire = v + return nil + } + case "minimum": + v, ok := value.(uint) + if ok { + record.Minimum = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *SoaRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "ttl": record.TTL, + "originserver": record.Originserver, + "contact": record.Contact, + "serial": record.Serial, + "refresh": record.Refresh, + "retry": record.Retry, + "expire": record.Expire, + "minimum": record.Minimum, + } +} + +type SpfRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` +} + +func NewSpfRecord() *SpfRecord { + return &SpfRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + }, + } +} + +func (record *SpfRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *SpfRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *SpfRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + } +} + +type SrvRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` + Priority int `json:"priority,omitempty"` + Weight uint16 `json:"weight,omitempty"` + Port uint16 `json:"port,omitempty"` +} + +func NewSrvRecord() *SrvRecord { + return &SrvRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + "priority", + "weight", + "port", + }, + } +} + +func (record *SrvRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *SrvRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + case "priority": + v, ok := value.(int) + if ok { + record.Priority = v + return nil + } + case "weight": + v, ok := value.(uint16) + if ok { + record.Weight = v + return nil + } + case "port": + v, ok := value.(uint16) + if ok { + record.Port = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *SrvRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + "priority": record.Priority, + "weight": record.Weight, + "port": record.Port, + } +} + +type SshfpRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Algorithm int `json:"algorithm,omitempty"` + FingerprintType int `json:"fingerprint_type,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` +} + +func NewSshfpRecord() *SshfpRecord { + return &SshfpRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "algorithm", + "fingerprinttype", + "fingerprint", + }, + } +} + +func (record *SshfpRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *SshfpRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "algorithm": + v, ok := value.(int) + if ok { + record.Algorithm = v + return nil + } + case "fingerprinttype": + v, ok := value.(int) + if ok { + record.FingerprintType = v + return nil + } + case "fingerprint": + v, ok := value.(string) + if ok { + record.Fingerprint = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *SshfpRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "algorithm": record.Algorithm, + "fingerprinttype": record.FingerprintType, + "fingerprint": record.Fingerprint, + } +} + +type TxtRecord struct { + fieldMap []string `json:"-"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + Active bool `json:"active,omitempty"` + Target string `json:"target,omitempty"` +} + +func NewTxtRecord() *TxtRecord { + return &TxtRecord{ + fieldMap: []string{ + "name", + "ttl", + "active", + "target", + }, + } +} + +func (record *TxtRecord) GetAllowedFields() []string { + return record.fieldMap +} + +func (record *TxtRecord) SetField(name string, value interface{}) error { + if contains(record.fieldMap, name) { + switch name { + case "name": + v, ok := value.(string) + if ok { + record.Name = v + return nil + } + case "ttl": + v, ok := value.(int) + if ok { + record.TTL = v + return nil + } + case "active": + v, ok := value.(bool) + if ok { + record.Active = v + return nil + } + case "target": + v, ok := value.(string) + if ok { + record.Target = v + return nil + } + } + } + return &RecordError{fieldName: name} +} + +func (record *TxtRecord) ToMap() map[string]interface{} { + return map[string]interface{}{ + "name": record.Name, + "ttl": record.TTL, + "active": record.Active, + "target": record.Target, + } +} + +func contains(fieldMap []string, field string) bool { + field = strings.ToLower(field) + + for _, r := range fieldMap { + if r == field { + return true + } + } + + return false +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/service.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/service.go new file mode 100644 index 000000000..7f8ff80b6 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/service.go @@ -0,0 +1,16 @@ +package dns + +import ( + "github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid" +) + +var ( + // Config contains the Akamai OPEN Edgegrid API credentials + // for automatic signing of requests + Config edgegrid.Config +) + +// Init sets the FastDNS edgegrid Config +func Init(config edgegrid.Config) { + Config = config +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/zone.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/zone.go new file mode 100644 index 000000000..aa256aff7 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/zone.go @@ -0,0 +1,1566 @@ +package dns + +import ( + "errors" + "fmt" + "reflect" + "strings" + "sync" + "time" + + "github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1" +) + +type name struct { + recordType string + name string +} + +var ( + cnameNames []name + nonCnameNames []name + zoneWriteLock sync.Mutex +) + +// Zone represents a DNS zone +type Zone struct { + Token string `json:"token"` + Zone struct { + Name string `json:"name,omitempty"` + A []*ARecord `json:"a,omitempty"` + Aaaa []*AaaaRecord `json:"aaaa,omitempty"` + Afsdb []*AfsdbRecord `json:"afsdb,omitempty"` + Cname []*CnameRecord `json:"cname,omitempty"` + Dnskey []*DnskeyRecord `json:"dnskey,omitempty"` + Ds []*DsRecord `json:"ds,omitempty"` + Hinfo []*HinfoRecord `json:"hinfo,omitempty"` + Loc []*LocRecord `json:"loc,omitempty"` + Mx []*MxRecord `json:"mx,omitempty"` + Naptr []*NaptrRecord `json:"naptr,omitempty"` + Ns []*NsRecord `json:"ns,omitempty"` + Nsec3 []*Nsec3Record `json:"nsec3,omitempty"` + Nsec3param []*Nsec3paramRecord `json:"nsec3param,omitempty"` + Ptr []*PtrRecord `json:"ptr,omitempty"` + Rp []*RpRecord `json:"rp,omitempty"` + Rrsig []*RrsigRecord `json:"rrsig,omitempty"` + Soa *SoaRecord `json:"soa,omitempty"` + Spf []*SpfRecord `json:"spf,omitempty"` + Srv []*SrvRecord `json:"srv,omitempty"` + Sshfp []*SshfpRecord `json:"sshfp,omitempty"` + Txt []*TxtRecord `json:"txt,omitempty"` + } `json:"zone"` +} + +// NewZone creates a new Zone +func NewZone(hostname string) *Zone { + zone := &Zone{Token: "new"} + zone.Zone.Soa = NewSoaRecord() + zone.Zone.Name = hostname + return zone +} + +// GetZone retrieves a DNS Zone for a given hostname +func GetZone(hostname string) (*Zone, error) { + zone := NewZone(hostname) + req, err := client.NewRequest( + Config, + "GET", + "/config-dns/v1/zones/"+hostname, + nil, + ) + if err != nil { + return nil, err + } + + res, err := client.Do(Config, req) + if err != nil { + return nil, err + } + + if client.IsError(res) && res.StatusCode != 404 { + return nil, client.NewAPIError(res) + } else if res.StatusCode == 404 { + return nil, &ZoneError{zoneName: hostname} + } else { + err = client.BodyJSON(res, zone) + if err != nil { + return nil, err + } + + return zone, nil + } +} + +// Save updates the Zone +func (zone *Zone) Save() error { + // This lock will restrict the concurrency of API calls + // to 1 save request at a time. This is needed for the Soa.Serial value which + // is required to be incremented for every subsequent update to a zone + // so we have to save just one request at a time to ensure this is always + // incremented properly + zoneWriteLock.Lock() + defer zoneWriteLock.Unlock() + + valid, f := zone.validateCnames() + if valid == false { + var msg string + for _, v := range f { + msg = msg + fmt.Sprintf("\n%s Record '%s' conflicts with CNAME", v.recordType, v.name) + } + return &ZoneError{ + zoneName: zone.Zone.Name, + apiErrorMessage: "All CNAMEs must be unique in the zone" + msg, + } + } + + req, err := client.NewJSONRequest( + Config, + "POST", + "/config-dns/v1/zones/"+zone.Zone.Name, + zone, + ) + if err != nil { + return err + } + + res, err := client.Do(Config, req) + + // Network error + if err != nil { + return &ZoneError{ + zoneName: zone.Zone.Name, + httpErrorMessage: err.Error(), + err: err, + } + } + + // API error + if client.IsError(res) { + err := client.NewAPIError(res) + return &ZoneError{zoneName: zone.Zone.Name, apiErrorMessage: err.Detail, err: err} + } + + for { + updatedZone, err := GetZone(zone.Zone.Name) + if err != nil { + return err + } + + if updatedZone.Token != zone.Token { + *zone = *updatedZone + break + } + time.Sleep(time.Second) + } + + return nil +} + +func (zone *Zone) Delete() error { + // remove all the records except for SOA + // which is required and save the zone + zone.Zone.A = nil + zone.Zone.Aaaa = nil + zone.Zone.Afsdb = nil + zone.Zone.Cname = nil + zone.Zone.Dnskey = nil + zone.Zone.Ds = nil + zone.Zone.Hinfo = nil + zone.Zone.Loc = nil + zone.Zone.Mx = nil + zone.Zone.Naptr = nil + zone.Zone.Ns = nil + zone.Zone.Nsec3 = nil + zone.Zone.Nsec3param = nil + zone.Zone.Ptr = nil + zone.Zone.Rp = nil + zone.Zone.Rrsig = nil + zone.Zone.Spf = nil + zone.Zone.Srv = nil + zone.Zone.Sshfp = nil + zone.Zone.Txt = nil + + return zone.Save() +} + +func (zone *Zone) AddRecord(recordPtr interface{}) error { + switch recordPtr.(type) { + case *ARecord: + zone.addARecord(recordPtr.(*ARecord)) + case *AaaaRecord: + zone.addAaaaRecord(recordPtr.(*AaaaRecord)) + case *AfsdbRecord: + zone.addAfsdbRecord(recordPtr.(*AfsdbRecord)) + case *CnameRecord: + zone.addCnameRecord(recordPtr.(*CnameRecord)) + case *DnskeyRecord: + zone.addDnskeyRecord(recordPtr.(*DnskeyRecord)) + case *DsRecord: + zone.addDsRecord(recordPtr.(*DsRecord)) + case *HinfoRecord: + zone.addHinfoRecord(recordPtr.(*HinfoRecord)) + case *LocRecord: + zone.addLocRecord(recordPtr.(*LocRecord)) + case *MxRecord: + zone.addMxRecord(recordPtr.(*MxRecord)) + case *NaptrRecord: + zone.addNaptrRecord(recordPtr.(*NaptrRecord)) + case *NsRecord: + zone.addNsRecord(recordPtr.(*NsRecord)) + case *Nsec3Record: + zone.addNsec3Record(recordPtr.(*Nsec3Record)) + case *Nsec3paramRecord: + zone.addNsec3paramRecord(recordPtr.(*Nsec3paramRecord)) + case *PtrRecord: + zone.addPtrRecord(recordPtr.(*PtrRecord)) + case *RpRecord: + zone.addRpRecord(recordPtr.(*RpRecord)) + case *RrsigRecord: + zone.addRrsigRecord(recordPtr.(*RrsigRecord)) + case *SoaRecord: + zone.addSoaRecord(recordPtr.(*SoaRecord)) + case *SpfRecord: + zone.addSpfRecord(recordPtr.(*SpfRecord)) + case *SrvRecord: + zone.addSrvRecord(recordPtr.(*SrvRecord)) + case *SshfpRecord: + zone.addSshfpRecord(recordPtr.(*SshfpRecord)) + case *TxtRecord: + zone.addTxtRecord(recordPtr.(*TxtRecord)) + } + + return nil +} + +func (zone *Zone) RemoveRecord(recordPtr interface{}) error { + switch recordPtr.(type) { + case *ARecord: + return zone.removeARecord(recordPtr.(*ARecord)) + case *AaaaRecord: + return zone.removeAaaaRecord(recordPtr.(*AaaaRecord)) + case *AfsdbRecord: + return zone.removeAfsdbRecord(recordPtr.(*AfsdbRecord)) + case *CnameRecord: + return zone.removeCnameRecord(recordPtr.(*CnameRecord)) + case *DnskeyRecord: + return zone.removeDnskeyRecord(recordPtr.(*DnskeyRecord)) + case *DsRecord: + return zone.removeDsRecord(recordPtr.(*DsRecord)) + case *HinfoRecord: + return zone.removeHinfoRecord(recordPtr.(*HinfoRecord)) + case *LocRecord: + return zone.removeLocRecord(recordPtr.(*LocRecord)) + case *MxRecord: + return zone.removeMxRecord(recordPtr.(*MxRecord)) + case *NaptrRecord: + return zone.removeNaptrRecord(recordPtr.(*NaptrRecord)) + case *NsRecord: + return zone.removeNsRecord(recordPtr.(*NsRecord)) + case *Nsec3Record: + return zone.removeNsec3Record(recordPtr.(*Nsec3Record)) + case *Nsec3paramRecord: + return zone.removeNsec3paramRecord(recordPtr.(*Nsec3paramRecord)) + case *PtrRecord: + return zone.removePtrRecord(recordPtr.(*PtrRecord)) + case *RpRecord: + return zone.removeRpRecord(recordPtr.(*RpRecord)) + case *RrsigRecord: + return zone.removeRrsigRecord(recordPtr.(*RrsigRecord)) + case *SoaRecord: + return zone.removeSoaRecord(recordPtr.(*SoaRecord)) + case *SpfRecord: + return zone.removeSpfRecord(recordPtr.(*SpfRecord)) + case *SrvRecord: + return zone.removeSrvRecord(recordPtr.(*SrvRecord)) + case *SshfpRecord: + return zone.removeSshfpRecord(recordPtr.(*SshfpRecord)) + case *TxtRecord: + return zone.removeTxtRecord(recordPtr.(*TxtRecord)) + } + + return nil +} + +func (zone *Zone) addARecord(record *ARecord) { + zone.Zone.A = append(zone.Zone.A, record) + nonCnameNames = append(nonCnameNames, name{recordType: "A", name: record.Name}) +} + +func (zone *Zone) addAaaaRecord(record *AaaaRecord) { + zone.Zone.Aaaa = append(zone.Zone.Aaaa, record) + nonCnameNames = append(nonCnameNames, name{recordType: "AAAA", name: record.Name}) +} + +func (zone *Zone) addAfsdbRecord(record *AfsdbRecord) { + zone.Zone.Afsdb = append(zone.Zone.Afsdb, record) + nonCnameNames = append(nonCnameNames, name{recordType: "AFSDB", name: record.Name}) +} + +func (zone *Zone) addCnameRecord(record *CnameRecord) { + zone.Zone.Cname = append(zone.Zone.Cname, record) + cnameNames = append(cnameNames, name{recordType: "CNAME", name: record.Name}) +} + +func (zone *Zone) addDnskeyRecord(record *DnskeyRecord) { + zone.Zone.Dnskey = append(zone.Zone.Dnskey, record) + nonCnameNames = append(nonCnameNames, name{recordType: "DNSKEY", name: record.Name}) +} + +func (zone *Zone) addDsRecord(record *DsRecord) { + zone.Zone.Ds = append(zone.Zone.Ds, record) + nonCnameNames = append(nonCnameNames, name{recordType: "DS", name: record.Name}) +} + +func (zone *Zone) addHinfoRecord(record *HinfoRecord) { + zone.Zone.Hinfo = append(zone.Zone.Hinfo, record) + nonCnameNames = append(nonCnameNames, name{recordType: "HINFO", name: record.Name}) +} + +func (zone *Zone) addLocRecord(record *LocRecord) { + zone.Zone.Loc = append(zone.Zone.Loc, record) + nonCnameNames = append(nonCnameNames, name{recordType: "LOC", name: record.Name}) +} + +func (zone *Zone) addMxRecord(record *MxRecord) { + zone.Zone.Mx = append(zone.Zone.Mx, record) + nonCnameNames = append(nonCnameNames, name{recordType: "MX", name: record.Name}) +} + +func (zone *Zone) addNaptrRecord(record *NaptrRecord) { + zone.Zone.Naptr = append(zone.Zone.Naptr, record) + nonCnameNames = append(nonCnameNames, name{recordType: "NAPTR", name: record.Name}) +} + +func (zone *Zone) addNsRecord(record *NsRecord) { + zone.Zone.Ns = append(zone.Zone.Ns, record) + nonCnameNames = append(nonCnameNames, name{recordType: "NS", name: record.Name}) +} + +func (zone *Zone) addNsec3Record(record *Nsec3Record) { + zone.Zone.Nsec3 = append(zone.Zone.Nsec3, record) + nonCnameNames = append(nonCnameNames, name{recordType: "NSEC3", name: record.Name}) +} + +func (zone *Zone) addNsec3paramRecord(record *Nsec3paramRecord) { + zone.Zone.Nsec3param = append(zone.Zone.Nsec3param, record) + nonCnameNames = append(nonCnameNames, name{recordType: "NSEC3PARAM", name: record.Name}) +} + +func (zone *Zone) addPtrRecord(record *PtrRecord) { + zone.Zone.Ptr = append(zone.Zone.Ptr, record) + nonCnameNames = append(nonCnameNames, name{recordType: "PTR", name: record.Name}) +} + +func (zone *Zone) addRpRecord(record *RpRecord) { + zone.Zone.Rp = append(zone.Zone.Rp, record) + nonCnameNames = append(nonCnameNames, name{recordType: "RP", name: record.Name}) +} + +func (zone *Zone) addRrsigRecord(record *RrsigRecord) { + zone.Zone.Rrsig = append(zone.Zone.Rrsig, record) + nonCnameNames = append(nonCnameNames, name{recordType: "RRSIG", name: record.Name}) +} + +func (zone *Zone) addSoaRecord(record *SoaRecord) { + // Only one SOA records is allowed + zone.Zone.Soa = record +} + +func (zone *Zone) addSpfRecord(record *SpfRecord) { + zone.Zone.Spf = append(zone.Zone.Spf, record) + nonCnameNames = append(nonCnameNames, name{recordType: "SPF", name: record.Name}) +} + +func (zone *Zone) addSrvRecord(record *SrvRecord) { + zone.Zone.Srv = append(zone.Zone.Srv, record) + nonCnameNames = append(nonCnameNames, name{recordType: "SRV", name: record.Name}) +} + +func (zone *Zone) addSshfpRecord(record *SshfpRecord) { + zone.Zone.Sshfp = append(zone.Zone.Sshfp, record) + nonCnameNames = append(nonCnameNames, name{recordType: "SSHFP", name: record.Name}) +} + +func (zone *Zone) addTxtRecord(record *TxtRecord) { + zone.Zone.Txt = append(zone.Zone.Txt, record) + nonCnameNames = append(nonCnameNames, name{recordType: "TXT", name: record.Name}) +} + +func (zone *Zone) removeARecord(record *ARecord) error { + for key, r := range zone.Zone.A { + if reflect.DeepEqual(r, record) { + records := zone.Zone.A[:key] + if len(zone.Zone.A) > key { + if len(zone.Zone.A) > key { + zone.Zone.A = append(records, zone.Zone.A[key+1:]...) + } else { + zone.Zone.A = records + } + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("A Record not found") +} + +func (zone *Zone) removeAaaaRecord(record *AaaaRecord) error { + for key, r := range zone.Zone.Aaaa { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Aaaa[:key] + if len(zone.Zone.Aaaa) > key { + zone.Zone.Aaaa = append(records, zone.Zone.Aaaa[key+1:]...) + } else { + zone.Zone.Aaaa = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("AAAA Record not found") +} + +func (zone *Zone) removeAfsdbRecord(record *AfsdbRecord) error { + for key, r := range zone.Zone.Afsdb { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Afsdb[:key] + if len(zone.Zone.Afsdb) > key { + zone.Zone.Afsdb = append(records, zone.Zone.Afsdb[key+1:]...) + } else { + zone.Zone.Afsdb = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Afsdb Record not found") +} + +func (zone *Zone) removeCnameRecord(record *CnameRecord) error { + for key, r := range zone.Zone.Cname { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Cname[:key] + if len(zone.Zone.Cname) > key { + zone.Zone.Cname = append(records, zone.Zone.Cname[key+1:]...) + } else { + zone.Zone.Cname = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Cname Record not found") + + zone.removeCnameName(record.Name) + + return nil +} + +func (zone *Zone) removeDnskeyRecord(record *DnskeyRecord) error { + for key, r := range zone.Zone.Dnskey { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Dnskey[:key] + if len(zone.Zone.Dnskey) > key { + zone.Zone.Dnskey = append(records, zone.Zone.Dnskey[key+1:]...) + } else { + zone.Zone.Dnskey = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Dnskey Record not found") +} + +func (zone *Zone) removeDsRecord(record *DsRecord) error { + for key, r := range zone.Zone.Ds { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Ds[:key] + if len(zone.Zone.Ds) > key { + zone.Zone.Ds = append(records, zone.Zone.Ds[key+1:]...) + } else { + zone.Zone.Ds = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Ds Record not found") +} + +func (zone *Zone) removeHinfoRecord(record *HinfoRecord) error { + for key, r := range zone.Zone.Hinfo { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Hinfo[:key] + if len(zone.Zone.Hinfo) > key { + zone.Zone.Hinfo = append(records, zone.Zone.Hinfo[key+1:]...) + } else { + zone.Zone.Hinfo = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Hinfo Record not found") +} + +func (zone *Zone) removeLocRecord(record *LocRecord) error { + for key, r := range zone.Zone.Loc { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Loc[:key] + if len(zone.Zone.Loc) > key { + zone.Zone.Loc = append(records, zone.Zone.Loc[key+1:]...) + } else { + zone.Zone.Loc = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Loc Record not found") +} + +func (zone *Zone) removeMxRecord(record *MxRecord) error { + for key, r := range zone.Zone.Mx { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Mx[:key] + if len(zone.Zone.Mx) > key { + zone.Zone.Mx = append(records, zone.Zone.Mx[key+1:]...) + } else { + zone.Zone.Mx = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Mx Record not found") +} + +func (zone *Zone) removeNaptrRecord(record *NaptrRecord) error { + for key, r := range zone.Zone.Naptr { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Naptr[:key] + if len(zone.Zone.Naptr) > key { + zone.Zone.Naptr = append(records, zone.Zone.Naptr[key+1:]...) + } else { + zone.Zone.Naptr = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Naptr Record not found") +} + +func (zone *Zone) removeNsRecord(record *NsRecord) error { + for key, r := range zone.Zone.Ns { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Ns[:key] + if len(zone.Zone.Ns) > key { + zone.Zone.Ns = append(records, zone.Zone.Ns[key+1:]...) + } else { + zone.Zone.Ns = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Ns Record not found") +} + +func (zone *Zone) removeNsec3Record(record *Nsec3Record) error { + for key, r := range zone.Zone.Nsec3 { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Nsec3[:key] + if len(zone.Zone.Nsec3) > key { + zone.Zone.Nsec3 = append(records, zone.Zone.Nsec3[key+1:]...) + } else { + zone.Zone.Nsec3 = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Nsec3 Record not found") +} + +func (zone *Zone) removeNsec3paramRecord(record *Nsec3paramRecord) error { + for key, r := range zone.Zone.Nsec3param { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Nsec3param[:key] + if len(zone.Zone.Nsec3param) > key { + zone.Zone.Nsec3param = append(records, zone.Zone.Nsec3param[key+1:]...) + } else { + zone.Zone.Nsec3param = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Nsec3param Record not found") +} + +func (zone *Zone) removePtrRecord(record *PtrRecord) error { + for key, r := range zone.Zone.Ptr { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Ptr[:key] + if len(zone.Zone.Ptr) > key { + zone.Zone.Ptr = append(records, zone.Zone.Ptr[key+1:]...) + } else { + zone.Zone.Ptr = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Ptr Record not found") +} + +func (zone *Zone) removeRpRecord(record *RpRecord) error { + for key, r := range zone.Zone.Rp { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Rp[:key] + if len(zone.Zone.Rp) > key { + zone.Zone.Rp = append(records, zone.Zone.Rp[key+1:]...) + } else { + zone.Zone.Rp = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Rp Record not found") +} + +func (zone *Zone) removeRrsigRecord(record *RrsigRecord) error { + for key, r := range zone.Zone.Rrsig { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Rrsig[:key] + if len(zone.Zone.Rrsig) > key { + zone.Zone.Rrsig = append(records, zone.Zone.Rrsig[key+1:]...) + } else { + zone.Zone.Rrsig = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Rrsig Record not found") +} + +func (zone *Zone) removeSoaRecord(record *SoaRecord) error { + if reflect.DeepEqual(zone.Zone.Soa, record) { + zone.Zone.Soa = nil + + return nil + } + + return errors.New("SOA Record does not match") +} + +func (zone *Zone) removeSpfRecord(record *SpfRecord) error { + for key, r := range zone.Zone.Spf { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Spf[:key] + if len(zone.Zone.Spf) > key { + zone.Zone.Spf = append(records, zone.Zone.Spf[key+1:]...) + } else { + zone.Zone.Spf = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Spf Record not found") +} + +func (zone *Zone) removeSrvRecord(record *SrvRecord) error { + for key, r := range zone.Zone.Srv { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Srv[:key] + if len(zone.Zone.Srv) > key { + zone.Zone.Srv = append(records, zone.Zone.Srv[key+1:]...) + } else { + zone.Zone.Srv = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Srv Record not found") +} + +func (zone *Zone) removeSshfpRecord(record *SshfpRecord) error { + for key, r := range zone.Zone.Sshfp { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Sshfp[:key] + if len(zone.Zone.Sshfp) > key { + zone.Zone.Sshfp = append(records, zone.Zone.Sshfp[key+1:]...) + } else { + zone.Zone.Sshfp = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Sshfp Record not found") +} + +func (zone *Zone) removeTxtRecord(record *TxtRecord) error { + for key, r := range zone.Zone.Txt { + if reflect.DeepEqual(r, record) { + records := zone.Zone.Txt[:key] + if len(zone.Zone.Txt) > key { + zone.Zone.Txt = append(records, zone.Zone.Txt[key+1:]...) + } else { + zone.Zone.Txt = records + } + zone.removeNonCnameName(record.Name) + + return nil + } + } + + return errors.New("Txt Record not found") +} + +func (zone *Zone) PostUnmarshalJSON() error { + if zone.Zone.Soa.Serial > 0 { + zone.Zone.Soa.originalSerial = zone.Zone.Soa.Serial + } + return nil +} + +func (zone *Zone) PreMarshalJSON() error { + if zone.Zone.Soa.Serial == 0 { + zone.Zone.Soa.Serial = uint(time.Now().Unix()) + } else if zone.Zone.Soa.Serial == zone.Zone.Soa.originalSerial { + zone.Zone.Soa.Serial = zone.Zone.Soa.Serial + 1 + } + return nil +} + +func (zone *Zone) validateCnames() (bool, []name) { + var valid bool = true + var failedRecords []name + for _, v := range cnameNames { + for _, vv := range nonCnameNames { + if v.name == vv.name { + valid = false + failedRecords = append(failedRecords, vv) + } + } + } + return valid, failedRecords +} + +func (zone *Zone) removeCnameName(host string) { + var ncn []name + for _, v := range cnameNames { + if v.name != host { + ncn = append(ncn, v) + } + } + cnameNames = ncn +} + +func (zone *Zone) removeNonCnameName(host string) { + var ncn []name + for _, v := range nonCnameNames { + if v.name != host { + ncn = append(ncn, v) + } + } + nonCnameNames = ncn +} + +func (zone *Zone) FindRecords(recordType string, options map[string]interface{}) []DNSRecord { + switch strings.ToUpper(recordType) { + case "A": + return zone.findARecord(options) + case "AAAA": + return zone.findAaaaRecord(options) + case "AFSDB": + return zone.findAfsdbRecord(options) + case "CNAME": + return zone.findCnameRecord(options) + case "DNSKEY": + return zone.findDnskeyRecord(options) + case "DS": + return zone.findDsRecord(options) + case "HINFO": + return zone.findHinfoRecord(options) + case "LOC": + return zone.findLocRecord(options) + case "MX": + return zone.findMxRecord(options) + case "NAPTR": + return zone.findNaptrRecord(options) + case "NS": + return zone.findNsRecord(options) + case "NSEC3": + return zone.findNsec3Record(options) + case "NSEC3PARAM": + return zone.findNsec3paramRecord(options) + case "PTR": + return zone.findPtrRecord(options) + case "RP": + return zone.findRpRecord(options) + case "RRSIG": + return zone.findRrsigRecord(options) + case "SPF": + return zone.findSpfRecord(options) + case "SRV": + return zone.findSrvRecord(options) + case "SSHFP": + return zone.findSshfpRecord(options) + case "TXT": + return zone.findTxtRecord(options) + } + + return make([]DNSRecord, 0) +} + +func (zone *Zone) findARecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.A { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + + return found +} + +func (zone *Zone) findAaaaRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Aaaa { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + + return found +} + +func (zone *Zone) findAfsdbRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Afsdb { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if subtype, ok := options["subtype"]; ok && record.Subtype == subtype.(int) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findCnameRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Cname { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findDnskeyRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Dnskey { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if flags, ok := options["flags"]; ok && record.Flags == flags.(int) { + matchCounter++ + } + + if protocol, ok := options["protocol"]; ok && record.Protocol == protocol.(int) { + matchCounter++ + } + + if algorithm, ok := options["algorithm"]; ok && record.Algorithm == algorithm.(int) { + matchCounter++ + } + + if key, ok := options["key"]; ok && record.Key == key.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findDsRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Ds { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if keytag, ok := options["keytag"]; ok && record.Keytag == keytag.(int) { + matchCounter++ + } + + if algorithm, ok := options["algorithm"]; ok && record.Algorithm == algorithm.(int) { + matchCounter++ + } + + if digesttype, ok := options["digesttype"]; ok && record.DigestType == digesttype.(int) { + matchCounter++ + } + + if digest, ok := options["digest"]; ok && record.Digest == digest.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findHinfoRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Hinfo { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if hardware, ok := options["hardware"]; ok && record.Hardware == hardware.(string) { + matchCounter++ + } + + if software, ok := options["software"]; ok && record.Software == software.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findLocRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Loc { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findMxRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Mx { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if priority, ok := options["priority"]; ok && record.Priority == priority.(int) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findNaptrRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Naptr { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if order, ok := options["order"]; ok && record.Order == order.(uint16) { + matchCounter++ + } + + if preference, ok := options["preference"]; ok && record.Preference == preference.(uint16) { + matchCounter++ + } + + if flags, ok := options["flags"]; ok && record.Flags == flags.(string) { + matchCounter++ + } + + if service, ok := options["service"]; ok && record.Service == service.(string) { + matchCounter++ + } + + if regexp, ok := options["regexp"]; ok && record.Regexp == regexp.(string) { + matchCounter++ + } + + if replacement, ok := options["replacement"]; ok && record.Replacement == replacement.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findNsRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Ns { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findNsec3Record(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Nsec3 { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if algorithm, ok := options["algorithm"]; ok && record.Algorithm == algorithm.(int) { + matchCounter++ + } + + if flags, ok := options["flags"]; ok && record.Flags == flags.(int) { + matchCounter++ + } + + if iterations, ok := options["iterations"]; ok && record.Iterations == iterations.(int) { + matchCounter++ + } + + if salt, ok := options["salt"]; ok && record.Salt == salt.(string) { + matchCounter++ + } + + if nextHashedOwnerName, ok := options["nextHashedOwnerName"]; ok && record.NextHashedOwnerName == nextHashedOwnerName.(string) { + matchCounter++ + } + + if typeBitmaps, ok := options["typeBitmaps"]; ok && record.TypeBitmaps == typeBitmaps.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findNsec3paramRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Nsec3param { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if algorithm, ok := options["algorithm"]; ok && record.Algorithm == algorithm.(int) { + matchCounter++ + } + + if flags, ok := options["flags"]; ok && record.Flags == flags.(int) { + matchCounter++ + } + + if iterations, ok := options["iterations"]; ok && record.Iterations == iterations.(int) { + matchCounter++ + } + + if salt, ok := options["salt"]; ok && record.Salt == salt.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findPtrRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Ptr { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findRpRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Rp { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if mailbox, ok := options["mailbox"]; ok && record.Mailbox == mailbox.(string) { + matchCounter++ + } + + if txt, ok := options["txt"]; ok && record.Txt == txt.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findRrsigRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Rrsig { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if typeCovered, ok := options["typeCovered"]; ok && record.TypeCovered == typeCovered.(string) { + matchCounter++ + } + + if algorithm, ok := options["algorithm"]; ok && record.Algorithm == algorithm.(int) { + matchCounter++ + } + + if originalTTL, ok := options["originalTTL"]; ok && record.OriginalTTL == originalTTL.(int) { + matchCounter++ + } + + if expiration, ok := options["expiration"]; ok && record.Expiration == expiration.(string) { + matchCounter++ + } + + if inception, ok := options["inception"]; ok && record.Inception == inception.(string) { + matchCounter++ + } + + if keytag, ok := options["keytag"]; ok && record.Keytag == keytag.(int) { + matchCounter++ + } + + if signer, ok := options["signer"]; ok && record.Signer == signer.(string) { + matchCounter++ + } + + if signature, ok := options["signature"]; ok && record.Signature == signature.(string) { + matchCounter++ + } + + if labels, ok := options["labels"]; ok && record.Labels == labels.(int) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findSpfRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Spf { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findSrvRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Srv { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if priority, ok := options["priority"]; ok && record.Priority == priority.(int) { + matchCounter++ + } + + if weight, ok := options["weight"]; ok && record.Weight == weight.(uint16) { + matchCounter++ + } + + if port, ok := options["port"]; ok && record.Port == port.(uint16) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findSshfpRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Sshfp { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if algorithm, ok := options["algorithm"]; ok && record.Algorithm == algorithm.(int) { + matchCounter++ + } + + if fingerprintType, ok := options["fingerprintType"]; ok && record.FingerprintType == fingerprintType.(int) { + matchCounter++ + } + + if fingerprint, ok := options["fingerprint"]; ok && record.Fingerprint == fingerprint.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} + +func (zone *Zone) findTxtRecord(options map[string]interface{}) []DNSRecord { + found := make([]DNSRecord, 0) + matchesNeeded := len(options) + for _, record := range zone.Zone.Txt { + matchCounter := 0 + if name, ok := options["name"]; ok && record.Name == name.(string) { + matchCounter++ + } + + if active, ok := options["active"]; ok && record.Active == active.(bool) { + matchCounter++ + } + + if ttl, ok := options["ttl"]; ok && record.TTL == ttl.(int) { + matchCounter++ + } + + if target, ok := options["target"]; ok && record.Target == target.(string) { + matchCounter++ + } + + if matchCounter >= matchesNeeded { + found = append(found, record) + } + } + return found +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/README.md b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/README.md new file mode 100644 index 000000000..28fb95087 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/README.md @@ -0,0 +1,2 @@ +# Akamai Edgegrid +A golang package which facilitates authenticating and signing requests made to [Akamai OPEN APIs](https://developer.akamai.com). \ No newline at end of file diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/config.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/config.go new file mode 100644 index 000000000..2bb247ccb --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/config.go @@ -0,0 +1,182 @@ +package edgegrid + +import ( + "fmt" + "os" + "strconv" + "strings" + + "github.com/go-ini/ini" + "github.com/mitchellh/go-homedir" +) + +// Config struct provides all the necessary fields to +// create authorization header, debug is optional +type Config struct { + Host string `ini:"host"` + ClientToken string `ini:"client_token"` + ClientSecret string `ini:"client_secret"` + AccessToken string `ini:"access_token"` + AccountKey string `ini:"account_key"` + HeaderToSign []string `ini:"headers_to_sign"` + MaxBody int `ini:"max_body"` + Debug bool `ini:"debug"` +} + +// Init initializes by first attempting to use ENV vars, with .edgerc as a fallback +// +// See: InitEnv() +// See: InitEdgeRc() +func Init(filepath string, section string) (Config, error) { + if section == "" { + section = defaultSection + } else { + section = strings.ToUpper(section) + } + + _, exists := os.LookupEnv("AKAMAI_" + section + "_HOST") + if !exists && section == defaultSection { + _, exists := os.LookupEnv("AKAMAI_HOST") + + if exists { + return InitEnv("") + } + } + + if exists { + return InitEnv(section) + } + + c, err := InitEdgeRc(filepath, strings.ToLower(section)) + + if err == nil { + return c, nil + } + + if section != defaultSection { + _, ok := os.LookupEnv("AKAMAI_HOST") + if ok { + return InitEnv("") + } + } + + return c, fmt.Errorf("Unable to create instance using environment or .edgerc file") +} + +// InitEdgeRc initializes using a configuration file in standard INI format +// +// By default, it uses the .edgerc found in the users home directory, and the +// "default" section. +func InitEdgeRc(filepath string, section string) (Config, error) { + var ( + c Config + requiredOptions = []string{"host", "client_token", "client_secret", "access_token"} + missing []string + ) + + // Check if filepath is empty + if filepath == "" { + filepath = "~/.edgerc" + } + + // Check if section is empty + if section == "" { + section = "default" + } + + // Tilde seems to be not working when passing ~/.edgerc as file + // Takes current user and use home dir instead + + path, err := homedir.Expand(filepath) + + if err != nil { + return c, fmt.Errorf(errorMap[ErrHomeDirNotFound], err) + } + + edgerc, err := ini.Load(path) + if err != nil { + return c, fmt.Errorf(errorMap[ErrConfigFile], err) + } + err = edgerc.Section(section).MapTo(&c) + if err != nil { + return c, fmt.Errorf(errorMap[ErrConfigFileSection], err) + } + for _, opt := range requiredOptions { + if !(edgerc.Section(section).HasKey(opt)) { + missing = append(missing, opt) + } + } + if len(missing) > 0 { + return c, fmt.Errorf(errorMap[ErrConfigMissingOptions], missing) + } + if c.MaxBody == 0 { + c.MaxBody = 131072 + } + return c, nil +} + +// InitEnv initializes using the Environment (ENV) +// +// By default, it uses AKAMAI_HOST, AKAMAI_CLIENT_TOKEN, AKAMAI_CLIENT_SECRET, +// AKAMAI_ACCESS_TOKEN, and AKAMAI_MAX_BODY variables. +// +// You can define multiple configurations by prefixing with the section name specified, e.g. +// passing "ccu" will cause it to look for AKAMAI_CCU_HOST, etc. +// +// If AKAMAI_{SECTION} does not exist, it will fall back to just AKAMAI_. +func InitEnv(section string) (Config, error) { + var ( + c Config + requiredOptions = []string{"HOST", "CLIENT_TOKEN", "CLIENT_SECRET", "ACCESS_TOKEN"} + missing []string + prefix string + ) + + // Check if section is empty + if section == "" { + section = defaultSection + } else { + section = strings.ToUpper(section) + } + + prefix = "AKAMAI_" + _, ok := os.LookupEnv("AKAMAI_" + section + "_HOST") + if ok { + prefix = "AKAMAI_" + section + "_" + } + + for _, opt := range requiredOptions { + val, ok := os.LookupEnv(prefix + opt) + if !ok { + missing = append(missing, prefix+opt) + } else { + switch { + case opt == "HOST": + c.Host = val + case opt == "CLIENT_TOKEN": + c.ClientToken = val + case opt == "CLIENT_SECRET": + c.ClientSecret = val + case opt == "ACCESS_TOKEN": + c.AccessToken = val + } + } + } + + if len(missing) > 0 { + return c, fmt.Errorf(errorMap[ErrMissingEnvVariables], missing) + } + + c.MaxBody = 0 + + val, ok := os.LookupEnv(prefix + "MAX_BODY") + if i, err := strconv.Atoi(val); err == nil { + c.MaxBody = i + } + + if !ok || c.MaxBody == 0 { + c.MaxBody = 131072 + } + + return c, nil +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/errors.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/errors.go new file mode 100644 index 000000000..d5448aeae --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/errors.go @@ -0,0 +1,22 @@ +package edgegrid + +// Error constants +const ( + ErrUUIDGenerateFailed = 500 + ErrHomeDirNotFound = 501 + ErrConfigFile = 502 + ErrConfigFileSection = 503 + ErrConfigMissingOptions = 504 + ErrMissingEnvVariables = 505 +) + +var ( + errorMap = map[int]string{ + ErrUUIDGenerateFailed: "Generate UUID failed: %s", + ErrHomeDirNotFound: "Fatal could not find home dir from user: %s", + ErrConfigFile: "Fatal error edgegrid file: %s", + ErrConfigFileSection: "Could not map section: %s", + ErrConfigMissingOptions: "Fatal missing required options: %s", + ErrMissingEnvVariables: "Fatal missing required environment variables: %s", + } +) diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/log.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/log.go new file mode 100644 index 000000000..caaacd090 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/log.go @@ -0,0 +1,73 @@ +// Copyright 2018. Akamai Technologies, 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. + +package edgegrid + +import ( + "bufio" + "fmt" + "os" + "strings" + + "github.com/sirupsen/logrus" +) + +var logBuffer *bufio.Writer +var LogFile *os.File + +func SetupLogging(log *logrus.Logger) { + log.SetFormatter(&logrus.TextFormatter{ + DisableLevelTruncation: true, + EnvironmentOverrideColors: true, + }) + // Log file destination specified? If not, use default stdout + if logFileName := os.Getenv("AKAMAI_LOG_FILE"); logFileName != "" { + // If the file doesn't exist, create it, or append to the file + LogFile, err := os.OpenFile(logFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Fatal(err) + } + log.SetOutput(LogFile) + } + + log.SetLevel(logrus.PanicLevel) + if logLevel := os.Getenv("AKAMAI_LOG"); logLevel != "" { + level, err := logrus.ParseLevel(logLevel) + if err == nil { + log.SetLevel(level) + } else { + log.Warningln("[WARN] Unknown AKAMAI_LOG value. Allowed values: panic, fatal, error, warn, info, debug, trace") + + } + } +} + +func LogMultiline(f func(args ...interface{}), args ...string) { + for _, str := range args { + for _, str := range strings.Split(strings.Trim(str, "\n"), "\n") { + f(str) + } + } +} + +func LogMultilineln(f func(args ...interface{}), args ...string) { + LogMultiline(f, args...) +} + +func LogMultilinef(f func(formatter string, args ...interface{}), formatter string, args ...interface{}) { + str := fmt.Sprintf(formatter, args...) + for _, str := range strings.Split(strings.Trim(str, "\n"), "\n") { + f(str) + } +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/signer.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/signer.go new file mode 100644 index 000000000..9f0c1e7c4 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/signer.go @@ -0,0 +1,216 @@ +// Package edgegrid allows you to sign http.Request's using the Akamai OPEN Edgegrid Signing Scheme +package edgegrid + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "fmt" + "io/ioutil" + "net/http" + "os" + "sort" + "strings" + "time" + "unicode" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +const defaultSection = "DEFAULT" + +// AddRequestHeader sets the Authorization header to use Akamai Open API +func AddRequestHeader(config Config, req *http.Request) *http.Request { + if config.Debug { + log.SetLevel(log.DebugLevel) + } + timestamp := makeEdgeTimeStamp() + nonce := createNonce() + + if req.Header.Get("Content-Type") == "" { + req.Header.Set("Content-Type", "application/json") + } + + _, AkamaiCliEnvOK := os.LookupEnv("AKAMAI_CLI") + AkamaiCliVersionEnv, AkamaiCliVersionEnvOK := os.LookupEnv("AKAMAI_CLI_VERSION") + AkamaiCliCommandEnv, AkamaiCliCommandEnvOK := os.LookupEnv("AKAMAI_CLI_COMMAND") + AkamaiCliCommandVersionEnv, AkamaiCliCommandVersionEnvOK := os.LookupEnv("AKAMAI_CLI_COMMAND_VERSION") + + if AkamaiCliEnvOK && AkamaiCliVersionEnvOK { + if req.Header.Get("User-Agent") != "" { + req.Header.Set("User-Agent", req.Header.Get("User-Agent")+" AkamaiCLI/"+AkamaiCliVersionEnv) + } else { + req.Header.Set("User-Agent", "AkamaiCLI/"+AkamaiCliVersionEnv) + } + } + if AkamaiCliCommandEnvOK && AkamaiCliCommandVersionEnvOK { + if req.Header.Get("User-Agent") != "" { + req.Header.Set("User-Agent", req.Header.Get("User-Agent")+" AkamaiCLI-"+AkamaiCliCommandEnv+"/"+AkamaiCliCommandVersionEnv) + } else { + req.Header.Set("User-Agent", "AkamaiCLI-"+AkamaiCliCommandEnv+"/"+AkamaiCliCommandVersionEnv) + } + } + + req.Header.Set("Authorization", createAuthHeader(config, req, timestamp, nonce)) + return req +} + +// Must be assigned the UTC time when the request is signed. +// Format of “yyyyMMddTHH:mm:ss+0000” +func makeEdgeTimeStamp() string { + local := time.FixedZone("GMT", 0) + t := time.Now().In(local) + return fmt.Sprintf("%d%02d%02dT%02d:%02d:%02d+0000", + t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()) +} + +// Must be assigned a nonce (number used once) for the request. +// It is a random string used to detect replayed request messages. +// A GUID is recommended. +func createNonce() string { + uuid, err := uuid.NewRandom() + if err != nil { + log.Errorf(errorMap[ErrUUIDGenerateFailed], err) + return "" + } + return uuid.String() +} + +func stringMinifier(in string) (out string) { + white := false + for _, c := range in { + if unicode.IsSpace(c) { + if !white { + out = out + " " + } + white = true + } else { + out = out + string(c) + white = false + } + } + return +} + +func concatPathQuery(path, query string) string { + if query == "" { + return path + } + return fmt.Sprintf("%s?%s", path, query) +} + +// createSignature is the base64-encoding of the SHA–256 HMAC of the data to sign with the signing key. +func createSignature(message string, secret string) string { + key := []byte(secret) + h := hmac.New(sha256.New, key) + h.Write([]byte(message)) + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +} + +func createHash(data string) string { + h := sha256.Sum256([]byte(data)) + return base64.StdEncoding.EncodeToString(h[:]) +} + +func canonicalizeHeaders(config Config, req *http.Request) string { + var unsortedHeader []string + var sortedHeader []string + for k := range req.Header { + unsortedHeader = append(unsortedHeader, k) + } + sort.Strings(unsortedHeader) + for _, k := range unsortedHeader { + for _, sign := range config.HeaderToSign { + if sign == k { + v := strings.TrimSpace(req.Header.Get(k)) + sortedHeader = append(sortedHeader, fmt.Sprintf("%s:%s", strings.ToLower(k), strings.ToLower(stringMinifier(v)))) + } + } + } + return strings.Join(sortedHeader, "\t") + +} + +// signingKey is derived from the client secret. +// The signing key is computed as the base64 encoding of the SHA–256 HMAC of the timestamp string +// (the field value included in the HTTP authorization header described above) with the client secret as the key. +func signingKey(config Config, timestamp string) string { + key := createSignature(timestamp, config.ClientSecret) + return key +} + +// The content hash is the base64-encoded SHA–256 hash of the POST body. +// For any other request methods, this field is empty. But the tac separator (\t) must be included. +// The size of the POST body must be less than or equal to the value specified by the service. +// Any request that does not meet this criteria SHOULD be rejected during the signing process, +// as the request will be rejected by EdgeGrid. +func createContentHash(config Config, req *http.Request) string { + var ( + contentHash string + preparedBody string + bodyBytes []byte + ) + if req.Body != nil { + bodyBytes, _ = ioutil.ReadAll(req.Body) + req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) + preparedBody = string(bodyBytes) + } + + log.Debugf("Body is %s", preparedBody) + if req.Method == "POST" && len(preparedBody) > 0 { + log.Debugf("Signing content: %s", preparedBody) + if len(preparedBody) > config.MaxBody { + log.Debugf("Data length %d is larger than maximum %d", + len(preparedBody), config.MaxBody) + + preparedBody = preparedBody[0:config.MaxBody] + log.Debugf("Data truncated to %d for computing the hash", len(preparedBody)) + } + contentHash = createHash(preparedBody) + } + log.Debugf("Content hash is '%s'", contentHash) + return contentHash +} + +// The data to sign includes the information from the HTTP request that is relevant to ensuring that the request is authentic. +// This data set comprised of the request data combined with the authorization header value (excluding the signature field, +// but including the ; right before the signature field). +func signingData(config Config, req *http.Request, authHeader string) string { + + dataSign := []string{ + req.Method, + req.URL.Scheme, + req.URL.Host, + concatPathQuery(req.URL.Path, req.URL.RawQuery), + canonicalizeHeaders(config, req), + createContentHash(config, req), + authHeader, + } + log.Debugf("Data to sign %s", strings.Join(dataSign, "\t")) + return strings.Join(dataSign, "\t") +} + +func signingRequest(config Config, req *http.Request, authHeader string, timestamp string) string { + return createSignature(signingData(config, req, authHeader), + signingKey(config, timestamp)) +} + +// The Authorization header starts with the signing algorithm moniker (name of the algorithm) used to sign the request. +// The moniker below identifies EdgeGrid V1, hash message authentication code, SHA–256 as the hash standard. +// This moniker is then followed by a space and an ordered list of name value pairs with each field separated by a semicolon. +func createAuthHeader(config Config, req *http.Request, timestamp string, nonce string) string { + authHeader := fmt.Sprintf("EG1-HMAC-SHA256 client_token=%s;access_token=%s;timestamp=%s;nonce=%s;", + config.ClientToken, + config.AccessToken, + timestamp, + nonce, + ) + log.Debugf("Unsigned authorization header: '%s'", authHeader) + + signedAuthHeader := fmt.Sprintf("%ssignature=%s", authHeader, signingRequest(config, req, authHeader, timestamp)) + + log.Debugf("Signed authorization header: '%s'", signedAuthHeader) + return signedAuthHeader +} diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/README.md b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/README.md new file mode 100644 index 000000000..80f36aab3 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/README.md @@ -0,0 +1 @@ +# Akamai JSONHooks \ No newline at end of file diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/errors.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/errors.go new file mode 100644 index 000000000..594c04e41 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/errors.go @@ -0,0 +1 @@ +package jsonhooks diff --git a/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/jsonhooks.go b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/jsonhooks.go new file mode 100644 index 000000000..24c5b8bb8 --- /dev/null +++ b/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/jsonhooks.go @@ -0,0 +1,69 @@ +// Package jsonhooks adds hooks that are automatically called before JSON marshaling (PreMarshalJSON) and +// after JSON unmarshaling (PostUnmarshalJSON). It does not do so recursively. +package jsonhooks + +import ( + "encoding/json" + "reflect" +) + +// Marshal wraps encoding/json.Marshal, calls v.PreMarshalJSON() if it exists +func Marshal(v interface{}) ([]byte, error) { + if ImplementsPreJSONMarshaler(v) { + err := v.(PreJSONMarshaler).PreMarshalJSON() + if err != nil { + return nil, err + } + } + + return json.Marshal(v) +} + +// Unmarshal wraps encoding/json.Unmarshal, calls v.PostUnmarshalJSON() if it exists +func Unmarshal(data []byte, v interface{}) error { + err := json.Unmarshal(data, v) + if err != nil { + return err + } + + if ImplementsPostJSONUnmarshaler(v) { + err := v.(PostJSONUnmarshaler).PostUnmarshalJSON() + if err != nil { + return err + } + } + + return nil +} + +// PreJSONMarshaler infers support for the PreMarshalJSON pre-hook +type PreJSONMarshaler interface { + PreMarshalJSON() error +} + +// ImplementsPreJSONMarshaler checks for support for the PreMarshalJSON pre-hook +func ImplementsPreJSONMarshaler(v interface{}) bool { + value := reflect.ValueOf(v) + if !value.IsValid() { + return false + } + + _, ok := value.Interface().(PreJSONMarshaler) + return ok +} + +// PostJSONUnmarshaler infers support for the PostUnmarshalJSON post-hook +type PostJSONUnmarshaler interface { + PostUnmarshalJSON() error +} + +// ImplementsPostJSONUnmarshaler checks for support for the PostUnmarshalJSON post-hook +func ImplementsPostJSONUnmarshaler(v interface{}) bool { + value := reflect.ValueOf(v) + if value.Kind() == reflect.Ptr && value.IsNil() { + return false + } + + _, ok := value.Interface().(PostJSONUnmarshaler) + return ok +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/LICENSE @@ -0,0 +1,201 @@ + 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. diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/api_timeout.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/api_timeout.go new file mode 100644 index 000000000..d7968dab7 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/api_timeout.go @@ -0,0 +1,249 @@ +package sdk + +import ( + "encoding/json" + "strings" + "time" +) + +var apiTimeouts = `{ + "ecs": { + "ActivateRouterInterface": 10, + "AddTags": 61, + "AllocateDedicatedHosts": 10, + "AllocateEipAddress": 17, + "AllocatePublicIpAddress": 36, + "ApplyAutoSnapshotPolicy": 10, + "AssignIpv6Addresses": 10, + "AssignPrivateIpAddresses": 10, + "AssociateEipAddress": 17, + "AttachClassicLinkVpc": 14, + "AttachDisk": 36, + "AttachInstanceRamRole": 11, + "AttachKeyPair": 16, + "AttachNetworkInterface": 16, + "AuthorizeSecurityGroupEgress": 16, + "AuthorizeSecurityGroup": 16, + "CancelAutoSnapshotPolicy": 10, + "CancelCopyImage": 10, + "CancelPhysicalConnection": 10, + "CancelSimulatedSystemEvents": 10, + "CancelTask": 10, + "ConnectRouterInterface": 10, + "ConvertNatPublicIpToEip": 12, + "CopyImage": 10, + "CreateAutoSnapshotPolicy": 10, + "CreateCommand": 16, + "CreateDeploymentSet": 16, + "CreateDisk": 36, + "CreateHpcCluster": 10, + "CreateImage": 36, + "CreateInstance": 86, + "CreateKeyPair": 10, + "CreateLaunchTemplate": 10, + "CreateLaunchTemplateVersion": 10, + "CreateNatGateway": 36, + "CreateNetworkInterfacePermission": 13, + "CreateNetworkInterface": 16, + "CreatePhysicalConnection": 10, + "CreateRouteEntry": 17, + "CreateRouterInterface": 10, + "CreateSecurityGroup": 86, + "CreateSimulatedSystemEvents": 10, + "CreateSnapshot": 86, + "CreateVirtualBorderRouter": 10, + "CreateVpc": 16, + "CreateVSwitch": 17, + "DeactivateRouterInterface": 10, + "DeleteAutoSnapshotPolicy": 10, + "DeleteBandwidthPackage": 10, + "DeleteCommand": 16, + "DeleteDeploymentSet": 12, + "DeleteDisk": 16, + "DeleteHpcCluster": 10, + "DeleteImage": 36, + "DeleteInstance": 66, + "DeleteKeyPairs": 10, + "DeleteLaunchTemplate": 10, + "DeleteLaunchTemplateVersion": 10, + "DeleteNatGateway": 10, + "DeleteNetworkInterfacePermission": 10, + "DeleteNetworkInterface": 16, + "DeletePhysicalConnection": 10, + "DeleteRouteEntry": 16, + "DeleteRouterInterface": 10, + "DeleteSecurityGroup": 87, + "DeleteSnapshot": 17, + "DeleteVirtualBorderRouter": 10, + "DeleteVpc": 17, + "DeleteVSwitch": 17, + "DescribeAccessPoints": 10, + "DescribeAccountAttributes": 10, + "DescribeAutoSnapshotPolicyEx": 16, + "DescribeAvailableResource": 10, + "DescribeBandwidthLimitation": 16, + "DescribeBandwidthPackages": 10, + "DescribeClassicLinkInstances": 15, + "DescribeCloudAssistantStatus": 16, + "DescribeClusters": 10, + "DescribeCommands": 16, + "DescribeDedicatedHosts": 10, + "DescribeDedicatedHostTypes": 10, + "DescribeDeploymentSets": 26, + "DescribeDiskMonitorData": 16, + "DescribeDisksFullStatus": 14, + "DescribeDisks": 19, + "DescribeEipAddresses": 16, + "DescribeEipMonitorData": 16, + "DescribeEniMonitorData": 10, + "DescribeHaVips": 10, + "DescribeHpcClusters": 16, + "DescribeImageSharePermission": 10, + "DescribeImages": 38, + "DescribeImageSupportInstanceTypes": 16, + "DescribeInstanceAttribute": 36, + "DescribeInstanceAutoRenewAttribute": 17, + "DescribeInstanceHistoryEvents": 19, + "DescribeInstanceMonitorData": 19, + "DescribeInstancePhysicalAttribute": 10, + "DescribeInstanceRamRole": 11, + "DescribeInstancesFullStatus": 14, + "DescribeInstances": 10, + "DescribeInstanceStatus": 26, + "DescribeInstanceTopology": 12, + "DescribeInstanceTypeFamilies": 17, + "DescribeInstanceTypes": 17, + "DescribeInstanceVncPasswd": 10, + "DescribeInstanceVncUrl": 36, + "DescribeInvocationResults": 16, + "DescribeInvocations": 16, + "DescribeKeyPairs": 12, + "DescribeLaunchTemplates": 16, + "DescribeLaunchTemplateVersions": 16, + "DescribeLimitation": 36, + "DescribeNatGateways": 10, + "DescribeNetworkInterfacePermissions": 13, + "DescribeNetworkInterfaces": 16, + "DescribeNewProjectEipMonitorData": 16, + "DescribePhysicalConnections": 10, + "DescribePrice": 16, + "DescribeRecommendInstanceType": 10, + "DescribeRegions": 19, + "DescribeRenewalPrice": 16, + "DescribeResourceByTags": 10, + "DescribeResourcesModification": 17, + "DescribeRouterInterfaces": 10, + "DescribeRouteTables": 17, + "DescribeSecurityGroupAttribute": 133, + "DescribeSecurityGroupReferences": 16, + "DescribeSecurityGroups": 25, + "DescribeSnapshotLinks": 17, + "DescribeSnapshotMonitorData": 12, + "DescribeSnapshotPackage": 10, + "DescribeSnapshots": 26, + "DescribeSnapshotsUsage": 26, + "DescribeSpotPriceHistory": 22, + "DescribeTags": 17, + "DescribeTaskAttribute": 10, + "DescribeTasks": 11, + "DescribeUserBusinessBehavior": 13, + "DescribeUserData": 10, + "DescribeVirtualBorderRoutersForPhysicalConnection": 10, + "DescribeVirtualBorderRouters": 10, + "DescribeVpcs": 41, + "DescribeVRouters": 17, + "DescribeVSwitches": 17, + "DescribeZones": 103, + "DetachClassicLinkVpc": 14, + "DetachDisk": 17, + "DetachInstanceRamRole": 10, + "DetachKeyPair": 10, + "DetachNetworkInterface": 16, + "EipFillParams": 19, + "EipFillProduct": 13, + "EipNotifyPaid": 10, + "EnablePhysicalConnection": 10, + "ExportImage": 10, + "GetInstanceConsoleOutput": 14, + "GetInstanceScreenshot": 14, + "ImportImage": 29, + "ImportKeyPair": 10, + "InstallCloudAssistant": 10, + "InvokeCommand": 16, + "JoinResourceGroup": 10, + "JoinSecurityGroup": 66, + "LeaveSecurityGroup": 66, + "ModifyAutoSnapshotPolicyEx": 10, + "ModifyBandwidthPackageSpec": 11, + "ModifyCommand": 10, + "ModifyDeploymentSetAttribute": 10, + "ModifyDiskAttribute": 16, + "ModifyDiskChargeType": 13, + "ModifyEipAddressAttribute": 14, + "ModifyImageAttribute": 10, + "ModifyImageSharePermission": 16, + "ModifyInstanceAttribute": 22, + "ModifyInstanceAutoReleaseTime": 15, + "ModifyInstanceAutoRenewAttribute": 16, + "ModifyInstanceChargeType": 22, + "ModifyInstanceDeployment": 10, + "ModifyInstanceNetworkSpec": 36, + "ModifyInstanceSpec": 62, + "ModifyInstanceVncPasswd": 35, + "ModifyInstanceVpcAttribute": 15, + "ModifyLaunchTemplateDefaultVersion": 10, + "ModifyNetworkInterfaceAttribute": 10, + "ModifyPhysicalConnectionAttribute": 10, + "ModifyPrepayInstanceSpec": 13, + "ModifyRouterInterfaceAttribute": 10, + "ModifySecurityGroupAttribute": 10, + "ModifySecurityGroupEgressRule": 10, + "ModifySecurityGroupPolicy": 10, + "ModifySecurityGroupRule": 16, + "ModifySnapshotAttribute": 10, + "ModifyUserBusinessBehavior": 10, + "ModifyVirtualBorderRouterAttribute": 10, + "ModifyVpcAttribute": 10, + "ModifyVRouterAttribute": 10, + "ModifyVSwitchAttribute": 10, + "ReActivateInstances": 10, + "RebootInstance": 27, + "RedeployInstance": 14, + "ReInitDisk": 16, + "ReleaseDedicatedHost": 10, + "ReleaseEipAddress": 16, + "ReleasePublicIpAddress": 10, + "RemoveTags": 10, + "RenewInstance": 19, + "ReplaceSystemDisk": 36, + "ResetDisk": 36, + "ResizeDisk": 11, + "RevokeSecurityGroupEgress": 13, + "RevokeSecurityGroup": 16, + "RunInstances": 86, + "StartInstance": 46, + "StopInstance": 27, + "StopInvocation": 10, + "TerminatePhysicalConnection": 10, + "TerminateVirtualBorderRouter": 10, + "UnassignIpv6Addresses": 10, + "UnassignPrivateIpAddresses": 10, + "UnassociateEipAddress": 16 + } +} +` + +func getAPIMaxTimeout(product, actionName string) (time.Duration, bool) { + timeout := make(map[string]map[string]int) + err := json.Unmarshal([]byte(apiTimeouts), &timeout) + if err != nil { + return 0 * time.Millisecond, false + } + + obj := timeout[strings.ToLower(product)] + if obj != nil && obj[actionName] != 0 { + return time.Duration(obj[actionName]) * time.Second, true + } + + return 0 * time.Millisecond, false +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go new file mode 100644 index 000000000..7f20b7a40 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credential.go @@ -0,0 +1,18 @@ +/* + * 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. + */ + +package auth + +type Credential interface { +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go new file mode 100644 index 000000000..68f822633 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/access_key_credential.go @@ -0,0 +1,34 @@ +package credentials + +// Deprecated: Use AccessKeyCredential in this package instead. +type BaseCredential struct { + AccessKeyId string + AccessKeySecret string +} + +type AccessKeyCredential struct { + AccessKeyId string + AccessKeySecret string +} + +// Deprecated: Use NewAccessKeyCredential in this package instead. +func NewBaseCredential(accessKeyId, accessKeySecret string) *BaseCredential { + return &BaseCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + } +} + +func (baseCred *BaseCredential) ToAccessKeyCredential() *AccessKeyCredential { + return &AccessKeyCredential{ + AccessKeyId: baseCred.AccessKeyId, + AccessKeySecret: baseCred.AccessKeySecret, + } +} + +func NewAccessKeyCredential(accessKeyId, accessKeySecret string) *AccessKeyCredential { + return &AccessKeyCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go new file mode 100644 index 000000000..6d4763e66 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/bearer_token_credential.go @@ -0,0 +1,12 @@ +package credentials + +type BearerTokenCredential struct { + BearerToken string +} + +// NewBearerTokenCredential return a BearerTokenCredential object +func NewBearerTokenCredential(token string) *BearerTokenCredential { + return &BearerTokenCredential{ + BearerToken: token, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go new file mode 100644 index 000000000..55a5c2da0 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/ecs_ram_role.go @@ -0,0 +1,29 @@ +package credentials + +func (oldCred *StsRoleNameOnEcsCredential) ToEcsRamRoleCredential() *EcsRamRoleCredential { + return &EcsRamRoleCredential{ + RoleName: oldCred.RoleName, + } +} + +type EcsRamRoleCredential struct { + RoleName string +} + +func NewEcsRamRoleCredential(roleName string) *EcsRamRoleCredential { + return &EcsRamRoleCredential{ + RoleName: roleName, + } +} + +// Deprecated: Use EcsRamRoleCredential in this package instead. +type StsRoleNameOnEcsCredential struct { + RoleName string +} + +// Deprecated: Use NewEcsRamRoleCredential in this package instead. +func NewStsRoleNameOnEcsCredential(roleName string) *StsRoleNameOnEcsCredential { + return &StsRoleNameOnEcsCredential{ + RoleName: roleName, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go new file mode 100644 index 000000000..3cd0d020a --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/env.go @@ -0,0 +1,30 @@ +package provider + +import ( + "errors" + "os" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" +) + +type EnvProvider struct{} + +var ProviderEnv = new(EnvProvider) + +func NewEnvProvider() Provider { + return &EnvProvider{} +} + +func (p *EnvProvider) Resolve() (auth.Credential, error) { + accessKeyID, ok1 := os.LookupEnv(ENVAccessKeyID) + accessKeySecret, ok2 := os.LookupEnv(ENVAccessKeySecret) + if !ok1 || !ok2 { + return nil, nil + } + if accessKeyID == "" || accessKeySecret == "" { + return nil, errors.New("Environmental variable (ALIBABACLOUD_ACCESS_KEY_ID or ALIBABACLOUD_ACCESS_KEY_SECRET) is empty") + } + return credentials.NewAccessKeyCredential(accessKeyID, accessKeySecret), nil +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go new file mode 100644 index 000000000..1906d21f6 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/instance_credentials.go @@ -0,0 +1,92 @@ +package provider + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/" + +type InstanceCredentialsProvider struct{} + +var ProviderInstance = new(InstanceCredentialsProvider) + +var HookGet = func(fn func(string) (int, []byte, error)) func(string) (int, []byte, error) { + return fn +} + +func NewInstanceCredentialsProvider() Provider { + return &InstanceCredentialsProvider{} +} + +func (p *InstanceCredentialsProvider) Resolve() (auth.Credential, error) { + roleName, ok := os.LookupEnv(ENVEcsMetadata) + if !ok { + return nil, nil + } + if roleName == "" { + return nil, errors.New("Environmental variable 'ALIBABA_CLOUD_ECS_METADATA' are empty") + } + status, content, err := HookGet(get)(securityCredURL + roleName) + if err != nil { + return nil, err + } + if status != 200 { + if status == 404 { + return nil, fmt.Errorf("The role was not found in the instance") + } + return nil, fmt.Errorf("Received %d when getting security credentials for %s", status, roleName) + } + body := make(map[string]interface{}) + + if err := json.Unmarshal(content, &body); err != nil { + return nil, err + } + + accessKeyID, err := extractString(body, "AccessKeyId") + if err != nil { + return nil, err + } + accessKeySecret, err := extractString(body, "AccessKeySecret") + if err != nil { + return nil, err + } + securityToken, err := extractString(body, "SecurityToken") + if err != nil { + return nil, err + } + + return credentials.NewStsTokenCredential(accessKeyID, accessKeySecret, securityToken), nil +} + +func get(url string) (status int, content []byte, err error) { + httpClient := http.DefaultClient + httpClient.Timeout = time.Second * 1 + resp, err := httpClient.Get(url) + if err != nil { + return + } + defer resp.Body.Close() + content, err = ioutil.ReadAll(resp.Body) + return resp.StatusCode, content, err +} + +func extractString(m map[string]interface{}, key string) (string, error) { + raw, ok := m[key] + if !ok { + return "", fmt.Errorf("%s not in map", key) + } + str, ok := raw.(string) + if !ok { + return "", fmt.Errorf("%s is not a string in map", key) + } + return str, nil +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go new file mode 100644 index 000000000..8d525c37a --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/profile_credentials.go @@ -0,0 +1,158 @@ +package provider + +import ( + "bufio" + "errors" + "os" + "runtime" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + + ini "gopkg.in/ini.v1" +) + +type ProfileProvider struct { + Profile string +} + +var ProviderProfile = NewProfileProvider() + +// NewProfileProvider receive zero or more parameters, +// when length of name is 0, the value of field Profile will be "default", +// and when there are multiple inputs, the function will take the +// first one and discard the other values. +func NewProfileProvider(name ...string) Provider { + p := new(ProfileProvider) + if len(name) == 0 { + p.Profile = "default" + } else { + p.Profile = name[0] + } + return p +} + +// Resolve implements the Provider interface +// when credential type is rsa_key_pair, the content of private_key file +// must be able to be parsed directly into the required string +// that NewRsaKeyPairCredential function needed +func (p *ProfileProvider) Resolve() (auth.Credential, error) { + path, ok := os.LookupEnv(ENVCredentialFile) + if !ok { + path, err := checkDefaultPath() + if err != nil { + return nil, err + } + if path == "" { + return nil, nil + } + } else if path == "" { + return nil, errors.New("Environment variable '" + ENVCredentialFile + "' cannot be empty") + } + + ini, err := ini.Load(path) + if err != nil { + return nil, errors.New("ERROR: Can not open file" + err.Error()) + } + + section, err := ini.GetSection(p.Profile) + if err != nil { + return nil, errors.New("ERROR: Can not load section" + err.Error()) + } + + value, err := section.GetKey("type") + if err != nil { + return nil, errors.New("ERROR: Can not find credential type" + err.Error()) + } + + switch value.String() { + case "access_key": + value1, err1 := section.GetKey("access_key_id") + value2, err2 := section.GetKey("access_key_secret") + if err1 != nil || err2 != nil { + return nil, errors.New("ERROR: Failed to get value") + } + if value1.String() == "" || value2.String() == "" { + return nil, errors.New("ERROR: Value can't be empty") + } + return credentials.NewAccessKeyCredential(value1.String(), value2.String()), nil + case "ecs_ram_role": + value1, err1 := section.GetKey("role_name") + if err1 != nil { + return nil, errors.New("ERROR: Failed to get value") + } + if value1.String() == "" { + return nil, errors.New("ERROR: Value can't be empty") + } + return credentials.NewEcsRamRoleCredential(value1.String()), nil + case "ram_role_arn": + value1, err1 := section.GetKey("access_key_id") + value2, err2 := section.GetKey("access_key_secret") + value3, err3 := section.GetKey("role_arn") + value4, err4 := section.GetKey("role_session_name") + if err1 != nil || err2 != nil || err3 != nil || err4 != nil { + return nil, errors.New("ERROR: Failed to get value") + } + if value1.String() == "" || value2.String() == "" || value3.String() == "" || value4.String() == "" { + return nil, errors.New("ERROR: Value can't be empty") + } + return credentials.NewRamRoleArnCredential(value1.String(), value2.String(), value3.String(), value4.String(), 3600), nil + case "rsa_key_pair": + value1, err1 := section.GetKey("public_key_id") + value2, err2 := section.GetKey("private_key_file") + if err1 != nil || err2 != nil { + return nil, errors.New("ERROR: Failed to get value") + } + if value1.String() == "" || value2.String() == "" { + return nil, errors.New("ERROR: Value can't be empty") + } + file, err := os.Open(value2.String()) + if err != nil { + return nil, errors.New("ERROR: Can not get private_key") + } + defer file.Close() + var privateKey string + scan := bufio.NewScanner(file) + var data string + for scan.Scan() { + if strings.HasPrefix(scan.Text(), "----") { + continue + } + data += scan.Text() + "\n" + } + return credentials.NewRsaKeyPairCredential(privateKey, value1.String(), 3600), nil + default: + return nil, errors.New("ERROR: Failed to get credential") + } +} + +// GetHomePath return home directory according to the system. +// if the environmental virables does not exist, will return empty +func GetHomePath() string { + if runtime.GOOS == "windows" { + path, ok := os.LookupEnv("USERPROFILE") + if !ok { + return "" + } + return path + } + path, ok := os.LookupEnv("HOME") + if !ok { + return "" + } + return path +} + +func checkDefaultPath() (path string, err error) { + path = GetHomePath() + if path == "" { + return "", errors.New("The default credential file path is invalid") + } + path = strings.Replace("~/.alibabacloud/credentials", "~", path, 1) + _, err = os.Stat(path) + if err != nil { + return "", nil + } + return path, nil +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go new file mode 100644 index 000000000..ae4e168eb --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider.go @@ -0,0 +1,19 @@ +package provider + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" +) + +//Environmental virables that may be used by the provider +const ( + ENVAccessKeyID = "ALIBABA_CLOUD_ACCESS_KEY_ID" + ENVAccessKeySecret = "ALIBABA_CLOUD_ACCESS_KEY_SECRET" + ENVCredentialFile = "ALIBABA_CLOUD_CREDENTIALS_FILE" + ENVEcsMetadata = "ALIBABA_CLOUD_ECS_METADATA" + PATHCredentialFile = "~/.alibabacloud/credentials" +) + +// When you want to customize the provider, you only need to implement the method of the interface. +type Provider interface { + Resolve() (auth.Credential, error) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go new file mode 100644 index 000000000..3f9315d13 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider/provider_chain.go @@ -0,0 +1,34 @@ +package provider + +import ( + "errors" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" +) + +type ProviderChain struct { + Providers []Provider +} + +var defaultproviders = []Provider{ProviderEnv, ProviderProfile, ProviderInstance} +var DefaultChain = NewProviderChain(defaultproviders) + +func NewProviderChain(providers []Provider) Provider { + return &ProviderChain{ + Providers: providers, + } +} + +func (p *ProviderChain) Resolve() (auth.Credential, error) { + for _, provider := range p.Providers { + creds, err := provider.Resolve() + if err != nil { + return nil, err + } else if err == nil && creds == nil { + continue + } + return creds, err + } + return nil, errors.New("No credential found") + +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go new file mode 100644 index 000000000..00d688eb8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/rsa_key_pair_credential.go @@ -0,0 +1,15 @@ +package credentials + +type RsaKeyPairCredential struct { + PrivateKey string + PublicKeyId string + SessionExpiration int +} + +func NewRsaKeyPairCredential(privateKey, publicKeyId string, sessionExpiration int) *RsaKeyPairCredential { + return &RsaKeyPairCredential{ + PrivateKey: privateKey, + PublicKeyId: publicKeyId, + SessionExpiration: sessionExpiration, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go new file mode 100644 index 000000000..554431ff0 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_credential.go @@ -0,0 +1,15 @@ +package credentials + +type StsTokenCredential struct { + AccessKeyId string + AccessKeySecret string + AccessKeyStsToken string +} + +func NewStsTokenCredential(accessKeyId, accessKeySecret, accessKeyStsToken string) *StsTokenCredential { + return &StsTokenCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + AccessKeyStsToken: accessKeyStsToken, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go new file mode 100644 index 000000000..27602fd74 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/sts_role_arn_credential.go @@ -0,0 +1,61 @@ +package credentials + +// Deprecated: Use RamRoleArnCredential in this package instead. +type StsRoleArnCredential struct { + AccessKeyId string + AccessKeySecret string + RoleArn string + RoleSessionName string + RoleSessionExpiration int +} + +type RamRoleArnCredential struct { + AccessKeyId string + AccessKeySecret string + RoleArn string + RoleSessionName string + RoleSessionExpiration int + Policy string +} + +// Deprecated: Use RamRoleArnCredential in this package instead. +func NewStsRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *StsRoleArnCredential { + return &StsRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + RoleSessionExpiration: roleSessionExpiration, + } +} + +func (oldCred *StsRoleArnCredential) ToRamRoleArnCredential() *RamRoleArnCredential { + return &RamRoleArnCredential{ + AccessKeyId: oldCred.AccessKeyId, + AccessKeySecret: oldCred.AccessKeySecret, + RoleArn: oldCred.RoleArn, + RoleSessionName: oldCred.RoleSessionName, + RoleSessionExpiration: oldCred.RoleSessionExpiration, + } +} + +func NewRamRoleArnCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName string, roleSessionExpiration int) *RamRoleArnCredential { + return &RamRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + RoleSessionExpiration: roleSessionExpiration, + } +} + +func NewRamRoleArnWithPolicyCredential(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string, roleSessionExpiration int) *RamRoleArnCredential { + return &RamRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + RoleSessionExpiration: roleSessionExpiration, + Policy: policy, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go new file mode 100644 index 000000000..8b4037a00 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/roa_signature_composer.go @@ -0,0 +1,136 @@ +/* + * 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. + */ + +package auth + +import ( + "bytes" + "sort" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +var debug utils.Debug + +var hookGetDate = func(fn func() string) string { + return fn() +} + +func init() { + debug = utils.Init("sdk") +} + +func signRoaRequest(request requests.AcsRequest, signer Signer, regionId string) (err error) { + completeROASignParams(request, signer, regionId) + stringToSign := buildRoaStringToSign(request) + request.SetStringToSign(stringToSign) + accessKeyId, err := signer.GetAccessKeyId() + if err != nil { + return err + } + + signature := signer.Sign(stringToSign, "") + request.GetHeaders()["Authorization"] = "acs " + accessKeyId + ":" + signature + + return +} + +func completeROASignParams(request requests.AcsRequest, signer Signer, regionId string) { + headerParams := request.GetHeaders() + + // complete query params + queryParams := request.GetQueryParams() + //if _, ok := queryParams["RegionId"]; !ok { + // queryParams["RegionId"] = regionId + //} + if extraParam := signer.GetExtraParam(); extraParam != nil { + for key, value := range extraParam { + if key == "SecurityToken" { + headerParams["x-acs-security-token"] = value + continue + } + if key == "BearerToken" { + headerParams["x-acs-bearer-token"] = value + continue + } + queryParams[key] = value + } + } + + // complete header params + headerParams["Date"] = hookGetDate(utils.GetTimeInFormatRFC2616) + headerParams["x-acs-signature-method"] = signer.GetName() + headerParams["x-acs-signature-version"] = signer.GetVersion() + if request.GetFormParams() != nil && len(request.GetFormParams()) > 0 { + formString := utils.GetUrlFormedMap(request.GetFormParams()) + request.SetContent([]byte(formString)) + headerParams["Content-Type"] = requests.Form + } + contentMD5 := utils.GetMD5Base64(request.GetContent()) + headerParams["Content-MD5"] = contentMD5 + if _, contains := headerParams["Content-Type"]; !contains { + headerParams["Content-Type"] = requests.Raw + } + switch format := request.GetAcceptFormat(); format { + case "JSON": + headerParams["Accept"] = requests.Json + case "XML": + headerParams["Accept"] = requests.Xml + default: + headerParams["Accept"] = requests.Raw + } +} + +func buildRoaStringToSign(request requests.AcsRequest) (stringToSign string) { + + headers := request.GetHeaders() + + stringToSignBuilder := bytes.Buffer{} + stringToSignBuilder.WriteString(request.GetMethod()) + stringToSignBuilder.WriteString(requests.HeaderSeparator) + + // append header keys for sign + appendIfContain(headers, &stringToSignBuilder, "Accept", requests.HeaderSeparator) + appendIfContain(headers, &stringToSignBuilder, "Content-MD5", requests.HeaderSeparator) + appendIfContain(headers, &stringToSignBuilder, "Content-Type", requests.HeaderSeparator) + appendIfContain(headers, &stringToSignBuilder, "Date", requests.HeaderSeparator) + + // sort and append headers witch starts with 'x-acs-' + var acsHeaders []string + for key := range headers { + if strings.HasPrefix(key, "x-acs-") { + acsHeaders = append(acsHeaders, key) + } + } + sort.Strings(acsHeaders) + for _, key := range acsHeaders { + stringToSignBuilder.WriteString(key + ":" + headers[key]) + stringToSignBuilder.WriteString(requests.HeaderSeparator) + } + + // append query params + stringToSignBuilder.WriteString(request.BuildQueries()) + stringToSign = stringToSignBuilder.String() + debug("stringToSign: %s", stringToSign) + return +} + +func appendIfContain(sourceMap map[string]string, target *bytes.Buffer, key, separator string) { + if value, contain := sourceMap[key]; contain && len(value) > 0 { + target.WriteString(sourceMap[key]) + target.WriteString(separator) + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go new file mode 100644 index 000000000..33967b9ef --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/rpc_signature_composer.go @@ -0,0 +1,94 @@ +/* + * 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. + */ + +package auth + +import ( + "net/url" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +var hookGetNonce = func(fn func() string) string { + return fn() +} + +func signRpcRequest(request requests.AcsRequest, signer Signer, regionId string) (err error) { + err = completeRpcSignParams(request, signer, regionId) + if err != nil { + return + } + // remove while retry + if _, containsSign := request.GetQueryParams()["Signature"]; containsSign { + delete(request.GetQueryParams(), "Signature") + } + stringToSign := buildRpcStringToSign(request) + request.SetStringToSign(stringToSign) + signature := signer.Sign(stringToSign, "&") + request.GetQueryParams()["Signature"] = signature + + return +} + +func completeRpcSignParams(request requests.AcsRequest, signer Signer, regionId string) (err error) { + queryParams := request.GetQueryParams() + queryParams["Version"] = request.GetVersion() + queryParams["Action"] = request.GetActionName() + queryParams["Format"] = request.GetAcceptFormat() + queryParams["Timestamp"] = hookGetDate(utils.GetTimeInFormatISO8601) + queryParams["SignatureMethod"] = signer.GetName() + queryParams["SignatureType"] = signer.GetType() + queryParams["SignatureVersion"] = signer.GetVersion() + queryParams["SignatureNonce"] = hookGetNonce(utils.GetUUID) + queryParams["AccessKeyId"], err = signer.GetAccessKeyId() + + if err != nil { + return + } + + if _, contains := queryParams["RegionId"]; !contains { + queryParams["RegionId"] = regionId + } + if extraParam := signer.GetExtraParam(); extraParam != nil { + for key, value := range extraParam { + queryParams[key] = value + } + } + + request.GetHeaders()["Content-Type"] = requests.Form + formString := utils.GetUrlFormedMap(request.GetFormParams()) + request.SetContent([]byte(formString)) + + return +} + +func buildRpcStringToSign(request requests.AcsRequest) (stringToSign string) { + signParams := make(map[string]string) + for key, value := range request.GetQueryParams() { + signParams[key] = value + } + for key, value := range request.GetFormParams() { + signParams[key] = value + } + + stringToSign = utils.GetUrlFormedMap(signParams) + stringToSign = strings.Replace(stringToSign, "+", "%20", -1) + stringToSign = strings.Replace(stringToSign, "*", "%2A", -1) + stringToSign = strings.Replace(stringToSign, "%7E", "~", -1) + stringToSign = url.QueryEscape(stringToSign) + stringToSign = request.GetMethod() + "&%2F&" + stringToSign + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go new file mode 100644 index 000000000..cbbc3cef7 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signer.go @@ -0,0 +1,98 @@ +/* + * 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. + */ + +package auth + +import ( + "fmt" + "reflect" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +type Signer interface { + GetName() string + GetType() string + GetVersion() string + GetAccessKeyId() (string, error) + GetExtraParam() map[string]string + Sign(stringToSign, secretSuffix string) string +} + +func NewSignerWithCredential(credential Credential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer Signer, err error) { + switch instance := credential.(type) { + case *credentials.AccessKeyCredential: + { + signer = signers.NewAccessKeySigner(instance) + } + case *credentials.StsTokenCredential: + { + signer = signers.NewStsTokenSigner(instance) + } + case *credentials.BearerTokenCredential: + { + signer = signers.NewBearerTokenSigner(instance) + } + case *credentials.RamRoleArnCredential: + { + signer, err = signers.NewRamRoleArnSigner(instance, commonApi) + } + case *credentials.RsaKeyPairCredential: + { + signer, err = signers.NewSignerKeyPair(instance, commonApi) + } + case *credentials.EcsRamRoleCredential: + { + signer = signers.NewEcsRamRoleSigner(instance, commonApi) + } + case *credentials.BaseCredential: // deprecated user interface + { + signer = signers.NewAccessKeySigner(instance.ToAccessKeyCredential()) + } + case *credentials.StsRoleArnCredential: // deprecated user interface + { + signer, err = signers.NewRamRoleArnSigner(instance.ToRamRoleArnCredential(), commonApi) + } + case *credentials.StsRoleNameOnEcsCredential: // deprecated user interface + { + signer = signers.NewEcsRamRoleSigner(instance.ToEcsRamRoleCredential(), commonApi) + } + default: + message := fmt.Sprintf(errors.UnsupportedCredentialErrorMessage, reflect.TypeOf(credential)) + err = errors.NewClientError(errors.UnsupportedCredentialErrorCode, message, nil) + } + return +} + +func Sign(request requests.AcsRequest, signer Signer, regionId string) (err error) { + switch request.GetStyle() { + case requests.ROA: + { + err = signRoaRequest(request, signer, regionId) + } + case requests.RPC: + { + err = signRpcRequest(request, signer, regionId) + } + default: + message := fmt.Sprintf(errors.UnknownRequestTypeErrorMessage, reflect.TypeOf(request)) + err = errors.NewClientError(errors.UnknownRequestTypeErrorCode, message, nil) + } + + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go new file mode 100644 index 000000000..887f50209 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/algorithms.go @@ -0,0 +1,57 @@ +/* + * 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. + */ + +package signers + +import ( + "crypto" + "crypto/hmac" + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "crypto/x509" + "encoding/base64" +) + +func ShaHmac1(source, secret string) string { + key := []byte(secret) + hmac := hmac.New(sha1.New, key) + hmac.Write([]byte(source)) + signedBytes := hmac.Sum(nil) + signedString := base64.StdEncoding.EncodeToString(signedBytes) + return signedString +} + +func Sha256WithRsa(source, secret string) string { + // block, _ := pem.Decode([]byte(secret)) + decodeString, err := base64.StdEncoding.DecodeString(secret) + if err != nil { + panic(err) + } + private, err := x509.ParsePKCS8PrivateKey(decodeString) + if err != nil { + panic(err) + } + + h := crypto.Hash.New(crypto.SHA256) + h.Write([]byte(source)) + hashed := h.Sum(nil) + signature, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey), + crypto.SHA256, hashed) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(signature) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go new file mode 100644 index 000000000..ba291a41e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/credential_updater.go @@ -0,0 +1,54 @@ +/* + * 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. + */ + +package signers + +import ( + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +const defaultInAdvanceScale = 0.95 + +type credentialUpdater struct { + credentialExpiration int + lastUpdateTimestamp int64 + inAdvanceScale float64 + buildRequestMethod func() (*requests.CommonRequest, error) + responseCallBack func(response *responses.CommonResponse) error + refreshApi func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) +} + +func (updater *credentialUpdater) needUpdateCredential() (result bool) { + if updater.inAdvanceScale == 0 { + updater.inAdvanceScale = defaultInAdvanceScale + } + return time.Now().Unix()-updater.lastUpdateTimestamp >= int64(float64(updater.credentialExpiration)*updater.inAdvanceScale) +} + +func (updater *credentialUpdater) updateCredential() (err error) { + request, err := updater.buildRequestMethod() + if err != nil { + return + } + response, err := updater.refreshApi(request) + if err != nil { + return + } + updater.lastUpdateTimestamp = time.Now().Unix() + err = updater.responseCallBack(response) + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go new file mode 100644 index 000000000..99c624c88 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/session_credential.go @@ -0,0 +1,7 @@ +package signers + +type SessionCredential struct { + AccessKeyId string + AccessKeySecret string + StsToken string +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go new file mode 100644 index 000000000..bc4f35b85 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_access_key.go @@ -0,0 +1,54 @@ +/* + * 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. + */ + +package signers + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +type AccessKeySigner struct { + credential *credentials.AccessKeyCredential +} + +func (signer *AccessKeySigner) GetExtraParam() map[string]string { + return nil +} + +func NewAccessKeySigner(credential *credentials.AccessKeyCredential) *AccessKeySigner { + return &AccessKeySigner{ + credential: credential, + } +} + +func (*AccessKeySigner) GetName() string { + return "HMAC-SHA1" +} + +func (*AccessKeySigner) GetType() string { + return "" +} + +func (*AccessKeySigner) GetVersion() string { + return "1.0" +} + +func (signer *AccessKeySigner) GetAccessKeyId() (accessKeyId string, err error) { + return signer.credential.AccessKeyId, nil +} + +func (signer *AccessKeySigner) Sign(stringToSign, secretSuffix string) string { + secret := signer.credential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go new file mode 100644 index 000000000..75b78433a --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_bearer_token.go @@ -0,0 +1,35 @@ +package signers + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +type BearerTokenSigner struct { + credential *credentials.BearerTokenCredential +} + +func NewBearerTokenSigner(credential *credentials.BearerTokenCredential) *BearerTokenSigner { + return &BearerTokenSigner{ + credential: credential, + } +} + +func (signer *BearerTokenSigner) GetExtraParam() map[string]string { + return map[string]string{"BearerToken": signer.credential.BearerToken} +} + +func (*BearerTokenSigner) GetName() string { + return "" +} +func (*BearerTokenSigner) GetType() string { + return "BEARERTOKEN" +} +func (*BearerTokenSigner) GetVersion() string { + return "1.0" +} +func (signer *BearerTokenSigner) GetAccessKeyId() (accessKeyId string, err error) { + return "", nil +} +func (signer *BearerTokenSigner) Sign(stringToSign, secretSuffix string) string { + return "" +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go new file mode 100644 index 000000000..73788429e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ecs_ram_role.go @@ -0,0 +1,167 @@ +/* + * 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. + */ + +package signers + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + jmespath "github.com/jmespath/go-jmespath" +) + +var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/" + +type EcsRamRoleSigner struct { + *credentialUpdater + sessionCredential *SessionCredential + credential *credentials.EcsRamRoleCredential + commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error) +} + +func NewEcsRamRoleSigner(credential *credentials.EcsRamRoleCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *EcsRamRoleSigner) { + signer = &EcsRamRoleSigner{ + credential: credential, + commonApi: commonApi, + } + + signer.credentialUpdater = &credentialUpdater{ + credentialExpiration: defaultDurationSeconds / 60, + buildRequestMethod: signer.buildCommonRequest, + responseCallBack: signer.refreshCredential, + refreshApi: signer.refreshApi, + } + + return signer +} + +func (*EcsRamRoleSigner) GetName() string { + return "HMAC-SHA1" +} + +func (*EcsRamRoleSigner) GetType() string { + return "" +} + +func (*EcsRamRoleSigner) GetVersion() string { + return "1.0" +} + +func (signer *EcsRamRoleSigner) GetAccessKeyId() (accessKeyId string, err error) { + if signer.sessionCredential == nil || signer.needUpdateCredential() { + err = signer.updateCredential() + if err != nil { + return + } + } + if signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0 { + return "", nil + } + return signer.sessionCredential.AccessKeyId, nil +} + +func (signer *EcsRamRoleSigner) GetExtraParam() map[string]string { + if signer.sessionCredential == nil { + return make(map[string]string) + } + if len(signer.sessionCredential.StsToken) <= 0 { + return make(map[string]string) + } + return map[string]string{"SecurityToken": signer.sessionCredential.StsToken} +} + +func (signer *EcsRamRoleSigner) Sign(stringToSign, secretSuffix string) string { + secret := signer.sessionCredential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} + +func (signer *EcsRamRoleSigner) buildCommonRequest() (request *requests.CommonRequest, err error) { + return +} + +func (signer *EcsRamRoleSigner) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) { + requestUrl := securityCredURL + signer.credential.RoleName + httpRequest, err := http.NewRequest(requests.GET, requestUrl, strings.NewReader("")) + if err != nil { + err = fmt.Errorf("refresh Ecs sts token err: %s", err.Error()) + return + } + httpClient := &http.Client{} + httpResponse, err := httpClient.Do(httpRequest) + if err != nil { + err = fmt.Errorf("refresh Ecs sts token err: %s", err.Error()) + return + } + + response = responses.NewCommonResponse() + err = responses.Unmarshal(response, httpResponse, "") + return +} + +func (signer *EcsRamRoleSigner) refreshCredential(response *responses.CommonResponse) (err error) { + if response.GetHttpStatus() != http.StatusOK { + return fmt.Errorf("refresh Ecs sts token err, httpStatus: %d, message = %s", response.GetHttpStatus(), response.GetHttpContentString()) + } + var data interface{} + err = json.Unmarshal(response.GetHttpContentBytes(), &data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, json.Unmarshal fail: %s", err.Error()) + } + code, err := jmespath.Search("Code", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get Code: %s", err.Error()) + } + if code.(string) != "Success" { + return fmt.Errorf("refresh Ecs sts token err, Code is not Success") + } + accessKeyId, err := jmespath.Search("AccessKeyId", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get AccessKeyId: %s", err.Error()) + } + accessKeySecret, err := jmespath.Search("AccessKeySecret", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get AccessKeySecret: %s", err.Error()) + } + securityToken, err := jmespath.Search("SecurityToken", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get SecurityToken: %s", err.Error()) + } + expiration, err := jmespath.Search("Expiration", data) + if err != nil { + return fmt.Errorf("refresh Ecs sts token err, fail to get Expiration: %s", err.Error()) + } + if accessKeyId == nil || accessKeySecret == nil || securityToken == nil || expiration == nil { + return + } + + expirationTime, err := time.Parse("2006-01-02T15:04:05Z", expiration.(string)) + signer.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix()) + signer.sessionCredential = &SessionCredential{ + AccessKeyId: accessKeyId.(string), + AccessKeySecret: accessKeySecret.(string), + StsToken: securityToken.(string), + } + + return +} + +func (signer *EcsRamRoleSigner) GetSessionCredential() *SessionCredential { + return signer.sessionCredential +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go new file mode 100644 index 000000000..19273d5a6 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_key_pair.go @@ -0,0 +1,148 @@ +/* + * 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. + */ + +package signers + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + jmespath "github.com/jmespath/go-jmespath" +) + +type SignerKeyPair struct { + *credentialUpdater + sessionCredential *SessionCredential + credential *credentials.RsaKeyPairCredential + commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error) +} + +func NewSignerKeyPair(credential *credentials.RsaKeyPairCredential, commonApi func(*requests.CommonRequest, interface{}) (response *responses.CommonResponse, err error)) (signer *SignerKeyPair, err error) { + signer = &SignerKeyPair{ + credential: credential, + commonApi: commonApi, + } + + signer.credentialUpdater = &credentialUpdater{ + credentialExpiration: credential.SessionExpiration, + buildRequestMethod: signer.buildCommonRequest, + responseCallBack: signer.refreshCredential, + refreshApi: signer.refreshApi, + } + + if credential.SessionExpiration > 0 { + if credential.SessionExpiration >= 900 && credential.SessionExpiration <= 3600 { + signer.credentialExpiration = credential.SessionExpiration + } else { + err = errors.NewClientError(errors.InvalidParamErrorCode, "Key Pair session duration should be in the range of 15min - 1Hr", nil) + } + } else { + signer.credentialExpiration = defaultDurationSeconds + } + return +} + +func (*SignerKeyPair) GetName() string { + return "HMAC-SHA1" +} + +func (*SignerKeyPair) GetType() string { + return "" +} + +func (*SignerKeyPair) GetVersion() string { + return "1.0" +} + +func (signer *SignerKeyPair) ensureCredential() error { + if signer.sessionCredential == nil || signer.needUpdateCredential() { + return signer.updateCredential() + } + return nil +} + +func (signer *SignerKeyPair) GetAccessKeyId() (accessKeyId string, err error) { + err = signer.ensureCredential() + if err != nil { + return + } + if signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0 { + accessKeyId = "" + return + } + + accessKeyId = signer.sessionCredential.AccessKeyId + return +} + +func (signer *SignerKeyPair) GetExtraParam() map[string]string { + return make(map[string]string) +} + +func (signer *SignerKeyPair) Sign(stringToSign, secretSuffix string) string { + secret := signer.sessionCredential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} + +func (signer *SignerKeyPair) buildCommonRequest() (request *requests.CommonRequest, err error) { + request = requests.NewCommonRequest() + request.Product = "Sts" + request.Version = "2015-04-01" + request.ApiName = "GenerateSessionAccessKey" + request.Scheme = requests.HTTPS + request.SetDomain("sts.ap-northeast-1.aliyuncs.com") + request.QueryParams["PublicKeyId"] = signer.credential.PublicKeyId + request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration) + return +} + +func (signer *SignerKeyPair) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) { + signerV2 := NewSignerV2(signer.credential) + return signer.commonApi(request, signerV2) +} + +func (signer *SignerKeyPair) refreshCredential(response *responses.CommonResponse) (err error) { + if response.GetHttpStatus() != http.StatusOK { + message := "refresh session AccessKey failed" + err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), message) + return + } + var data interface{} + err = json.Unmarshal(response.GetHttpContentBytes(), &data) + if err != nil { + return fmt.Errorf("refresh KeyPair err, json.Unmarshal fail: %s", err.Error()) + } + accessKeyId, err := jmespath.Search("SessionAccessKey.SessionAccessKeyId", data) + if err != nil { + return fmt.Errorf("refresh KeyPair err, fail to get SessionAccessKeyId: %s", err.Error()) + } + accessKeySecret, err := jmespath.Search("SessionAccessKey.SessionAccessKeySecret", data) + if err != nil { + return fmt.Errorf("refresh KeyPair err, fail to get SessionAccessKeySecret: %s", err.Error()) + } + if accessKeyId == nil || accessKeySecret == nil { + return + } + signer.sessionCredential = &SessionCredential{ + AccessKeyId: accessKeyId.(string), + AccessKeySecret: accessKeySecret.(string), + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go new file mode 100644 index 000000000..c945c8aeb --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_ram_role_arn.go @@ -0,0 +1,175 @@ +/* + * 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. + */ + +package signers + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + jmespath "github.com/jmespath/go-jmespath" +) + +const ( + defaultDurationSeconds = 3600 +) + +type RamRoleArnSigner struct { + *credentialUpdater + roleSessionName string + sessionCredential *SessionCredential + credential *credentials.RamRoleArnCredential + commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error) +} + +func NewRamRoleArnSigner(credential *credentials.RamRoleArnCredential, commonApi func(request *requests.CommonRequest, signer interface{}) (response *responses.CommonResponse, err error)) (signer *RamRoleArnSigner, err error) { + signer = &RamRoleArnSigner{ + credential: credential, + commonApi: commonApi, + } + + signer.credentialUpdater = &credentialUpdater{ + credentialExpiration: credential.RoleSessionExpiration, + buildRequestMethod: signer.buildCommonRequest, + responseCallBack: signer.refreshCredential, + refreshApi: signer.refreshApi, + } + + if len(credential.RoleSessionName) > 0 { + signer.roleSessionName = credential.RoleSessionName + } else { + signer.roleSessionName = "aliyun-go-sdk-" + strconv.FormatInt(time.Now().UnixNano()/1000, 10) + } + if credential.RoleSessionExpiration > 0 { + if credential.RoleSessionExpiration >= 900 && credential.RoleSessionExpiration <= 3600 { + signer.credentialExpiration = credential.RoleSessionExpiration + } else { + err = errors.NewClientError(errors.InvalidParamErrorCode, "Assume Role session duration should be in the range of 15min - 1Hr", nil) + } + } else { + signer.credentialExpiration = defaultDurationSeconds + } + return +} + +func (*RamRoleArnSigner) GetName() string { + return "HMAC-SHA1" +} + +func (*RamRoleArnSigner) GetType() string { + return "" +} + +func (*RamRoleArnSigner) GetVersion() string { + return "1.0" +} + +func (signer *RamRoleArnSigner) GetAccessKeyId() (accessKeyId string, err error) { + if signer.sessionCredential == nil || signer.needUpdateCredential() { + err = signer.updateCredential() + if err != nil { + return + } + } + + if signer.sessionCredential == nil || len(signer.sessionCredential.AccessKeyId) <= 0 { + return "", err + } + + return signer.sessionCredential.AccessKeyId, nil +} + +func (signer *RamRoleArnSigner) GetExtraParam() map[string]string { + if signer.sessionCredential == nil || signer.needUpdateCredential() { + signer.updateCredential() + } + if signer.sessionCredential == nil || len(signer.sessionCredential.StsToken) <= 0 { + return make(map[string]string) + } + return map[string]string{"SecurityToken": signer.sessionCredential.StsToken} +} + +func (signer *RamRoleArnSigner) Sign(stringToSign, secretSuffix string) string { + secret := signer.sessionCredential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} + +func (signer *RamRoleArnSigner) buildCommonRequest() (request *requests.CommonRequest, err error) { + request = requests.NewCommonRequest() + request.Product = "Sts" + request.Version = "2015-04-01" + request.ApiName = "AssumeRole" + request.Scheme = requests.HTTPS + request.QueryParams["RoleArn"] = signer.credential.RoleArn + if signer.credential.Policy != "" { + request.QueryParams["Policy"] = signer.credential.Policy + } + request.QueryParams["RoleSessionName"] = signer.credential.RoleSessionName + request.QueryParams["DurationSeconds"] = strconv.Itoa(signer.credentialExpiration) + return +} + +func (signer *RamRoleArnSigner) refreshApi(request *requests.CommonRequest) (response *responses.CommonResponse, err error) { + credential := &credentials.AccessKeyCredential{ + AccessKeyId: signer.credential.AccessKeyId, + AccessKeySecret: signer.credential.AccessKeySecret, + } + signerV1 := NewAccessKeySigner(credential) + return signer.commonApi(request, signerV1) +} + +func (signer *RamRoleArnSigner) refreshCredential(response *responses.CommonResponse) (err error) { + if response.GetHttpStatus() != http.StatusOK { + message := "refresh session token failed" + err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), message) + return + } + var data interface{} + err = json.Unmarshal(response.GetHttpContentBytes(), &data) + if err != nil { + return fmt.Errorf("refresh RoleArn sts token err, json.Unmarshal fail: %s", err.Error()) + } + accessKeyId, err := jmespath.Search("Credentials.AccessKeyId", data) + if err != nil { + return fmt.Errorf("refresh RoleArn sts token err, fail to get AccessKeyId: %s", err.Error()) + } + accessKeySecret, err := jmespath.Search("Credentials.AccessKeySecret", data) + if err != nil { + return fmt.Errorf("refresh RoleArn sts token err, fail to get AccessKeySecret: %s", err.Error()) + } + securityToken, err := jmespath.Search("Credentials.SecurityToken", data) + if err != nil { + return fmt.Errorf("refresh RoleArn sts token err, fail to get SecurityToken: %s", err.Error()) + } + if accessKeyId == nil || accessKeySecret == nil || securityToken == nil { + return + } + signer.sessionCredential = &SessionCredential{ + AccessKeyId: accessKeyId.(string), + AccessKeySecret: accessKeySecret.(string), + StsToken: securityToken.(string), + } + return +} + +func (signer *RamRoleArnSigner) GetSessionCredential() *SessionCredential { + return signer.sessionCredential +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go new file mode 100644 index 000000000..d0ce36c38 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_sts_token.go @@ -0,0 +1,54 @@ +/* + * 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. + */ + +package signers + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +type StsTokenSigner struct { + credential *credentials.StsTokenCredential +} + +func NewStsTokenSigner(credential *credentials.StsTokenCredential) *StsTokenSigner { + return &StsTokenSigner{ + credential: credential, + } +} + +func (*StsTokenSigner) GetName() string { + return "HMAC-SHA1" +} + +func (*StsTokenSigner) GetType() string { + return "" +} + +func (*StsTokenSigner) GetVersion() string { + return "1.0" +} + +func (signer *StsTokenSigner) GetAccessKeyId() (accessKeyId string, err error) { + return signer.credential.AccessKeyId, nil +} + +func (signer *StsTokenSigner) GetExtraParam() map[string]string { + return map[string]string{"SecurityToken": signer.credential.AccessKeyStsToken} +} + +func (signer *StsTokenSigner) Sign(stringToSign, secretSuffix string) string { + secret := signer.credential.AccessKeySecret + secretSuffix + return ShaHmac1(stringToSign, secret) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go new file mode 100644 index 000000000..973485298 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/signers/signer_v2.go @@ -0,0 +1,54 @@ +/* + * 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. + */ + +package signers + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" +) + +type SignerV2 struct { + credential *credentials.RsaKeyPairCredential +} + +func (signer *SignerV2) GetExtraParam() map[string]string { + return nil +} + +func NewSignerV2(credential *credentials.RsaKeyPairCredential) *SignerV2 { + return &SignerV2{ + credential: credential, + } +} + +func (*SignerV2) GetName() string { + return "SHA256withRSA" +} + +func (*SignerV2) GetType() string { + return "PRIVATEKEY" +} + +func (*SignerV2) GetVersion() string { + return "1.0" +} + +func (signer *SignerV2) GetAccessKeyId() (accessKeyId string, err error) { + return signer.credential.PublicKeyId, err +} + +func (signer *SignerV2) Sign(stringToSign, secretSuffix string) string { + secret := signer.credential.PrivateKey + return Sha256WithRsa(stringToSign, secret) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go new file mode 100644 index 000000000..aef8bdc05 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/client.go @@ -0,0 +1,766 @@ +/* + * 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. + */ + +package sdk + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "net/http" + "net/url" + "os" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +var debug utils.Debug + +func init() { + debug = utils.Init("sdk") +} + +// Version this value will be replaced while build: -ldflags="-X sdk.version=x.x.x" +var Version = "0.0.1" +var defaultConnectTimeout = 5 * time.Second +var defaultReadTimeout = 10 * time.Second + +var DefaultUserAgent = fmt.Sprintf("AlibabaCloud (%s; %s) Golang/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version) + +var hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) { + return fn +} + +// Client the type Client +type Client struct { + isInsecure bool + regionId string + config *Config + httpProxy string + httpsProxy string + noProxy string + logger *Logger + userAgent map[string]string + signer auth.Signer + httpClient *http.Client + asyncTaskQueue chan func() + readTimeout time.Duration + connectTimeout time.Duration + EndpointMap map[string]string + EndpointType string + Network string + + debug bool + isRunning bool + // void "panic(write to close channel)" cause of addAsync() after Shutdown() + asyncChanLock *sync.RWMutex +} + +func (client *Client) Init() (err error) { + panic("not support yet") +} + +func (client *Client) SetEndpointRules(endpointMap map[string]string, endpointType string, netWork string) { + client.EndpointMap = endpointMap + client.Network = netWork + client.EndpointType = endpointType +} + +func (client *Client) SetHTTPSInsecure(isInsecure bool) { + client.isInsecure = isInsecure +} + +func (client *Client) GetHTTPSInsecure() bool { + return client.isInsecure +} + +func (client *Client) SetHttpsProxy(httpsProxy string) { + client.httpsProxy = httpsProxy +} + +func (client *Client) GetHttpsProxy() string { + return client.httpsProxy +} + +func (client *Client) SetHttpProxy(httpProxy string) { + client.httpProxy = httpProxy +} + +func (client *Client) GetHttpProxy() string { + return client.httpProxy +} + +func (client *Client) SetNoProxy(noProxy string) { + client.noProxy = noProxy +} + +func (client *Client) GetNoProxy() string { + return client.noProxy +} + +// InitWithProviderChain will get credential from the providerChain, +// the RsaKeyPairCredential Only applicable to regionID `ap-northeast-1`, +// if your providerChain may return a credential type with RsaKeyPairCredential, +// please ensure your regionID is `ap-northeast-1`. +func (client *Client) InitWithProviderChain(regionId string, provider provider.Provider) (err error) { + config := client.InitClientConfig() + credential, err := provider.Resolve() + if err != nil { + return + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithOptions(regionId string, config *Config, credential auth.Credential) (err error) { + client.isRunning = true + client.asyncChanLock = new(sync.RWMutex) + client.regionId = regionId + client.config = config + client.httpClient = &http.Client{} + + if config.HttpTransport != nil { + client.httpClient.Transport = config.HttpTransport + } + + if config.Timeout > 0 { + client.httpClient.Timeout = config.Timeout + } + + if config.EnableAsync { + client.EnableAsync(config.GoRoutinePoolSize, config.MaxTaskQueueSize) + } + + client.signer, err = auth.NewSignerWithCredential(credential, client.ProcessCommonRequestWithSigner) + + return +} + +func (client *Client) SetReadTimeout(readTimeout time.Duration) { + client.readTimeout = readTimeout +} + +func (client *Client) SetConnectTimeout(connectTimeout time.Duration) { + client.connectTimeout = connectTimeout +} + +func (client *Client) GetReadTimeout() time.Duration { + return client.readTimeout +} + +func (client *Client) GetConnectTimeout() time.Duration { + return client.connectTimeout +} + +func (client *Client) getHttpProxy(scheme string) (proxy *url.URL, err error) { + if scheme == "https" { + if client.GetHttpsProxy() != "" { + proxy, err = url.Parse(client.httpsProxy) + } else if rawurl := os.Getenv("HTTPS_PROXY"); rawurl != "" { + proxy, err = url.Parse(rawurl) + } else if rawurl := os.Getenv("https_proxy"); rawurl != "" { + proxy, err = url.Parse(rawurl) + } + } else { + if client.GetHttpProxy() != "" { + proxy, err = url.Parse(client.httpProxy) + } else if rawurl := os.Getenv("HTTP_PROXY"); rawurl != "" { + proxy, err = url.Parse(rawurl) + } else if rawurl := os.Getenv("http_proxy"); rawurl != "" { + proxy, err = url.Parse(rawurl) + } + } + + return proxy, err +} + +func (client *Client) getNoProxy(scheme string) []string { + var urls []string + if client.GetNoProxy() != "" { + urls = strings.Split(client.noProxy, ",") + } else if rawurl := os.Getenv("NO_PROXY"); rawurl != "" { + urls = strings.Split(rawurl, ",") + } else if rawurl := os.Getenv("no_proxy"); rawurl != "" { + urls = strings.Split(rawurl, ",") + } + + return urls +} + +// EnableAsync enable the async task queue +func (client *Client) EnableAsync(routinePoolSize, maxTaskQueueSize int) { + client.asyncTaskQueue = make(chan func(), maxTaskQueueSize) + for i := 0; i < routinePoolSize; i++ { + go func() { + for client.isRunning { + select { + case task, notClosed := <-client.asyncTaskQueue: + if notClosed { + task() + } + } + } + }() + } +} + +func (client *Client) InitWithAccessKey(regionId, accessKeyId, accessKeySecret string) (err error) { + config := client.InitClientConfig() + credential := &credentials.BaseCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithStsToken(regionId, accessKeyId, accessKeySecret, securityToken string) (err error) { + config := client.InitClientConfig() + credential := &credentials.StsTokenCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + AccessKeyStsToken: securityToken, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (err error) { + config := client.InitClientConfig() + credential := &credentials.RamRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithRamRoleArnAndPolicy(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string) (err error) { + config := client.InitClientConfig() + credential := &credentials.RamRoleArnCredential{ + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + RoleArn: roleArn, + RoleSessionName: roleSessionName, + Policy: policy, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithRsaKeyPair(regionId, publicKeyId, privateKey string, sessionExpiration int) (err error) { + config := client.InitClientConfig() + credential := &credentials.RsaKeyPairCredential{ + PrivateKey: privateKey, + PublicKeyId: publicKeyId, + SessionExpiration: sessionExpiration, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithEcsRamRole(regionId, roleName string) (err error) { + config := client.InitClientConfig() + credential := &credentials.EcsRamRoleCredential{ + RoleName: roleName, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitWithBearerToken(regionId, bearerToken string) (err error) { + config := client.InitClientConfig() + credential := &credentials.BearerTokenCredential{ + BearerToken: bearerToken, + } + return client.InitWithOptions(regionId, config, credential) +} + +func (client *Client) InitClientConfig() (config *Config) { + if client.config != nil { + return client.config + } else { + return NewConfig() + } +} + +func (client *Client) DoAction(request requests.AcsRequest, response responses.AcsResponse) (err error) { + return client.DoActionWithSigner(request, response, nil) +} + +func (client *Client) GetEndpointRules(regionId string, product string) (endpointRaw string) { + if client.EndpointType == "regional" { + endpointRaw = strings.Replace("..aliyuncs.com", "", regionId, 1) + } else { + endpointRaw = ".aliyuncs.com" + } + endpointRaw = strings.Replace(endpointRaw, "", strings.ToLower(product), 1) + if client.Network == "" || client.Network == "public" { + endpointRaw = strings.Replace(endpointRaw, "", "", 1) + } else { + endpointRaw = strings.Replace(endpointRaw, "", "-"+client.Network, 1) + } + return endpointRaw +} + +func (client *Client) buildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (httpRequest *http.Request, err error) { + // add clientVersion + request.GetHeaders()["x-sdk-core-version"] = Version + + regionId := client.regionId + if len(request.GetRegionId()) > 0 { + regionId = request.GetRegionId() + } + + // resolve endpoint + endpoint := request.GetDomain() + if endpoint == "" && client.EndpointType != "" { + if client.EndpointMap != nil && client.Network == "" || client.Network == "public" { + endpoint = client.EndpointMap[regionId] + } + + if endpoint == "" { + endpoint = client.GetEndpointRules(regionId, request.GetProduct()) + } + } + + if endpoint == "" { + resolveParam := &endpoints.ResolveParam{ + Domain: request.GetDomain(), + Product: request.GetProduct(), + RegionId: regionId, + LocationProduct: request.GetLocationServiceCode(), + LocationEndpointType: request.GetLocationEndpointType(), + CommonApi: client.ProcessCommonRequest, + } + endpoint, err = endpoints.Resolve(resolveParam) + if err != nil { + return + } + } + + request.SetDomain(endpoint) + if request.GetScheme() == "" { + request.SetScheme(client.config.Scheme) + } + // init request params + err = requests.InitParams(request) + if err != nil { + return + } + + // signature + var finalSigner auth.Signer + if signer != nil { + finalSigner = signer + } else { + finalSigner = client.signer + } + httpRequest, err = buildHttpRequest(request, finalSigner, regionId) + if err == nil { + userAgent := DefaultUserAgent + getSendUserAgent(client.config.UserAgent, client.userAgent, request.GetUserAgent()) + httpRequest.Header.Set("User-Agent", userAgent) + } + + return +} + +func getSendUserAgent(configUserAgent string, clientUserAgent, requestUserAgent map[string]string) string { + realUserAgent := "" + for key1, value1 := range clientUserAgent { + for key2, _ := range requestUserAgent { + if key1 == key2 { + key1 = "" + } + } + if key1 != "" { + realUserAgent += fmt.Sprintf(" %s/%s", key1, value1) + + } + } + for key, value := range requestUserAgent { + realUserAgent += fmt.Sprintf(" %s/%s", key, value) + } + if configUserAgent != "" { + return realUserAgent + fmt.Sprintf(" Extra/%s", configUserAgent) + } + return realUserAgent +} + +func (client *Client) AppendUserAgent(key, value string) { + newkey := true + + if client.userAgent == nil { + client.userAgent = make(map[string]string) + } + if strings.ToLower(key) != "core" && strings.ToLower(key) != "go" { + for tag, _ := range client.userAgent { + if tag == key { + client.userAgent[tag] = value + newkey = false + } + } + if newkey { + client.userAgent[key] = value + } + } +} + +func (client *Client) BuildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (err error) { + _, err = client.buildRequestWithSigner(request, signer) + return +} + +func (client *Client) getTimeout(request requests.AcsRequest) (time.Duration, time.Duration) { + readTimeout := defaultReadTimeout + connectTimeout := defaultConnectTimeout + + reqReadTimeout := request.GetReadTimeout() + reqConnectTimeout := request.GetConnectTimeout() + if reqReadTimeout != 0*time.Millisecond { + readTimeout = reqReadTimeout + } else if client.readTimeout != 0*time.Millisecond { + readTimeout = client.readTimeout + } else if client.httpClient.Timeout != 0 { + readTimeout = client.httpClient.Timeout + } else if timeout, ok := getAPIMaxTimeout(request.GetProduct(), request.GetActionName()); ok { + readTimeout = timeout + } + + if reqConnectTimeout != 0*time.Millisecond { + connectTimeout = reqConnectTimeout + } else if client.connectTimeout != 0*time.Millisecond { + connectTimeout = client.connectTimeout + } + return readTimeout, connectTimeout +} + +func Timeout(connectTimeout time.Duration) func(cxt context.Context, net, addr string) (c net.Conn, err error) { + return func(ctx context.Context, network, address string) (net.Conn, error) { + return (&net.Dialer{ + Timeout: connectTimeout, + DualStack: true, + }).DialContext(ctx, network, address) + } +} + +func (client *Client) setTimeout(request requests.AcsRequest) { + readTimeout, connectTimeout := client.getTimeout(request) + client.httpClient.Timeout = readTimeout + if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil { + trans.DialContext = Timeout(connectTimeout) + client.httpClient.Transport = trans + } else { + client.httpClient.Transport = &http.Transport{ + DialContext: Timeout(connectTimeout), + } + } +} + +func (client *Client) getHTTPSInsecure(request requests.AcsRequest) (insecure bool) { + if request.GetHTTPSInsecure() != nil { + insecure = *request.GetHTTPSInsecure() + } else { + insecure = client.GetHTTPSInsecure() + } + return insecure +} + +func (client *Client) DoActionWithSigner(request requests.AcsRequest, response responses.AcsResponse, signer auth.Signer) (err error) { + + fieldMap := make(map[string]string) + initLogMsg(fieldMap) + defer func() { + client.printLog(fieldMap, err) + }() + httpRequest, err := client.buildRequestWithSigner(request, signer) + if err != nil { + return + } + + client.setTimeout(request) + proxy, err := client.getHttpProxy(httpRequest.URL.Scheme) + if err != nil { + return err + } + + noProxy := client.getNoProxy(httpRequest.URL.Scheme) + + var flag bool + for _, value := range noProxy { + if value == httpRequest.Host { + flag = true + break + } + } + + // Set whether to ignore certificate validation. + // Default InsecureSkipVerify is false. + if trans, ok := client.httpClient.Transport.(*http.Transport); ok && trans != nil { + trans.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: client.getHTTPSInsecure(request), + } + if proxy != nil && !flag { + trans.Proxy = http.ProxyURL(proxy) + } + client.httpClient.Transport = trans + } + + var httpResponse *http.Response + for retryTimes := 0; retryTimes <= client.config.MaxRetryTime; retryTimes++ { + if proxy != nil && proxy.User != nil { + if password, passwordSet := proxy.User.Password(); passwordSet { + httpRequest.SetBasicAuth(proxy.User.Username(), password) + } + } + if retryTimes > 0 { + client.printLog(fieldMap, err) + initLogMsg(fieldMap) + } + putMsgToMap(fieldMap, httpRequest) + debug("> %s %s %s", httpRequest.Method, httpRequest.URL.RequestURI(), httpRequest.Proto) + debug("> Host: %s", httpRequest.Host) + for key, value := range httpRequest.Header { + debug("> %s: %v", key, strings.Join(value, "")) + } + debug(">") + debug(" Retry Times: %d.", retryTimes) + + startTime := time.Now() + fieldMap["{start_time}"] = startTime.Format("2006-01-02 15:04:05") + httpResponse, err = hookDo(client.httpClient.Do)(httpRequest) + fieldMap["{cost}"] = time.Now().Sub(startTime).String() + if err == nil { + fieldMap["{code}"] = strconv.Itoa(httpResponse.StatusCode) + fieldMap["{res_headers}"] = TransToString(httpResponse.Header) + debug("< %s %s", httpResponse.Proto, httpResponse.Status) + for key, value := range httpResponse.Header { + debug("< %s: %v", key, strings.Join(value, "")) + } + } + debug("<") + // receive error + if err != nil { + debug(" Error: %s.", err.Error()) + if !client.config.AutoRetry { + return + } else if retryTimes >= client.config.MaxRetryTime { + // timeout but reached the max retry times, return + times := strconv.Itoa(retryTimes + 1) + timeoutErrorMsg := fmt.Sprintf(errors.TimeoutErrorMessage, times, times) + if strings.Contains(err.Error(), "Client.Timeout") { + timeoutErrorMsg += " Read timeout. Please set a valid ReadTimeout." + } else { + timeoutErrorMsg += " Connect timeout. Please set a valid ConnectTimeout." + } + err = errors.NewClientError(errors.TimeoutErrorCode, timeoutErrorMsg, err) + return + } + } + // if status code >= 500 or timeout, will trigger retry + if client.config.AutoRetry && (err != nil || isServerError(httpResponse)) { + client.setTimeout(request) + // rewrite signatureNonce and signature + httpRequest, err = client.buildRequestWithSigner(request, signer) + // buildHttpRequest(request, finalSigner, regionId) + if err != nil { + return + } + continue + } + break + } + + err = responses.Unmarshal(response, httpResponse, request.GetAcceptFormat()) + fieldMap["{res_body}"] = response.GetHttpContentString() + debug("%s", response.GetHttpContentString()) + // wrap server errors + if serverErr, ok := err.(*errors.ServerError); ok { + var wrapInfo = map[string]string{} + wrapInfo["StringToSign"] = request.GetStringToSign() + err = errors.WrapServerError(serverErr, wrapInfo) + } + return +} + +func putMsgToMap(fieldMap map[string]string, request *http.Request) { + fieldMap["{host}"] = request.Host + fieldMap["{method}"] = request.Method + fieldMap["{uri}"] = request.URL.RequestURI() + fieldMap["{pid}"] = strconv.Itoa(os.Getpid()) + fieldMap["{version}"] = strings.Split(request.Proto, "/")[1] + hostname, _ := os.Hostname() + fieldMap["{hostname}"] = hostname + fieldMap["{req_headers}"] = TransToString(request.Header) + fieldMap["{target}"] = request.URL.Path + request.URL.RawQuery +} + +func buildHttpRequest(request requests.AcsRequest, singer auth.Signer, regionId string) (httpRequest *http.Request, err error) { + err = auth.Sign(request, singer, regionId) + if err != nil { + return + } + requestMethod := request.GetMethod() + requestUrl := request.BuildUrl() + body := request.GetBodyReader() + httpRequest, err = http.NewRequest(requestMethod, requestUrl, body) + if err != nil { + return + } + for key, value := range request.GetHeaders() { + httpRequest.Header[key] = []string{value} + } + // host is a special case + if host, containsHost := request.GetHeaders()["Host"]; containsHost { + httpRequest.Host = host + } + return +} + +func isServerError(httpResponse *http.Response) bool { + return httpResponse.StatusCode >= http.StatusInternalServerError +} + +/** +only block when any one of the following occurs: +1. the asyncTaskQueue is full, increase the queue size to avoid this +2. Shutdown() in progressing, the client is being closed +**/ +func (client *Client) AddAsyncTask(task func()) (err error) { + if client.asyncTaskQueue != nil { + client.asyncChanLock.RLock() + defer client.asyncChanLock.RUnlock() + if client.isRunning { + client.asyncTaskQueue <- task + } + } else { + err = errors.NewClientError(errors.AsyncFunctionNotEnabledCode, errors.AsyncFunctionNotEnabledMessage, nil) + } + return +} + +func (client *Client) GetConfig() *Config { + return client.config +} + +func NewClient() (client *Client, err error) { + client = &Client{} + err = client.Init() + return +} + +func NewClientWithProvider(regionId string, providers ...provider.Provider) (client *Client, err error) { + client = &Client{} + var pc provider.Provider + if len(providers) == 0 { + pc = provider.DefaultChain + } else { + pc = provider.NewProviderChain(providers) + } + err = client.InitWithProviderChain(regionId, pc) + return +} + +func NewClientWithOptions(regionId string, config *Config, credential auth.Credential) (client *Client, err error) { + client = &Client{} + err = client.InitWithOptions(regionId, config, credential) + return +} + +func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (client *Client, err error) { + client = &Client{} + err = client.InitWithAccessKey(regionId, accessKeyId, accessKeySecret) + return +} + +func NewClientWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken string) (client *Client, err error) { + client = &Client{} + err = client.InitWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken) + return +} + +func NewClientWithRamRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) { + client = &Client{} + err = client.InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName) + return +} + +func NewClientWithRamRoleArnAndPolicy(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string) (client *Client, err error) { + client = &Client{} + err = client.InitWithRamRoleArnAndPolicy(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy) + return +} + +func NewClientWithEcsRamRole(regionId string, roleName string) (client *Client, err error) { + client = &Client{} + err = client.InitWithEcsRamRole(regionId, roleName) + return +} + +func NewClientWithRsaKeyPair(regionId string, publicKeyId, privateKey string, sessionExpiration int) (client *Client, err error) { + client = &Client{} + err = client.InitWithRsaKeyPair(regionId, publicKeyId, privateKey, sessionExpiration) + return +} + +func NewClientWithBearerToken(regionId, bearerToken string) (client *Client, err error) { + client = &Client{} + err = client.InitWithBearerToken(regionId, bearerToken) + return +} + +func (client *Client) ProcessCommonRequest(request *requests.CommonRequest) (response *responses.CommonResponse, err error) { + request.TransToAcsRequest() + response = responses.NewCommonResponse() + err = client.DoAction(request, response) + return +} + +func (client *Client) ProcessCommonRequestWithSigner(request *requests.CommonRequest, signerInterface interface{}) (response *responses.CommonResponse, err error) { + if signer, isSigner := signerInterface.(auth.Signer); isSigner { + request.TransToAcsRequest() + response = responses.NewCommonResponse() + err = client.DoActionWithSigner(request, response, signer) + return + } + panic("should not be here") +} + +func (client *Client) Shutdown() { + // lock the addAsync() + client.asyncChanLock.Lock() + defer client.asyncChanLock.Unlock() + if client.asyncTaskQueue != nil { + close(client.asyncTaskQueue) + } + client.isRunning = false +} + +// Deprecated: Use NewClientWithRamRoleArn in this package instead. +func NewClientWithStsRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) { + return NewClientWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName) +} + +// Deprecated: Use NewClientWithEcsRamRole in this package instead. +func NewClientWithStsRoleNameOnEcs(regionId string, roleName string) (client *Client, err error) { + return NewClientWithEcsRamRole(regionId, roleName) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go new file mode 100644 index 000000000..5e50166fc --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/config.go @@ -0,0 +1,91 @@ +/* + * 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. + */ + +package sdk + +import ( + "net/http" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +type Config struct { + AutoRetry bool `default:"true"` + MaxRetryTime int `default:"3"` + UserAgent string `default:""` + Debug bool `default:"false"` + HttpTransport *http.Transport `default:""` + EnableAsync bool `default:"false"` + MaxTaskQueueSize int `default:"1000"` + GoRoutinePoolSize int `default:"5"` + Scheme string `default:"HTTP"` + Timeout time.Duration +} + +func NewConfig() (config *Config) { + config = &Config{} + utils.InitStructWithDefaultTag(config) + return +} + +func (c *Config) WithAutoRetry(isAutoRetry bool) *Config { + c.AutoRetry = isAutoRetry + return c +} + +func (c *Config) WithMaxRetryTime(maxRetryTime int) *Config { + c.MaxRetryTime = maxRetryTime + return c +} + +func (c *Config) WithUserAgent(userAgent string) *Config { + c.UserAgent = userAgent + return c +} + +func (c *Config) WithDebug(isDebug bool) *Config { + c.Debug = isDebug + return c +} + +func (c *Config) WithTimeout(timeout time.Duration) *Config { + c.Timeout = timeout + return c +} + +func (c *Config) WithHttpTransport(httpTransport *http.Transport) *Config { + c.HttpTransport = httpTransport + return c +} + +func (c *Config) WithEnableAsync(isEnableAsync bool) *Config { + c.EnableAsync = isEnableAsync + return c +} + +func (c *Config) WithMaxTaskQueueSize(maxTaskQueueSize int) *Config { + c.MaxTaskQueueSize = maxTaskQueueSize + return c +} + +func (c *Config) WithGoRoutinePoolSize(goRoutinePoolSize int) *Config { + c.GoRoutinePoolSize = goRoutinePoolSize + return c +} + +func (c *Config) WithScheme(scheme string) *Config { + c.Scheme = scheme + return c +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go new file mode 100644 index 000000000..a4fc47098 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/endpoints_config.go @@ -0,0 +1,4126 @@ + +package endpoints + +import ( + "encoding/json" + "fmt" + "sync" +) + +const endpointsJson =`{ + "products": [ + { + "code": "emr", + "document_id": "28140", + "location_service_code": "emr", + "regional_endpoints": [ + { + "region": "cn-qingdao", + "endpoint": "emr.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "emr.eu-west-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "emr.me-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "emr.ap-northeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "emr.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "emr.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "emr.ap-south-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "emr.us-east-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "emr.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "emr.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "emr.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "emr.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "emr.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "emr.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "emr.aliyuncs.com" + } + ], + "global_endpoint": "emr.aliyuncs.com", + "regional_endpoint_pattern": "emr.[RegionId].aliyuncs.com" + }, + { + "code": "petadata", + "document_id": "", + "location_service_code": "petadata", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "petadata.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "petadata.ap-southeast-2.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "petadata.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "petadata.ap-southeast-5.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "petadata.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "petadata.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "petadata.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "petadata.aliyuncs.com" + } + ], + "global_endpoint": "petadata.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "dbs", + "document_id": "", + "location_service_code": "dbs", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dbs-api.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "dbs-api.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "dbs-api.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "alidnsgtm", + "document_id": "", + "location_service_code": "alidnsgtm", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "alidns.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "alidns.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "elasticsearch", + "document_id": "", + "location_service_code": "elasticsearch", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "elasticsearch.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "elasticsearch.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "elasticsearch.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "elasticsearch.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "elasticsearch.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "elasticsearch.ap-southeast-3.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "elasticsearch.us-west-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "elasticsearch.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "elasticsearch.ap-southeast-5.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "elasticsearch.eu-central-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "elasticsearch.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "elasticsearch.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "elasticsearch.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "elasticsearch.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "elasticsearch.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "baas", + "document_id": "", + "location_service_code": "baas", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "baas.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "baas.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "baas.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "baas.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "baas.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "baas.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cr", + "document_id": "60716", + "location_service_code": "cr", + "regional_endpoints": null, + "global_endpoint": "cr.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudap", + "document_id": "", + "location_service_code": "cloudap", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cloudwf.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "imagesearch", + "document_id": "", + "location_service_code": "imagesearch", + "regional_endpoints": [ + { + "region": "ap-southeast-2", + "endpoint": "imagesearch.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "imagesearch.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "imagesearch.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "imagesearch.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "pts", + "document_id": "", + "location_service_code": "pts", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "pts.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ehs", + "document_id": "", + "location_service_code": "ehs", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "ehpc.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ehpc.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ehpc.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ehpc.cn-qingdao.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ehpc.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ehpc.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "ehpc.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ehpc.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ehpc.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ehpc.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ehpc.ap-southeast-2.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "polardb", + "document_id": "58764", + "location_service_code": "polardb", + "regional_endpoints": [ + { + "region": "ap-south-1", + "endpoint": "polardb.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "polardb.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "polardb.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "polardb.ap-southeast-5.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "polardb.aliyuncs.com" + }, + { + "code": "r-kvstore", + "document_id": "60831", + "location_service_code": "redisa", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "r-kvstore.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "r-kvstore.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "r-kvstore.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "r-kvstore.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "r-kvstore.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "r-kvstore.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "r-kvstore.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "r-kvstore.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "r-kvstore.eu-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "r-kvstore.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "r-kvstore.me-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "r-kvstore.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "r-kvstore.ap-southeast-5.aliyuncs.com" + } + ], + "global_endpoint": "r-kvstore.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "xianzhi", + "document_id": "", + "location_service_code": "xianzhi", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "xianzhi.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "pcdn", + "document_id": "", + "location_service_code": "pcdn", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "pcdn.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cdn", + "document_id": "27148", + "location_service_code": "cdn", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cdn.aliyuncs.com" + } + ], + "global_endpoint": "cdn.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudauth", + "document_id": "60687", + "location_service_code": "cloudauth", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cloudauth.aliyuncs.com" + } + ], + "global_endpoint": "cloudauth.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "nas", + "document_id": "62598", + "location_service_code": "nas", + "regional_endpoints": [ + { + "region": "ap-southeast-2", + "endpoint": "nas.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "nas.ap-south-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "nas.eu-central-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "nas.us-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "nas.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "nas.cn-qingdao.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "nas.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "nas.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "nas.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "nas.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "nas.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "nas.ap-northeast-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "nas.us-east-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "nas.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "nas.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "nas.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "nas.ap-southeast-3.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "alidns", + "document_id": "29739", + "location_service_code": "alidns", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "alidns.aliyuncs.com" + } + ], + "global_endpoint": "alidns.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "dts", + "document_id": "", + "location_service_code": "dts", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "dts.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dts.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "emas", + "document_id": "", + "location_service_code": "emas", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "mhub.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "mhub.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dysmsapi", + "document_id": "", + "location_service_code": "dysmsapi", + "regional_endpoints": [ + { + "region": "ap-southeast-3", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-chengdu", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "dysmsapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "dysmsapi.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dysmsapi.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudwf", + "document_id": "58111", + "location_service_code": "cloudwf", + "regional_endpoints": null, + "global_endpoint": "cloudwf.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "fc", + "document_id": "", + "location_service_code": "fc", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "cn-beijing.fc.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ap-southeast-2.fc.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "cn-huhehaote.fc.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "cn-shanghai.fc.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "cn-hangzhou.fc.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "cn-shenzhen.fc.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "saf", + "document_id": "", + "location_service_code": "saf", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "saf.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "saf.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "saf.cn-shenzhen.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "rds", + "document_id": "26223", + "location_service_code": "rds", + "regional_endpoints": [ + { + "region": "ap-northeast-1", + "endpoint": "rds.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "rds.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "rds.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "rds.eu-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "rds.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "rds.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "rds.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "rds.ap-southeast-5.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "rds.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "rds.me-east-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "rds.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "rds.aliyuncs.com" + } + ], + "global_endpoint": "rds.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "vpc", + "document_id": "34962", + "location_service_code": "vpc", + "regional_endpoints": [ + { + "region": "ap-south-1", + "endpoint": "vpc.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "vpc.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "vpc.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "vpc.cn-huhehaote.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "vpc.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "vpc.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "vpc.ap-southeast-3.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "vpc.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "vpc.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "vpc.eu-west-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "vpc.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "vpc.aliyuncs.com" + } + ], + "global_endpoint": "vpc.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "gpdb", + "document_id": "", + "location_service_code": "gpdb", + "regional_endpoints": [ + { + "region": "ap-southeast-3", + "endpoint": "gpdb.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "gpdb.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "gpdb.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "gpdb.ap-southeast-2.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "gpdb.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "gpdb.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "gpdb.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "gpdb.ap-northeast-1.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "gpdb.eu-west-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "gpdb.ap-south-1.aliyuncs.com" + } + ], + "global_endpoint": "gpdb.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "yunmarket", + "document_id": "", + "location_service_code": "yunmarket", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "market.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "pvtz", + "document_id": "", + "location_service_code": "pvtz", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "pvtz.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "pvtz.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "oss", + "document_id": "", + "location_service_code": "oss", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "oss-cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "oss-cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "oss-cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "oss-cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "oss-cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "oss-ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "oss-us-west-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "oss-cn-qingdao.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "foas", + "document_id": "", + "location_service_code": "foas", + "regional_endpoints": [ + { + "region": "cn-qingdao", + "endpoint": "foas.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "foas.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "foas.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "foas.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "foas.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "foas.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "foas.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ddos", + "document_id": "", + "location_service_code": "ddos", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ddospro.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ddospro.cn-hongkong.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cbn", + "document_id": "", + "location_service_code": "cbn", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "cbn.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "cbn.aliyuncs.com" + } + ], + "global_endpoint": "cbn.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "nlp", + "document_id": "", + "location_service_code": "nlp", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "nlp.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hsm", + "document_id": "", + "location_service_code": "hsm", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "hsm.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "hsm.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ons", + "document_id": "44416", + "location_service_code": "ons", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "ons.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "ons.cn-huhehaote.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "ons.us-east-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ons.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ons.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "ons.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ons.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ons.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ons.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "ons.me-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "ons.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ons.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "ons.cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ons.eu-central-1.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "ons.eu-west-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ons.us-west-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ons.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ons.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "kms", + "document_id": "", + "location_service_code": "kms", + "regional_endpoints": [ + { + "region": "cn-hongkong", + "endpoint": "kms.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "kms.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "kms.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "kms.cn-qingdao.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "kms.eu-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "kms.us-east-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "kms.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "kms.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "kms.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "kms.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "kms.cn-huhehaote.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "kms.me-east-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "kms.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "kms.ap-southeast-3.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "kms.us-west-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "kms.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "kms.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "kms.eu-central-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "kms.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cps", + "document_id": "", + "location_service_code": "cps", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cloudpush.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ensdisk", + "document_id": "", + "location_service_code": "ensdisk", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ens.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudapi", + "document_id": "43590", + "location_service_code": "apigateway", + "regional_endpoints": [ + { + "region": "ap-southeast-2", + "endpoint": "apigateway.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "apigateway.ap-south-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "apigateway.us-east-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "apigateway.me-east-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "apigateway.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "apigateway.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "apigateway.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "apigateway.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "apigateway.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "apigateway.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "apigateway.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "apigateway.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "apigateway.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "apigateway.us-west-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "apigateway.cn-shenzhen.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "apigateway.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "apigateway.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "apigateway.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "apigateway.cn-hongkong.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "apigateway.[RegionId].aliyuncs.com" + }, + { + "code": "eci", + "document_id": "", + "location_service_code": "eci", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "eci.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "eci.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "onsvip", + "document_id": "", + "location_service_code": "onsvip", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "ons.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ons.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ons.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ons.cn-shenzhen.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ons.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ons.cn-qingdao.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "linkwan", + "document_id": "", + "location_service_code": "linkwan", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "linkwan.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "linkwan.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ddosdip", + "document_id": "", + "location_service_code": "ddosdip", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "ddosdip.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "batchcompute", + "document_id": "44717", + "location_service_code": "batchcompute", + "regional_endpoints": [ + { + "region": "us-west-1", + "endpoint": "batchcompute.us-west-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "batchcompute.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "batchcompute.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "batchcompute.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "batchcompute.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "batchcompute.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "batchcompute.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "batchcompute.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "batchcompute.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "batchcompute.[RegionId].aliyuncs.com" + }, + { + "code": "aegis", + "document_id": "28449", + "location_service_code": "vipaegis", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "aegis.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "aegis.ap-southeast-3.aliyuncs.com" + } + ], + "global_endpoint": "aegis.cn-hangzhou.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "arms", + "document_id": "42924", + "location_service_code": "arms", + "regional_endpoints": [ + { + "region": "cn-hongkong", + "endpoint": "arms.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "arms.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "arms.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "arms.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "arms.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "arms.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "arms.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "arms.[RegionId].aliyuncs.com" + }, + { + "code": "live", + "document_id": "48207", + "location_service_code": "live", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "live.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "live.aliyuncs.com" + } + ], + "global_endpoint": "live.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "alimt", + "document_id": "", + "location_service_code": "alimt", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "mt.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "actiontrail", + "document_id": "", + "location_service_code": "actiontrail", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "actiontrail.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "actiontrail.cn-qingdao.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "actiontrail.us-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "actiontrail.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "actiontrail.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "actiontrail.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "actiontrail.ap-south-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "actiontrail.me-east-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "actiontrail.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "actiontrail.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "actiontrail.cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "actiontrail.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "actiontrail.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "actiontrail.ap-northeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "actiontrail.us-west-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "actiontrail.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "actiontrail.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "actiontrail.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "actiontrail.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "smartag", + "document_id": "", + "location_service_code": "smartag", + "regional_endpoints": [ + { + "region": "ap-southeast-3", + "endpoint": "smartag.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "smartag.ap-southeast-5.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "smartag.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "smartag.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "smartag.cn-hongkong.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "smartag.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "smartag.ap-southeast-2.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "vod", + "document_id": "60574", + "location_service_code": "vod", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "vod.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "vod.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "vod.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "vod.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "vod.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "vod.eu-central-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "domain", + "document_id": "42875", + "location_service_code": "domain", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "domain-intl.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "domain.aliyuncs.com" + } + ], + "global_endpoint": "domain.aliyuncs.com", + "regional_endpoint_pattern": "domain.aliyuncs.com" + }, + { + "code": "ros", + "document_id": "28899", + "location_service_code": "ros", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ros.aliyuncs.com" + } + ], + "global_endpoint": "ros.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudphoto", + "document_id": "59902", + "location_service_code": "cloudphoto", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "cloudphoto.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "cloudphoto.[RegionId].aliyuncs.com" + }, + { + "code": "rtc", + "document_id": "", + "location_service_code": "rtc", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "rtc.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "odpsmayi", + "document_id": "", + "location_service_code": "odpsmayi", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "bsb.cloud.alipay.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "bsb.cloud.alipay.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ims", + "document_id": "", + "location_service_code": "ims", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ims.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "csb", + "document_id": "64837", + "location_service_code": "csb", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "csb.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "csb.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "csb.[RegionId].aliyuncs.com" + }, + { + "code": "cds", + "document_id": "62887", + "location_service_code": "codepipeline", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "cds.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "cds.cn-beijing.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "ddosbgp", + "document_id": "", + "location_service_code": "ddosbgp", + "regional_endpoints": [ + { + "region": "cn-huhehaote", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ddosbgp.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ddosbgp.us-west-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ddosbgp.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dybaseapi", + "document_id": "", + "location_service_code": "dybaseapi", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-chengdu", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dybaseapi.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "dybaseapi.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ecs", + "document_id": "25484", + "location_service_code": "ecs", + "regional_endpoints": [ + { + "region": "cn-huhehaote", + "endpoint": "ecs.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "ecs.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ecs.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "ecs.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "ecs.ap-southeast-3.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ecs.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ecs.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "ecs.eu-west-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "ecs.me-east-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "ecs.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ecs-cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "ecs-cn-hangzhou.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "ccc", + "document_id": "63027", + "location_service_code": "ccc", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ccc.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ccc.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "ccc.[RegionId].aliyuncs.com" + }, + { + "code": "cs", + "document_id": "26043", + "location_service_code": "cs", + "regional_endpoints": null, + "global_endpoint": "cs.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "drdspre", + "document_id": "", + "location_service_code": "drdspre", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "drds.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "drds.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "drds.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "drds.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "drds.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "drds.cn-qingdao.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "drds.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dcdn", + "document_id": "", + "location_service_code": "dcdn", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "dcdn.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "dcdn.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "linkedmall", + "document_id": "", + "location_service_code": "linkedmall", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "linkedmall.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "linkedmall.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "trademark", + "document_id": "", + "location_service_code": "trademark", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "trademark.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "openanalytics", + "document_id": "", + "location_service_code": "openanalytics", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "openanalytics.cn-shenzhen.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "openanalytics.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "openanalytics.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "openanalytics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "openanalytics.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "openanalytics.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "openanalytics.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "openanalytics.cn-zhangjiakou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "sts", + "document_id": "28756", + "location_service_code": "sts", + "regional_endpoints": null, + "global_endpoint": "sts.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "waf", + "document_id": "62847", + "location_service_code": "waf", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "wafopenapi.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ots", + "document_id": "", + "location_service_code": "ots", + "regional_endpoints": [ + { + "region": "me-east-1", + "endpoint": "ots.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "ots.ap-southeast-5.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "ots.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "ots.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ots.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ots.ap-southeast-2.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ots.us-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "ots.us-east-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "ots.ap-south-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ots.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ots.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ots.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "ots.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ots.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ots.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "ots.ap-southeast-3.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cloudfirewall", + "document_id": "", + "location_service_code": "cloudfirewall", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cloudfw.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dm", + "document_id": "29434", + "location_service_code": "dm", + "regional_endpoints": [ + { + "region": "ap-southeast-2", + "endpoint": "dm.ap-southeast-2.aliyuncs.com" + } + ], + "global_endpoint": "dm.aliyuncs.com", + "regional_endpoint_pattern": "dm.[RegionId].aliyuncs.com" + }, + { + "code": "oas", + "document_id": "", + "location_service_code": "oas", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "cn-shenzhen.oas.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "cn-beijing.oas.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "cn-hangzhou.oas.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ddoscoo", + "document_id": "", + "location_service_code": "ddoscoo", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ddoscoo.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "jaq", + "document_id": "35037", + "location_service_code": "jaq", + "regional_endpoints": null, + "global_endpoint": "jaq.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "iovcc", + "document_id": "", + "location_service_code": "iovcc", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "iovcc.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "sas-api", + "document_id": "28498", + "location_service_code": "sas", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "sas.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "chatbot", + "document_id": "60760", + "location_service_code": "beebot", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "chatbot.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "chatbot.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "chatbot.[RegionId].aliyuncs.com" + }, + { + "code": "airec", + "document_id": "", + "location_service_code": "airec", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "airec.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "airec.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "airec.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "dmsenterprise", + "document_id": "", + "location_service_code": "dmsenterprise", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "dms-enterprise.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "dms-enterprise.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ivision", + "document_id": "", + "location_service_code": "ivision", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ivision.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ivision.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "odpsplusmayi", + "document_id": "", + "location_service_code": "odpsplusmayi", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "bsb.cloud.alipay.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "bsb.cloud.alipay.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "bsb.cloud.alipay.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "gameshield", + "document_id": "", + "location_service_code": "gameshield", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "gameshield.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "gameshield.cn-zhangjiakou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "scdn", + "document_id": "", + "location_service_code": "scdn", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "scdn.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hitsdb", + "document_id": "", + "location_service_code": "hitsdb", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "hitsdb.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hdm", + "document_id": "", + "location_service_code": "hdm", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "hdm-api.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "slb", + "document_id": "27565", + "location_service_code": "slb", + "regional_endpoints": [ + { + "region": "cn-shenzhen", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "slb.eu-west-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "slb.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "slb.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "slb.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "slb.ap-south-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "slb.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "slb.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "slb.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "slb.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "slb.me-east-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "slb.cn-zhangjiakou.aliyuncs.com" + } + ], + "global_endpoint": "slb.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "green", + "document_id": "28427", + "location_service_code": "green", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "green.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "green.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "green.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "green.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "green.us-west-1.aliyuncs.com" + } + ], + "global_endpoint": "green.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cccvn", + "document_id": "", + "location_service_code": "cccvn", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "voicenavigator.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ddosrewards", + "document_id": "", + "location_service_code": "ddosrewards", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ddosright.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "iot", + "document_id": "30557", + "location_service_code": "iot", + "regional_endpoints": [ + { + "region": "us-east-1", + "endpoint": "iot.us-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "iot.ap-northeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "iot.us-west-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "iot.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "iot.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "iot.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "iot.[RegionId].aliyuncs.com" + }, + { + "code": "bssopenapi", + "document_id": "", + "location_service_code": "bssopenapi", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "business.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "business.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "sca", + "document_id": "", + "location_service_code": "sca", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "qualitycheck.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "luban", + "document_id": "", + "location_service_code": "luban", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "luban.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "luban.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "drdspost", + "document_id": "", + "location_service_code": "drdspost", + "regional_endpoints": [ + { + "region": "cn-shanghai", + "endpoint": "drds.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "drds.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "drds.ap-southeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "drds", + "document_id": "51111", + "location_service_code": "drds", + "regional_endpoints": [ + { + "region": "ap-southeast-1", + "endpoint": "drds.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "drds.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "drds.aliyuncs.com", + "regional_endpoint_pattern": "drds.aliyuncs.com" + }, + { + "code": "httpdns", + "document_id": "52679", + "location_service_code": "httpdns", + "regional_endpoints": null, + "global_endpoint": "httpdns-api.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "cas", + "document_id": "", + "location_service_code": "cas", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "cas.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "cas.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "cas.ap-northeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "cas.eu-central-1.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "cas.me-east-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hpc", + "document_id": "35201", + "location_service_code": "hpc", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "hpc.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "hpc.aliyuncs.com" + } + ], + "global_endpoint": "hpc.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "ddosbasic", + "document_id": "", + "location_service_code": "ddosbasic", + "regional_endpoints": [ + { + "region": "ap-south-1", + "endpoint": "antiddos-openapi.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "antiddos-openapi.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "antiddos-openapi.ap-southeast-3.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "antiddos-openapi.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "antiddos-openapi.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "antiddos-openapi.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "antiddos-openapi.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "antiddos-openapi.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "antiddos-openapi.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "antiddos.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "antiddos-openapi.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "antiddos.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "clouddesktop", + "document_id": "", + "location_service_code": "clouddesktop", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "clouddesktop.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "clouddesktop.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "clouddesktop.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "clouddesktop.cn-shenzhen.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "uis", + "document_id": "", + "location_service_code": "uis", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "uis.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "imm", + "document_id": "", + "location_service_code": "imm", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "imm.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "imm.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "imm.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "imm.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "imm.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "imm.cn-shenzhen.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ens", + "document_id": "", + "location_service_code": "ens", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ens.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ram", + "document_id": "28672", + "location_service_code": "ram", + "regional_endpoints": null, + "global_endpoint": "ram.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "hcs_mgw", + "document_id": "", + "location_service_code": "hcs_mgw", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "mgw.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "mgw.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "mgw.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "itaas", + "document_id": "55759", + "location_service_code": "itaas", + "regional_endpoints": null, + "global_endpoint": "itaas.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "qualitycheck", + "document_id": "50807", + "location_service_code": "qualitycheck", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "qualitycheck.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "alikafka", + "document_id": "", + "location_service_code": "alikafka", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "alikafka.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "alikafka.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "alikafka.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "alikafka.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "alikafka.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "alikafka.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "alikafka.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "alikafka.cn-qingdao.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "faas", + "document_id": "", + "location_service_code": "faas", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "faas.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "faas.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "faas.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "faas.cn-beijing.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "alidfs", + "document_id": "", + "location_service_code": "alidfs", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "dfs.cn-beijing.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "dfs.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "cms", + "document_id": "28615", + "location_service_code": "cms", + "regional_endpoints": [ + { + "region": "ap-southeast-3", + "endpoint": "metrics.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "metrics.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "metrics.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "metrics.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "metrics.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "metrics.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "metrics.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "metrics.cn-hangzhou.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "domain-intl", + "document_id": "", + "location_service_code": "domain-intl", + "regional_endpoints": null, + "global_endpoint": "domain-intl.aliyuncs.com", + "regional_endpoint_pattern": "domain-intl.aliyuncs.com" + }, + { + "code": "kvstore", + "document_id": "", + "location_service_code": "kvstore", + "regional_endpoints": [ + { + "region": "ap-northeast-1", + "endpoint": "r-kvstore.ap-northeast-1.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ccs", + "document_id": "", + "location_service_code": "ccs", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "ccs.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "ess", + "document_id": "25925", + "location_service_code": "ess", + "regional_endpoints": [ + { + "region": "cn-huhehaote", + "endpoint": "ess.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "ess.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "ess.eu-west-1.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "ess.ap-southeast-5.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "ess.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "ess.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "ess.me-east-1.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "ess.ap-northeast-1.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "ess.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "ess.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "ess.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "ess.aliyuncs.com" + } + ], + "global_endpoint": "ess.aliyuncs.com", + "regional_endpoint_pattern": "ess.[RegionId].aliyuncs.com" + }, + { + "code": "dds", + "document_id": "61715", + "location_service_code": "dds", + "regional_endpoints": [ + { + "region": "me-east-1", + "endpoint": "mongodb.me-east-1.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "mongodb.ap-southeast-3.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "mongodb.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "mongodb.ap-northeast-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "mongodb.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "mongodb.eu-west-1.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "cn-huhehaote", + "endpoint": "mongodb.cn-huhehaote.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "mongodb.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "mongodb.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "mongodb.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "mongodb.ap-south-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "mongodb.aliyuncs.com" + } + ], + "global_endpoint": "mongodb.aliyuncs.com", + "regional_endpoint_pattern": "mongodb.[RegionId].aliyuncs.com" + }, + { + "code": "mts", + "document_id": "29212", + "location_service_code": "mts", + "regional_endpoints": [ + { + "region": "cn-beijing", + "endpoint": "mts.cn-beijing.aliyuncs.com" + }, + { + "region": "ap-northeast-1", + "endpoint": "mts.ap-northeast-1.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "mts.cn-hongkong.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "mts.cn-shenzhen.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "mts.cn-zhangjiakou.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "mts.ap-south-1.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "mts.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "mts.ap-southeast-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "mts.us-west-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "mts.eu-central-1.aliyuncs.com" + }, + { + "region": "eu-west-1", + "endpoint": "mts.eu-west-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "mts.cn-hangzhou.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "push", + "document_id": "30074", + "location_service_code": "push", + "regional_endpoints": null, + "global_endpoint": "cloudpush.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "hcs_sgw", + "document_id": "", + "location_service_code": "hcs_sgw", + "regional_endpoints": [ + { + "region": "eu-central-1", + "endpoint": "sgw.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-zhangjiakou", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "sgw.ap-southeast-1.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-hongkong", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "sgw.ap-southeast-2.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "sgw.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "hbase", + "document_id": "", + "location_service_code": "hbase", + "regional_endpoints": [ + { + "region": "cn-huhehaote", + "endpoint": "hbase.cn-huhehaote.aliyuncs.com" + }, + { + "region": "ap-south-1", + "endpoint": "hbase.ap-south-1.aliyuncs.com" + }, + { + "region": "us-west-1", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "me-east-1", + "endpoint": "hbase.me-east-1.aliyuncs.com" + }, + { + "region": "eu-central-1", + "endpoint": "hbase.eu-central-1.aliyuncs.com" + }, + { + "region": "cn-qingdao", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "cn-shenzhen", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "ap-southeast-2", + "endpoint": "hbase.ap-southeast-2.aliyuncs.com" + }, + { + "region": "ap-southeast-3", + "endpoint": "hbase.ap-southeast-3.aliyuncs.com" + }, + { + "region": "cn-hangzhou", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "us-east-1", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "ap-southeast-5", + "endpoint": "hbase.ap-southeast-5.aliyuncs.com" + }, + { + "region": "cn-beijing", + "endpoint": "hbase.aliyuncs.com" + }, + { + "region": "ap-southeast-1", + "endpoint": "hbase.aliyuncs.com" + } + ], + "global_endpoint": "hbase.aliyuncs.com", + "regional_endpoint_pattern": "" + }, + { + "code": "bastionhost", + "document_id": "", + "location_service_code": "bastionhost", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "yundun-bastionhost.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + }, + { + "code": "vs", + "document_id": "", + "location_service_code": "vs", + "regional_endpoints": [ + { + "region": "cn-hangzhou", + "endpoint": "vs.cn-hangzhou.aliyuncs.com" + }, + { + "region": "cn-shanghai", + "endpoint": "vs.cn-shanghai.aliyuncs.com" + } + ], + "global_endpoint": "", + "regional_endpoint_pattern": "" + } + ] +}` +var initOnce sync.Once +var data interface{} + +func getEndpointConfigData() interface{} { + initOnce.Do(func() { + err := json.Unmarshal([]byte(endpointsJson), &data) + if err != nil { + panic(fmt.Sprintf("init endpoint config data failed. %s", err)) + } + }) + return data +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go new file mode 100644 index 000000000..160e62cb6 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_global_resolver.go @@ -0,0 +1,43 @@ +/* + * 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. + */ + +package endpoints + +import ( + "fmt" + "strings" + + "github.com/jmespath/go-jmespath" +) + +type LocalGlobalResolver struct { +} + +func (resolver *LocalGlobalResolver) GetName() (name string) { + name = "local global resolver" + return +} + +func (resolver *LocalGlobalResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + // get the global endpoints configs + endpointExpression := fmt.Sprintf("products[?code=='%s'].global_endpoint", strings.ToLower(param.Product)) + endpointData, err := jmespath.Search(endpointExpression, getEndpointConfigData()) + if err == nil && endpointData != nil && len(endpointData.([]interface{})) > 0 { + endpoint = endpointData.([]interface{})[0].(string) + support = len(endpoint) > 0 + return + } + support = false + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go new file mode 100644 index 000000000..7fee64d42 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/local_regional_resolver.go @@ -0,0 +1,48 @@ +/* + * 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. + */ + +package endpoints + +import ( + "fmt" + "strings" + + "github.com/jmespath/go-jmespath" +) + +type LocalRegionalResolver struct { +} + +func (resolver *LocalRegionalResolver) GetName() (name string) { + name = "local regional resolver" + return +} + +func (resolver *LocalRegionalResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + // get the regional endpoints configs + regionalExpression := fmt.Sprintf("products[?code=='%s'].regional_endpoints", strings.ToLower(param.Product)) + regionalData, err := jmespath.Search(regionalExpression, getEndpointConfigData()) + if err == nil && regionalData != nil && len(regionalData.([]interface{})) > 0 { + endpointExpression := fmt.Sprintf("[0][?region=='%s'].endpoint", strings.ToLower(param.RegionId)) + var endpointData interface{} + endpointData, err = jmespath.Search(endpointExpression, regionalData) + if err == nil && endpointData != nil && len(endpointData.([]interface{})) > 0 { + endpoint = endpointData.([]interface{})[0].(string) + support = len(endpoint) > 0 + return + } + } + support = false + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go new file mode 100644 index 000000000..cc354cc4d --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/location_resolver.go @@ -0,0 +1,176 @@ +/* + * 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. + */ +package endpoints + +import ( + "encoding/json" + "sync" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" +) + +const ( + // EndpointCacheExpireTime ... + EndpointCacheExpireTime = 3600 //Seconds +) + +// Cache caches endpoint for specific product and region +type Cache struct { + sync.RWMutex + cache map[string]interface{} +} + +// Get ... +func (c *Cache) Get(k string) (v interface{}) { + c.RLock() + v = c.cache[k] + c.RUnlock() + return +} + +// Set ... +func (c *Cache) Set(k string, v interface{}) { + c.Lock() + c.cache[k] = v + c.Unlock() +} + +var lastClearTimePerProduct = &Cache{cache: make(map[string]interface{})} +var endpointCache = &Cache{cache: make(map[string]interface{})} + +// LocationResolver ... +type LocationResolver struct { +} + +func (resolver *LocationResolver) GetName() (name string) { + name = "location resolver" + return +} + +// TryResolve resolves endpoint giving product and region +func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + if len(param.LocationProduct) <= 0 { + support = false + return + } + + //get from cache + cacheKey := param.Product + "#" + param.RegionId + var ok bool + endpoint, ok = endpointCache.Get(cacheKey).(string) + + if ok && len(endpoint) > 0 && !CheckCacheIsExpire(cacheKey) { + support = true + return + } + + //get from remote + getEndpointRequest := requests.NewCommonRequest() + + getEndpointRequest.Product = "Location" + getEndpointRequest.Version = "2015-06-12" + getEndpointRequest.ApiName = "DescribeEndpoints" + getEndpointRequest.Domain = "location-readonly.aliyuncs.com" + getEndpointRequest.Method = "GET" + getEndpointRequest.Scheme = requests.HTTPS + + getEndpointRequest.QueryParams["Id"] = param.RegionId + getEndpointRequest.QueryParams["ServiceCode"] = param.LocationProduct + if len(param.LocationEndpointType) > 0 { + getEndpointRequest.QueryParams["Type"] = param.LocationEndpointType + } else { + getEndpointRequest.QueryParams["Type"] = "openAPI" + } + + response, err := param.CommonApi(getEndpointRequest) + if err != nil { + support = false + return + } + + if !response.IsSuccess() { + support = false + return + } + + var getEndpointResponse GetEndpointResponse + err = json.Unmarshal([]byte(response.GetHttpContentString()), &getEndpointResponse) + if err != nil { + support = false + return + } + + if !getEndpointResponse.Success || getEndpointResponse.Endpoints == nil { + support = false + return + } + if len(getEndpointResponse.Endpoints.Endpoint) <= 0 { + support = false + return + } + if len(getEndpointResponse.Endpoints.Endpoint[0].Endpoint) > 0 { + endpoint = getEndpointResponse.Endpoints.Endpoint[0].Endpoint + endpointCache.Set(cacheKey, endpoint) + lastClearTimePerProduct.Set(cacheKey, time.Now().Unix()) + support = true + return + } + + support = false + return +} + +// CheckCacheIsExpire ... +func CheckCacheIsExpire(cacheKey string) bool { + lastClearTime, ok := lastClearTimePerProduct.Get(cacheKey).(int64) + if !ok { + return true + } + + if lastClearTime <= 0 { + lastClearTime = time.Now().Unix() + lastClearTimePerProduct.Set(cacheKey, lastClearTime) + } + + now := time.Now().Unix() + elapsedTime := now - lastClearTime + if elapsedTime > EndpointCacheExpireTime { + return true + } + + return false +} + +// GetEndpointResponse ... +type GetEndpointResponse struct { + Endpoints *EndpointsObj + RequestId string + Success bool +} + +// EndpointsObj ... +type EndpointsObj struct { + Endpoint []EndpointObj +} + +// EndpointObj ... +type EndpointObj struct { + // Protocols map[string]string + Type string + Namespace string + Id string + SerivceCode string + Endpoint string +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go new file mode 100644 index 000000000..e39f53367 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/mapping_resolver.go @@ -0,0 +1,48 @@ +/* + * 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. + */ + +package endpoints + +import ( + "fmt" + "strings" +) + +const keyFormatter = "%s::%s" + +var endpointMapping = make(map[string]string) + +// AddEndpointMapping Use product id and region id as key to store the endpoint into inner map +func AddEndpointMapping(regionId, productId, endpoint string) (err error) { + key := fmt.Sprintf(keyFormatter, strings.ToLower(regionId), strings.ToLower(productId)) + endpointMapping[key] = endpoint + return nil +} + +// MappingResolver the mapping resolver type +type MappingResolver struct { +} + +// GetName get the resolver name: "mapping resolver" +func (resolver *MappingResolver) GetName() (name string) { + name = "mapping resolver" + return +} + +// TryResolve use Product and RegionId as key to find endpoint from inner map +func (resolver *MappingResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + key := fmt.Sprintf(keyFormatter, strings.ToLower(param.RegionId), strings.ToLower(param.Product)) + endpoint, contains := endpointMapping[key] + return endpoint, contains, nil +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go new file mode 100644 index 000000000..5e1e30530 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/resolver.go @@ -0,0 +1,98 @@ +/* + * 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. + */ + +package endpoints + +import ( + "encoding/json" + "fmt" + "sync" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +var debug utils.Debug + +func init() { + debug = utils.Init("sdk") +} + +const ( + ResolveEndpointUserGuideLink = "" +) + +var once sync.Once +var resolvers []Resolver + +type Resolver interface { + TryResolve(param *ResolveParam) (endpoint string, support bool, err error) + GetName() (name string) +} + +// Resolve resolve endpoint with params +// It will resolve with each supported resolver until anyone resolved +func Resolve(param *ResolveParam) (endpoint string, err error) { + supportedResolvers := getAllResolvers() + var lastErr error + for _, resolver := range supportedResolvers { + endpoint, supported, resolveErr := resolver.TryResolve(param) + if resolveErr != nil { + lastErr = resolveErr + } + + if supported { + debug("resolve endpoint with %s\n", param) + debug("\t%s by resolver(%s)\n", endpoint, resolver.GetName()) + return endpoint, nil + } + } + + // not support + errorMsg := fmt.Sprintf(errors.CanNotResolveEndpointErrorMessage, param, ResolveEndpointUserGuideLink) + err = errors.NewClientError(errors.CanNotResolveEndpointErrorCode, errorMsg, lastErr) + return +} + +func getAllResolvers() []Resolver { + once.Do(func() { + resolvers = []Resolver{ + &SimpleHostResolver{}, + &MappingResolver{}, + &LocationResolver{}, + &LocalRegionalResolver{}, + &LocalGlobalResolver{}, + } + }) + return resolvers +} + +type ResolveParam struct { + Domain string + Product string + RegionId string + LocationProduct string + LocationEndpointType string + CommonApi func(request *requests.CommonRequest) (response *responses.CommonResponse, err error) `json:"-"` +} + +func (param *ResolveParam) String() string { + jsonBytes, err := json.Marshal(param) + if err != nil { + return fmt.Sprint("ResolveParam.String() process error:", err) + } + return string(jsonBytes) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go new file mode 100644 index 000000000..9ba2346c6 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/endpoints/simple_host_resolver.go @@ -0,0 +1,33 @@ +/* + * 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. + */ + +package endpoints + +// SimpleHostResolver the simple host resolver type +type SimpleHostResolver struct { +} + +// GetName get the resolver name: "simple host resolver" +func (resolver *SimpleHostResolver) GetName() (name string) { + name = "simple host resolver" + return +} + +// TryResolve if the Domain exist in param, use it as endpoint +func (resolver *SimpleHostResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) { + if support = len(param.Domain) > 0; support { + endpoint = param.Domain + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go new file mode 100644 index 000000000..1e2d9c004 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/client_error.go @@ -0,0 +1,92 @@ +/* + * 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. + */ + +package errors + +import "fmt" + +const ( + DefaultClientErrorStatus = 400 + DefaultClientErrorCode = "SDK.ClientError" + + UnsupportedCredentialErrorCode = "SDK.UnsupportedCredential" + UnsupportedCredentialErrorMessage = "Specified credential (type = %s) is not supported, please check" + + CanNotResolveEndpointErrorCode = "SDK.CanNotResolveEndpoint" + CanNotResolveEndpointErrorMessage = "Can not resolve endpoint(param = %s), please check your accessKey with secret, and read the user guide\n %s" + + UnsupportedParamPositionErrorCode = "SDK.UnsupportedParamPosition" + UnsupportedParamPositionErrorMessage = "Specified param position (%s) is not supported, please upgrade sdk and retry" + + AsyncFunctionNotEnabledCode = "SDK.AsyncFunctionNotEnabled" + AsyncFunctionNotEnabledMessage = "Async function is not enabled in client, please invoke 'client.EnableAsync' function" + + UnknownRequestTypeErrorCode = "SDK.UnknownRequestType" + UnknownRequestTypeErrorMessage = "Unknown Request Type: %s" + + MissingParamErrorCode = "SDK.MissingParam" + InvalidParamErrorCode = "SDK.InvalidParam" + + JsonUnmarshalErrorCode = "SDK.JsonUnmarshalError" + JsonUnmarshalErrorMessage = "Failed to unmarshal response, but you can get the data via response.GetHttpStatusCode() and response.GetHttpContentString()" + + TimeoutErrorCode = "SDK.TimeoutError" + TimeoutErrorMessage = "The request timed out %s times(%s for retry), perhaps we should have the threshold raised a little?" +) + +type ClientError struct { + errorCode string + message string + originError error +} + +func NewClientError(errorCode, message string, originErr error) Error { + return &ClientError{ + errorCode: errorCode, + message: message, + originError: originErr, + } +} + +func (err *ClientError) Error() string { + clientErrMsg := fmt.Sprintf("[%s] %s", err.ErrorCode(), err.message) + if err.originError != nil { + return clientErrMsg + "\ncaused by:\n" + err.originError.Error() + } + return clientErrMsg +} + +func (err *ClientError) OriginError() error { + return err.originError +} + +func (*ClientError) HttpStatus() int { + return DefaultClientErrorStatus +} + +func (err *ClientError) ErrorCode() string { + if err.errorCode == "" { + return DefaultClientErrorCode + } else { + return err.errorCode + } +} + +func (err *ClientError) Message() string { + return err.message +} + +func (err *ClientError) String() string { + return err.Error() +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go new file mode 100644 index 000000000..49962f3b5 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/error.go @@ -0,0 +1,23 @@ +/* + * 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. + */ + +package errors + +type Error interface { + error + HttpStatus() int + ErrorCode() string + Message() string + OriginError() error +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go new file mode 100644 index 000000000..1b7810414 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/server_error.go @@ -0,0 +1,123 @@ +/* + * 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. + */ + +package errors + +import ( + "encoding/json" + "fmt" + + "github.com/jmespath/go-jmespath" +) + +var wrapperList = []ServerErrorWrapper{ + &SignatureDostNotMatchWrapper{}, +} + +type ServerError struct { + httpStatus int + requestId string + hostId string + errorCode string + recommend string + message string + comment string +} + +type ServerErrorWrapper interface { + tryWrap(error *ServerError, wrapInfo map[string]string) bool +} + +func (err *ServerError) Error() string { + return fmt.Sprintf("SDK.ServerError\nErrorCode: %s\nRecommend: %s\nRequestId: %s\nMessage: %s", + err.errorCode, err.comment+err.recommend, err.requestId, err.message) +} + +func NewServerError(httpStatus int, responseContent, comment string) Error { + result := &ServerError{ + httpStatus: httpStatus, + message: responseContent, + comment: comment, + } + + var data interface{} + err := json.Unmarshal([]byte(responseContent), &data) + if err == nil { + requestId, _ := jmespath.Search("RequestId", data) + hostId, _ := jmespath.Search("HostId", data) + errorCode, _ := jmespath.Search("Code", data) + recommend, _ := jmespath.Search("Recommend", data) + message, _ := jmespath.Search("Message", data) + + if requestId != nil { + result.requestId = requestId.(string) + } + if hostId != nil { + result.hostId = hostId.(string) + } + if errorCode != nil { + result.errorCode = errorCode.(string) + } + if recommend != nil { + result.recommend = recommend.(string) + } + if message != nil { + result.message = message.(string) + } + } + + return result +} + +func WrapServerError(originError *ServerError, wrapInfo map[string]string) *ServerError { + for _, wrapper := range wrapperList { + ok := wrapper.tryWrap(originError, wrapInfo) + if ok { + return originError + } + } + return originError +} + +func (err *ServerError) HttpStatus() int { + return err.httpStatus +} + +func (err *ServerError) ErrorCode() string { + return err.errorCode +} + +func (err *ServerError) Message() string { + return err.message +} + +func (err *ServerError) OriginError() error { + return nil +} + +func (err *ServerError) HostId() string { + return err.hostId +} + +func (err *ServerError) RequestId() string { + return err.requestId +} + +func (err *ServerError) Recommend() string { + return err.recommend +} + +func (err *ServerError) Comment() string { + return err.comment +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go new file mode 100644 index 000000000..4b09d7d71 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors/signature_does_not_match_wrapper.go @@ -0,0 +1,45 @@ +package errors + +import ( + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +const SignatureDostNotMatchErrorCode = "SignatureDoesNotMatch" +const IncompleteSignatureErrorCode = "IncompleteSignature" +const MessageContain = "server string to sign is:" + +var debug utils.Debug + +func init() { + debug = utils.Init("sdk") +} + +type SignatureDostNotMatchWrapper struct { +} + +func (*SignatureDostNotMatchWrapper) tryWrap(error *ServerError, wrapInfo map[string]string) (ok bool) { + clientStringToSign := wrapInfo["StringToSign"] + if (error.errorCode == SignatureDostNotMatchErrorCode || error.errorCode == IncompleteSignatureErrorCode) && clientStringToSign != "" { + message := error.message + if strings.Contains(message, MessageContain) { + str := strings.Split(message, MessageContain) + serverStringToSign := str[1] + + if clientStringToSign == serverStringToSign { + // user secret is error + error.recommend = "InvalidAccessKeySecret: Please check you AccessKeySecret" + } else { + debug("Client StringToSign: %s", clientStringToSign) + debug("Server StringToSign: %s", serverStringToSign) + error.recommend = "This may be a bug with the SDK and we hope you can submit this question in the " + + "github issue(https://github.com/aliyun/alibaba-cloud-sdk-go/issues), thanks very much" + } + } + ok = true + return + } + ok = false + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/logger.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/logger.go new file mode 100644 index 000000000..a01a7bbc9 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/logger.go @@ -0,0 +1,116 @@ +package sdk + +import ( + "encoding/json" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" + "io" + "log" + "os" + "strings" + "time" +) + +var logChannel string +var defaultChannel = "AlibabaCloud" + +type Logger struct { + *log.Logger + formatTemplate string + isOpen bool + lastLogMsg string +} + +var defaultLoggerTemplate = `{time} {channel}: "{method} {uri} HTTP/{version}" {code} {cost} {hostname}` +var loggerParam = []string{"{time}", "{start_time}", "{ts}", "{channel}", "{pid}", "{host}", "{method}", "{uri}", "{version}", "{target}", "{hostname}", "{code}", "{error}", "{req_headers}", "{res_body}", "{res_headers}", "{cost}"} + +func initLogMsg(fieldMap map[string]string) { + for _, value := range loggerParam { + fieldMap[value] = "" + } +} + +func (client *Client) GetLogger() *Logger { + return client.logger +} + +func (client *Client) GetLoggerMsg() string { + if client.logger == nil { + client.SetLogger("", "", os.Stdout, "") + } + return client.logger.lastLogMsg +} + +func (client *Client) SetLogger(level string, channel string, out io.Writer, template string) { + if level == "" { + level = "info" + } + + logChannel = "AlibabaCloud" + if channel != "" { + logChannel = channel + } + log := log.New(out, "["+strings.ToUpper(level)+"]", log.Lshortfile) + if template == "" { + template = defaultLoggerTemplate + } + + client.logger = &Logger{ + Logger: log, + formatTemplate: template, + isOpen: true, + } +} + +func (client *Client) OpenLogger() { + if client.logger == nil { + client.SetLogger("", "", os.Stdout, "") + } + client.logger.isOpen = true +} + +func (client *Client) CloseLogger() { + if client.logger != nil { + client.logger.isOpen = false + } +} + +func (client *Client) SetTemplate(template string) { + if client.logger == nil { + client.SetLogger("", "", os.Stdout, "") + } + client.logger.formatTemplate = template +} + +func (client *Client) GetTemplate() string { + if client.logger == nil { + client.SetLogger("", "", os.Stdout, "") + } + return client.logger.formatTemplate +} + +func TransToString(object interface{}) string { + byt, err := json.Marshal(object) + if err != nil { + return "" + } + return string(byt) +} + +func (client *Client) printLog(fieldMap map[string]string, err error) { + if err != nil { + fieldMap["{error}"] = err.Error() + } + fieldMap["{time}"] = time.Now().Format("2006-01-02 15:04:05") + fieldMap["{ts}"] = utils.GetTimeInFormatISO8601() + fieldMap["{channel}"] = logChannel + if client.logger != nil { + logMsg := client.logger.formatTemplate + for key, value := range fieldMap { + logMsg = strings.Replace(logMsg, key, value, -1) + } + client.logger.lastLogMsg = logMsg + if client.logger.isOpen == true { + client.logger.Output(2, logMsg) + } + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request.go new file mode 100644 index 000000000..846d448f2 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/acs_request.go @@ -0,0 +1,410 @@ +/* + * 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. + */ + +package requests + +import ( + "encoding/json" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" +) + +const ( + RPC = "RPC" + ROA = "ROA" + + HTTP = "HTTP" + HTTPS = "HTTPS" + + DefaultHttpPort = "80" + + GET = "GET" + PUT = "PUT" + POST = "POST" + DELETE = "DELETE" + HEAD = "HEAD" + OPTIONS = "OPTIONS" + + Json = "application/json" + Xml = "application/xml" + Raw = "application/octet-stream" + Form = "application/x-www-form-urlencoded" + + Header = "Header" + Query = "Query" + Body = "Body" + Path = "Path" + + HeaderSeparator = "\n" +) + +// interface +type AcsRequest interface { + GetScheme() string + GetMethod() string + GetDomain() string + GetPort() string + GetRegionId() string + GetHeaders() map[string]string + GetQueryParams() map[string]string + GetFormParams() map[string]string + GetContent() []byte + GetBodyReader() io.Reader + GetStyle() string + GetProduct() string + GetVersion() string + SetVersion(version string) + GetActionName() string + GetAcceptFormat() string + GetLocationServiceCode() string + GetLocationEndpointType() string + GetReadTimeout() time.Duration + GetConnectTimeout() time.Duration + SetReadTimeout(readTimeout time.Duration) + SetConnectTimeout(connectTimeout time.Duration) + SetHTTPSInsecure(isInsecure bool) + GetHTTPSInsecure() *bool + + GetUserAgent() map[string]string + + SetStringToSign(stringToSign string) + GetStringToSign() string + + SetDomain(domain string) + SetContent(content []byte) + SetScheme(scheme string) + BuildUrl() string + BuildQueries() string + + addHeaderParam(key, value string) + addQueryParam(key, value string) + addFormParam(key, value string) + addPathParam(key, value string) +} + +// base class +type baseRequest struct { + Scheme string + Method string + Domain string + Port string + RegionId string + ReadTimeout time.Duration + ConnectTimeout time.Duration + isInsecure *bool + + userAgent map[string]string + product string + version string + + actionName string + + AcceptFormat string + + QueryParams map[string]string + Headers map[string]string + FormParams map[string]string + Content []byte + + locationServiceCode string + locationEndpointType string + + queries string + + stringToSign string +} + +func (request *baseRequest) GetQueryParams() map[string]string { + return request.QueryParams +} + +func (request *baseRequest) GetFormParams() map[string]string { + return request.FormParams +} + +func (request *baseRequest) GetReadTimeout() time.Duration { + return request.ReadTimeout +} + +func (request *baseRequest) GetConnectTimeout() time.Duration { + return request.ConnectTimeout +} + +func (request *baseRequest) SetReadTimeout(readTimeout time.Duration) { + request.ReadTimeout = readTimeout +} + +func (request *baseRequest) SetConnectTimeout(connectTimeout time.Duration) { + request.ConnectTimeout = connectTimeout +} + +func (request *baseRequest) GetHTTPSInsecure() *bool { + return request.isInsecure +} + +func (request *baseRequest) SetHTTPSInsecure(isInsecure bool) { + request.isInsecure = &isInsecure +} + +func (request *baseRequest) GetContent() []byte { + return request.Content +} + +func (request *baseRequest) SetVersion(version string) { + request.version = version +} + +func (request *baseRequest) GetVersion() string { + return request.version +} + +func (request *baseRequest) GetActionName() string { + return request.actionName +} + +func (request *baseRequest) SetContent(content []byte) { + request.Content = content +} + +func (request *baseRequest) GetUserAgent() map[string]string { + return request.userAgent +} + +func (request *baseRequest) AppendUserAgent(key, value string) { + newkey := true + if request.userAgent == nil { + request.userAgent = make(map[string]string) + } + if strings.ToLower(key) != "core" && strings.ToLower(key) != "go" { + for tag, _ := range request.userAgent { + if tag == key { + request.userAgent[tag] = value + newkey = false + } + } + if newkey { + request.userAgent[key] = value + } + } +} + +func (request *baseRequest) addHeaderParam(key, value string) { + request.Headers[key] = value +} + +func (request *baseRequest) addQueryParam(key, value string) { + request.QueryParams[key] = value +} + +func (request *baseRequest) addFormParam(key, value string) { + request.FormParams[key] = value +} + +func (request *baseRequest) GetAcceptFormat() string { + return request.AcceptFormat +} + +func (request *baseRequest) GetLocationServiceCode() string { + return request.locationServiceCode +} + +func (request *baseRequest) GetLocationEndpointType() string { + return request.locationEndpointType +} + +func (request *baseRequest) GetProduct() string { + return request.product +} + +func (request *baseRequest) GetScheme() string { + return request.Scheme +} + +func (request *baseRequest) SetScheme(scheme string) { + request.Scheme = scheme +} + +func (request *baseRequest) GetMethod() string { + return request.Method +} + +func (request *baseRequest) GetDomain() string { + return request.Domain +} + +func (request *baseRequest) SetDomain(host string) { + request.Domain = host +} + +func (request *baseRequest) GetPort() string { + return request.Port +} + +func (request *baseRequest) GetRegionId() string { + return request.RegionId +} + +func (request *baseRequest) GetHeaders() map[string]string { + return request.Headers +} + +func (request *baseRequest) SetContentType(contentType string) { + request.addHeaderParam("Content-Type", contentType) +} + +func (request *baseRequest) GetContentType() (contentType string, contains bool) { + contentType, contains = request.Headers["Content-Type"] + return +} + +func (request *baseRequest) SetStringToSign(stringToSign string) { + request.stringToSign = stringToSign +} + +func (request *baseRequest) GetStringToSign() string { + return request.stringToSign +} + +func defaultBaseRequest() (request *baseRequest) { + request = &baseRequest{ + Scheme: "", + AcceptFormat: "JSON", + Method: GET, + QueryParams: make(map[string]string), + Headers: map[string]string{ + "x-sdk-client": "golang/1.0.0", + "x-sdk-invoke-type": "normal", + "Accept-Encoding": "identity", + }, + FormParams: make(map[string]string), + } + return +} + +func InitParams(request AcsRequest) (err error) { + requestValue := reflect.ValueOf(request).Elem() + err = flatRepeatedList(requestValue, request, "", "") + return +} + +func flatRepeatedList(dataValue reflect.Value, request AcsRequest, position, prefix string) (err error) { + dataType := dataValue.Type() + for i := 0; i < dataType.NumField(); i++ { + field := dataType.Field(i) + name, containsNameTag := field.Tag.Lookup("name") + fieldPosition := position + if fieldPosition == "" { + fieldPosition, _ = field.Tag.Lookup("position") + } + typeTag, containsTypeTag := field.Tag.Lookup("type") + if containsNameTag { + if !containsTypeTag { + // simple param + key := prefix + name + value := dataValue.Field(i).String() + if dataValue.Field(i).Kind().String() == "map" { + byt, _ := json.Marshal(dataValue.Field(i).Interface()) + value = string(byt) + } + err = addParam(request, fieldPosition, key, value) + if err != nil { + return + } + } else if typeTag == "Repeated" { + // repeated param + repeatedFieldValue := dataValue.Field(i) + if repeatedFieldValue.Kind() != reflect.Slice { + // possible value: {"[]string", "*[]struct"}, we must call Elem() in the last condition + repeatedFieldValue = repeatedFieldValue.Elem() + } + if repeatedFieldValue.IsValid() && !repeatedFieldValue.IsNil() { + for m := 0; m < repeatedFieldValue.Len(); m++ { + elementValue := repeatedFieldValue.Index(m) + key := prefix + name + "." + strconv.Itoa(m+1) + if elementValue.Type().Kind().String() == "string" { + value := elementValue.String() + err = addParam(request, fieldPosition, key, value) + if err != nil { + return + } + } else { + err = flatRepeatedList(elementValue, request, fieldPosition, key+".") + if err != nil { + return + } + } + } + } + } else if typeTag == "Struct" { + valueField := dataValue.Field(i) + if valueField.Kind() == reflect.Struct { + if valueField.IsValid() && valueField.String() != "" { + valueFieldType := valueField.Type() + for m := 0; m < valueFieldType.NumField(); m++ { + fieldName := valueFieldType.Field(m).Name + elementValue := valueField.FieldByName(fieldName) + key := prefix + name + "." + fieldName + if elementValue.Type().String() == "[]string" { + for j := 0; j < elementValue.Len(); j++ { + err = addParam(request, fieldPosition, key+"."+strconv.Itoa(j+1), elementValue.Index(j).String()) + if err != nil { + return + } + } + } else { + // value := elementValue.String() + // err = addParam(request, fieldPosition, key, value) + // if err != nil { + // return + // } + // } else { + // err = flatRepeatedList(elementValue, request, fieldPosition, key+".") + // if err != nil { + // return + // } + // } + } + } + } + } + } + } + } + return +} + +func addParam(request AcsRequest, position, name, value string) (err error) { + if len(value) > 0 { + switch position { + case Header: + request.addHeaderParam(name, value) + case Query: + request.addQueryParam(name, value) + case Path: + request.addPathParam(name, value) + case Body: + request.addFormParam(name, value) + default: + errMsg := fmt.Sprintf(errors.UnsupportedParamPositionErrorMessage, position) + err = errors.NewClientError(errors.UnsupportedParamPositionErrorCode, errMsg, nil) + } + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go new file mode 100644 index 000000000..80c170097 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/common_request.go @@ -0,0 +1,108 @@ +package requests + +import ( + "bytes" + "fmt" + "io" + "sort" + "strings" +) + +type CommonRequest struct { + *baseRequest + + Version string + ApiName string + Product string + ServiceCode string + + // roa params + PathPattern string + PathParams map[string]string + + Ontology AcsRequest +} + +func NewCommonRequest() (request *CommonRequest) { + request = &CommonRequest{ + baseRequest: defaultBaseRequest(), + } + request.Headers["x-sdk-invoke-type"] = "common" + request.PathParams = make(map[string]string) + return +} + +func (request *CommonRequest) String() string { + request.TransToAcsRequest() + + resultBuilder := bytes.Buffer{} + + mapOutput := func(m map[string]string) { + if len(m) > 0 { + sortedKeys := make([]string, 0) + for k := range m { + sortedKeys = append(sortedKeys, k) + } + + // sort 'string' key in increasing order + sort.Strings(sortedKeys) + + for _, key := range sortedKeys { + resultBuilder.WriteString(key + ": " + m[key] + "\n") + } + } + } + + // Request Line + resultBuilder.WriteString(fmt.Sprintf("%s %s %s/1.1\n", request.Method, request.BuildQueries(), strings.ToUpper(request.Scheme))) + + // Headers + resultBuilder.WriteString("Host" + ": " + request.Domain + "\n") + mapOutput(request.Headers) + + resultBuilder.WriteString("\n") + // Body + if len(request.Content) > 0 { + resultBuilder.WriteString(string(request.Content) + "\n") + } else { + mapOutput(request.FormParams) + } + + return resultBuilder.String() +} + +func (request *CommonRequest) TransToAcsRequest() { + if len(request.PathPattern) > 0 { + roaRequest := &RoaRequest{} + roaRequest.initWithCommonRequest(request) + request.Ontology = roaRequest + } else { + rpcRequest := &RpcRequest{} + rpcRequest.baseRequest = request.baseRequest + rpcRequest.product = request.Product + rpcRequest.version = request.Version + rpcRequest.locationServiceCode = request.ServiceCode + rpcRequest.actionName = request.ApiName + request.Ontology = rpcRequest + } +} + +func (request *CommonRequest) BuildUrl() string { + return request.Ontology.BuildUrl() +} + +func (request *CommonRequest) BuildQueries() string { + return request.Ontology.BuildQueries() +} + +func (request *CommonRequest) GetBodyReader() io.Reader { + return request.Ontology.GetBodyReader() +} + +func (request *CommonRequest) GetStyle() string { + return request.Ontology.GetStyle() +} + +func (request *CommonRequest) addPathParam(key, value string) { + request.PathParams[key] = value +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go new file mode 100644 index 000000000..70b856e3c --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/roa_request.go @@ -0,0 +1,152 @@ +/* + * 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. + */ + +package requests + +import ( + "bytes" + "fmt" + "io" + "net/url" + "sort" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +type RoaRequest struct { + *baseRequest + pathPattern string + PathParams map[string]string +} + +func (*RoaRequest) GetStyle() string { + return ROA +} + +func (request *RoaRequest) GetBodyReader() io.Reader { + if request.FormParams != nil && len(request.FormParams) > 0 { + formString := utils.GetUrlFormedMap(request.FormParams) + return strings.NewReader(formString) + } else if len(request.Content) > 0 { + return bytes.NewReader(request.Content) + } else { + return nil + } +} + +// for sign method, need not url encoded +func (request *RoaRequest) BuildQueries() string { + return request.buildQueries() +} + +func (request *RoaRequest) buildPath() string { + path := request.pathPattern + for key, value := range request.PathParams { + path = strings.Replace(path, "["+key+"]", value, 1) + } + return path +} + +func (request *RoaRequest) buildQueries() string { + // replace path params with value + path := request.buildPath() + queryParams := request.QueryParams + // sort QueryParams by key + var queryKeys []string + for key := range queryParams { + queryKeys = append(queryKeys, key) + } + sort.Strings(queryKeys) + + // append urlBuilder + urlBuilder := bytes.Buffer{} + urlBuilder.WriteString(path) + if len(queryKeys) > 0 { + urlBuilder.WriteString("?") + } + for i := 0; i < len(queryKeys); i++ { + queryKey := queryKeys[i] + urlBuilder.WriteString(queryKey) + if value := queryParams[queryKey]; len(value) > 0 { + urlBuilder.WriteString("=") + urlBuilder.WriteString(value) + } + if i < len(queryKeys)-1 { + urlBuilder.WriteString("&") + } + } + result := urlBuilder.String() + result = popStandardUrlencode(result) + return result +} + +func (request *RoaRequest) buildQueryString() string { + queryParams := request.QueryParams + // sort QueryParams by key + q := url.Values{} + for key, value := range queryParams { + q.Add(key, value) + } + return q.Encode() +} + +func popStandardUrlencode(stringToSign string) (result string) { + result = strings.Replace(stringToSign, "+", "%20", -1) + result = strings.Replace(result, "*", "%2A", -1) + result = strings.Replace(result, "%7E", "~", -1) + return +} + +func (request *RoaRequest) BuildUrl() string { + // for network trans, need url encoded + scheme := strings.ToLower(request.Scheme) + domain := request.Domain + port := request.Port + path := request.buildPath() + url := fmt.Sprintf("%s://%s:%s%s", scheme, domain, port, path) + querystring := request.buildQueryString() + if len(querystring) > 0 { + url = fmt.Sprintf("%s?%s", url, querystring) + } + return url +} + +func (request *RoaRequest) addPathParam(key, value string) { + request.PathParams[key] = value +} + +func (request *RoaRequest) InitWithApiInfo(product, version, action, uriPattern, serviceCode, endpointType string) { + request.baseRequest = defaultBaseRequest() + request.PathParams = make(map[string]string) + request.Headers["x-acs-version"] = version + request.pathPattern = uriPattern + request.locationServiceCode = serviceCode + request.locationEndpointType = endpointType + request.product = product + //request.version = version + request.actionName = action +} + +func (request *RoaRequest) initWithCommonRequest(commonRequest *CommonRequest) { + request.baseRequest = commonRequest.baseRequest + request.PathParams = commonRequest.PathParams + request.product = commonRequest.Product + //request.version = commonRequest.Version + request.Headers["x-acs-version"] = commonRequest.Version + request.actionName = commonRequest.ApiName + request.pathPattern = commonRequest.PathPattern + request.locationServiceCode = commonRequest.ServiceCode + request.locationEndpointType = "" +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go new file mode 100644 index 000000000..01be6fd04 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/rpc_request.go @@ -0,0 +1,79 @@ +/* + * 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. + */ + +package requests + +import ( + "fmt" + "io" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils" +) + +type RpcRequest struct { + *baseRequest +} + +func (request *RpcRequest) init() { + request.baseRequest = defaultBaseRequest() + request.Method = POST +} + +func (*RpcRequest) GetStyle() string { + return RPC +} + +func (request *RpcRequest) GetBodyReader() io.Reader { + if request.FormParams != nil && len(request.FormParams) > 0 { + formString := utils.GetUrlFormedMap(request.FormParams) + return strings.NewReader(formString) + } else { + return strings.NewReader("") + } +} + +func (request *RpcRequest) BuildQueries() string { + request.queries = "/?" + utils.GetUrlFormedMap(request.QueryParams) + return request.queries +} + +func (request *RpcRequest) BuildUrl() string { + url := fmt.Sprintf("%s://%s", strings.ToLower(request.Scheme), request.Domain) + if len(request.Port) > 0 { + url = fmt.Sprintf("%s:%s", url, request.Port) + } + return url + request.BuildQueries() +} + +func (request *RpcRequest) GetVersion() string { + return request.version +} + +func (request *RpcRequest) GetActionName() string { + return request.actionName +} + +func (request *RpcRequest) addPathParam(key, value string) { + panic("not support") +} + +func (request *RpcRequest) InitWithApiInfo(product, version, action, serviceCode, endpointType string) { + request.init() + request.product = product + request.version = version + request.actionName = action + request.locationServiceCode = serviceCode + request.locationEndpointType = endpointType +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go new file mode 100644 index 000000000..28af63ea1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests/types.go @@ -0,0 +1,53 @@ +package requests + +import "strconv" + +type Integer string + +func NewInteger(integer int) Integer { + return Integer(strconv.Itoa(integer)) +} + +func (integer Integer) HasValue() bool { + return integer != "" +} + +func (integer Integer) GetValue() (int, error) { + return strconv.Atoi(string(integer)) +} + +func NewInteger64(integer int64) Integer { + return Integer(strconv.FormatInt(integer, 10)) +} + +func (integer Integer) GetValue64() (int64, error) { + return strconv.ParseInt(string(integer), 10, 0) +} + +type Boolean string + +func NewBoolean(bool bool) Boolean { + return Boolean(strconv.FormatBool(bool)) +} + +func (boolean Boolean) HasValue() bool { + return boolean != "" +} + +func (boolean Boolean) GetValue() (bool, error) { + return strconv.ParseBool(string(boolean)) +} + +type Float string + +func NewFloat(f float64) Float { + return Float(strconv.FormatFloat(f, 'f', 6, 64)) +} + +func (float Float) HasValue() bool { + return float != "" +} + +func (float Float) GetValue() (float64, error) { + return strconv.ParseFloat(string(float), 64) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go new file mode 100644 index 000000000..36604fe80 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/json_parser.go @@ -0,0 +1,328 @@ +package responses + +import ( + "encoding/json" + "io" + "math" + "strconv" + "strings" + "unsafe" + + jsoniter "github.com/json-iterator/go" +) + +const maxUint = ^uint(0) +const maxInt = int(maxUint >> 1) +const minInt = -maxInt - 1 + +var jsonParser jsoniter.API + +func init() { + registerBetterFuzzyDecoder() + jsonParser = jsoniter.Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, + CaseSensitive: true, + }.Froze() +} + +func registerBetterFuzzyDecoder() { + jsoniter.RegisterTypeDecoder("string", &nullableFuzzyStringDecoder{}) + jsoniter.RegisterTypeDecoder("bool", &fuzzyBoolDecoder{}) + jsoniter.RegisterTypeDecoder("float32", &nullableFuzzyFloat32Decoder{}) + jsoniter.RegisterTypeDecoder("float64", &nullableFuzzyFloat64Decoder{}) + jsoniter.RegisterTypeDecoder("int", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(maxInt) || val < float64(minInt) { + iter.ReportError("fuzzy decode int", "exceed range") + return + } + *((*int)(ptr)) = int(val) + } else { + *((*int)(ptr)) = iter.ReadInt() + } + }}) + jsoniter.RegisterTypeDecoder("uint", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(maxUint) || val < 0 { + iter.ReportError("fuzzy decode uint", "exceed range") + return + } + *((*uint)(ptr)) = uint(val) + } else { + *((*uint)(ptr)) = iter.ReadUint() + } + }}) + jsoniter.RegisterTypeDecoder("int8", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxInt8) || val < float64(math.MinInt8) { + iter.ReportError("fuzzy decode int8", "exceed range") + return + } + *((*int8)(ptr)) = int8(val) + } else { + *((*int8)(ptr)) = iter.ReadInt8() + } + }}) + jsoniter.RegisterTypeDecoder("uint8", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxUint8) || val < 0 { + iter.ReportError("fuzzy decode uint8", "exceed range") + return + } + *((*uint8)(ptr)) = uint8(val) + } else { + *((*uint8)(ptr)) = iter.ReadUint8() + } + }}) + jsoniter.RegisterTypeDecoder("int16", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxInt16) || val < float64(math.MinInt16) { + iter.ReportError("fuzzy decode int16", "exceed range") + return + } + *((*int16)(ptr)) = int16(val) + } else { + *((*int16)(ptr)) = iter.ReadInt16() + } + }}) + jsoniter.RegisterTypeDecoder("uint16", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxUint16) || val < 0 { + iter.ReportError("fuzzy decode uint16", "exceed range") + return + } + *((*uint16)(ptr)) = uint16(val) + } else { + *((*uint16)(ptr)) = iter.ReadUint16() + } + }}) + jsoniter.RegisterTypeDecoder("int32", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxInt32) || val < float64(math.MinInt32) { + iter.ReportError("fuzzy decode int32", "exceed range") + return + } + *((*int32)(ptr)) = int32(val) + } else { + *((*int32)(ptr)) = iter.ReadInt32() + } + }}) + jsoniter.RegisterTypeDecoder("uint32", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxUint32) || val < 0 { + iter.ReportError("fuzzy decode uint32", "exceed range") + return + } + *((*uint32)(ptr)) = uint32(val) + } else { + *((*uint32)(ptr)) = iter.ReadUint32() + } + }}) + jsoniter.RegisterTypeDecoder("int64", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxInt64) || val < float64(math.MinInt64) { + iter.ReportError("fuzzy decode int64", "exceed range") + return + } + *((*int64)(ptr)) = int64(val) + } else { + *((*int64)(ptr)) = iter.ReadInt64() + } + }}) + jsoniter.RegisterTypeDecoder("uint64", &nullableFuzzyIntegerDecoder{func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) { + if isFloat { + val := iter.ReadFloat64() + if val > float64(math.MaxUint64) || val < 0 { + iter.ReportError("fuzzy decode uint64", "exceed range") + return + } + *((*uint64)(ptr)) = uint64(val) + } else { + *((*uint64)(ptr)) = iter.ReadUint64() + } + }}) +} + +type nullableFuzzyStringDecoder struct { +} + +func (decoder *nullableFuzzyStringDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + switch valueType { + case jsoniter.NumberValue: + var number json.Number + iter.ReadVal(&number) + *((*string)(ptr)) = string(number) + case jsoniter.StringValue: + *((*string)(ptr)) = iter.ReadString() + case jsoniter.BoolValue: + *((*string)(ptr)) = strconv.FormatBool(iter.ReadBool()) + case jsoniter.NilValue: + iter.ReadNil() + *((*string)(ptr)) = "" + default: + iter.ReportError("fuzzyStringDecoder", "not number or string or bool") + } +} + +type fuzzyBoolDecoder struct { +} + +func (decoder *fuzzyBoolDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + switch valueType { + case jsoniter.BoolValue: + *((*bool)(ptr)) = iter.ReadBool() + case jsoniter.NumberValue: + var number json.Number + iter.ReadVal(&number) + num, err := number.Int64() + if err != nil { + iter.ReportError("fuzzyBoolDecoder", "get value from json.number failed") + } + if num == 0 { + *((*bool)(ptr)) = false + } else { + *((*bool)(ptr)) = true + } + case jsoniter.StringValue: + strValue := strings.ToLower(iter.ReadString()) + if strValue == "true" { + *((*bool)(ptr)) = true + } else if strValue == "false" || strValue == "" { + *((*bool)(ptr)) = false + } else { + iter.ReportError("fuzzyBoolDecoder", "unsupported bool value: "+strValue) + } + case jsoniter.NilValue: + iter.ReadNil() + *((*bool)(ptr)) = false + default: + iter.ReportError("fuzzyBoolDecoder", "not number or string or nil") + } +} + +type nullableFuzzyIntegerDecoder struct { + fun func(isFloat bool, ptr unsafe.Pointer, iter *jsoniter.Iterator) +} + +func (decoder *nullableFuzzyIntegerDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + var str string + switch valueType { + case jsoniter.NumberValue: + var number json.Number + iter.ReadVal(&number) + str = string(number) + case jsoniter.StringValue: + str = iter.ReadString() + // support empty string + if str == "" { + str = "0" + } + case jsoniter.BoolValue: + if iter.ReadBool() { + str = "1" + } else { + str = "0" + } + case jsoniter.NilValue: + iter.ReadNil() + str = "0" + default: + iter.ReportError("fuzzyIntegerDecoder", "not number or string") + } + newIter := iter.Pool().BorrowIterator([]byte(str)) + defer iter.Pool().ReturnIterator(newIter) + isFloat := strings.IndexByte(str, '.') != -1 + decoder.fun(isFloat, ptr, newIter) + if newIter.Error != nil && newIter.Error != io.EOF { + iter.Error = newIter.Error + } +} + +type nullableFuzzyFloat32Decoder struct { +} + +func (decoder *nullableFuzzyFloat32Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + var str string + switch valueType { + case jsoniter.NumberValue: + *((*float32)(ptr)) = iter.ReadFloat32() + case jsoniter.StringValue: + str = iter.ReadString() + // support empty string + if str == "" { + *((*float32)(ptr)) = 0 + return + } + newIter := iter.Pool().BorrowIterator([]byte(str)) + defer iter.Pool().ReturnIterator(newIter) + *((*float32)(ptr)) = newIter.ReadFloat32() + if newIter.Error != nil && newIter.Error != io.EOF { + iter.Error = newIter.Error + } + case jsoniter.BoolValue: + // support bool to float32 + if iter.ReadBool() { + *((*float32)(ptr)) = 1 + } else { + *((*float32)(ptr)) = 0 + } + case jsoniter.NilValue: + iter.ReadNil() + *((*float32)(ptr)) = 0 + default: + iter.ReportError("nullableFuzzyFloat32Decoder", "not number or string") + } +} + +type nullableFuzzyFloat64Decoder struct { +} + +func (decoder *nullableFuzzyFloat64Decoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) { + valueType := iter.WhatIsNext() + var str string + switch valueType { + case jsoniter.NumberValue: + *((*float64)(ptr)) = iter.ReadFloat64() + case jsoniter.StringValue: + str = iter.ReadString() + // support empty string + if str == "" { + *((*float64)(ptr)) = 0 + return + } + newIter := iter.Pool().BorrowIterator([]byte(str)) + defer iter.Pool().ReturnIterator(newIter) + *((*float64)(ptr)) = newIter.ReadFloat64() + if newIter.Error != nil && newIter.Error != io.EOF { + iter.Error = newIter.Error + } + case jsoniter.BoolValue: + // support bool to float64 + if iter.ReadBool() { + *((*float64)(ptr)) = 1 + } else { + *((*float64)(ptr)) = 0 + } + case jsoniter.NilValue: + // support empty string + iter.ReadNil() + *((*float64)(ptr)) = 0 + default: + iter.ReportError("nullableFuzzyFloat64Decoder", "not number or string") + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go new file mode 100644 index 000000000..53a156b71 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses/response.go @@ -0,0 +1,144 @@ +/* + * 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. + */ + +package responses + +import ( + "bytes" + "encoding/xml" + "fmt" + "io/ioutil" + "net/http" + "strings" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors" +) + +type AcsResponse interface { + IsSuccess() bool + GetHttpStatus() int + GetHttpHeaders() map[string][]string + GetHttpContentString() string + GetHttpContentBytes() []byte + GetOriginHttpResponse() *http.Response + parseFromHttpResponse(httpResponse *http.Response) error +} + +// Unmarshal object from http response body to target Response +func Unmarshal(response AcsResponse, httpResponse *http.Response, format string) (err error) { + err = response.parseFromHttpResponse(httpResponse) + if err != nil { + return + } + if !response.IsSuccess() { + err = errors.NewServerError(response.GetHttpStatus(), response.GetHttpContentString(), "") + return + } + + if _, isCommonResponse := response.(*CommonResponse); isCommonResponse { + // common response need not unmarshal + return + } + + if len(response.GetHttpContentBytes()) == 0 { + return + } + + if strings.ToUpper(format) == "JSON" { + err = jsonParser.Unmarshal(response.GetHttpContentBytes(), response) + if err != nil { + err = errors.NewClientError(errors.JsonUnmarshalErrorCode, errors.JsonUnmarshalErrorMessage, err) + } + } else if strings.ToUpper(format) == "XML" { + err = xml.Unmarshal(response.GetHttpContentBytes(), response) + } + return +} + +type BaseResponse struct { + httpStatus int + httpHeaders map[string][]string + httpContentString string + httpContentBytes []byte + originHttpResponse *http.Response +} + +func (baseResponse *BaseResponse) GetHttpStatus() int { + return baseResponse.httpStatus +} + +func (baseResponse *BaseResponse) GetHttpHeaders() map[string][]string { + return baseResponse.httpHeaders +} + +func (baseResponse *BaseResponse) GetHttpContentString() string { + return baseResponse.httpContentString +} + +func (baseResponse *BaseResponse) GetHttpContentBytes() []byte { + return baseResponse.httpContentBytes +} + +func (baseResponse *BaseResponse) GetOriginHttpResponse() *http.Response { + return baseResponse.originHttpResponse +} + +func (baseResponse *BaseResponse) IsSuccess() bool { + if baseResponse.GetHttpStatus() >= 200 && baseResponse.GetHttpStatus() < 300 { + return true + } + + return false +} + +func (baseResponse *BaseResponse) parseFromHttpResponse(httpResponse *http.Response) (err error) { + defer httpResponse.Body.Close() + body, err := ioutil.ReadAll(httpResponse.Body) + if err != nil { + return + } + baseResponse.httpStatus = httpResponse.StatusCode + baseResponse.httpHeaders = httpResponse.Header + baseResponse.httpContentBytes = body + baseResponse.httpContentString = string(body) + baseResponse.originHttpResponse = httpResponse + return +} + +func (baseResponse *BaseResponse) String() string { + resultBuilder := bytes.Buffer{} + // statusCode + // resultBuilder.WriteString("\n") + resultBuilder.WriteString(fmt.Sprintf("%s %s\n", baseResponse.originHttpResponse.Proto, baseResponse.originHttpResponse.Status)) + // httpHeaders + //resultBuilder.WriteString("Headers:\n") + for key, value := range baseResponse.httpHeaders { + resultBuilder.WriteString(key + ": " + strings.Join(value, ";") + "\n") + } + resultBuilder.WriteString("\n") + // content + //resultBuilder.WriteString("Content:\n") + resultBuilder.WriteString(baseResponse.httpContentString + "\n") + return resultBuilder.String() +} + +type CommonResponse struct { + *BaseResponse +} + +func NewCommonResponse() (response *CommonResponse) { + return &CommonResponse{ + BaseResponse: &BaseResponse{}, + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/debug.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/debug.go new file mode 100644 index 000000000..09440d27b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/debug.go @@ -0,0 +1,36 @@ +package utils + +import ( + "fmt" + "os" + "strings" +) + +type Debug func(format string, v ...interface{}) + +var hookGetEnv = func() string { + return os.Getenv("DEBUG") +} + +var hookPrint = func(input string) { + fmt.Println(input) +} + +func Init(flag string) Debug { + enable := false + + env := hookGetEnv() + parts := strings.Split(env, ",") + for _, part := range parts { + if part == flag { + enable = true + break + } + } + + return func(format string, v ...interface{}) { + if enable { + hookPrint(fmt.Sprintf(format, v...)) + } + } +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go new file mode 100644 index 000000000..f8a3ad384 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/sdk/utils/utils.go @@ -0,0 +1,141 @@ +/* + * 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. + */ + +package utils + +import ( + "crypto/md5" + "crypto/rand" + "encoding/base64" + "encoding/hex" + "hash" + rand2 "math/rand" + "net/url" + "reflect" + "strconv" + "time" +) + +type UUID [16]byte + +const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +func GetUUID() (uuidHex string) { + uuid := NewUUID() + uuidHex = hex.EncodeToString(uuid[:]) + return +} + +func RandStringBytes(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand2.Intn(len(letterBytes))] + } + return string(b) +} + +func GetMD5Base64(bytes []byte) (base64Value string) { + md5Ctx := md5.New() + md5Ctx.Write(bytes) + md5Value := md5Ctx.Sum(nil) + base64Value = base64.StdEncoding.EncodeToString(md5Value) + return +} + +func GetTimeInFormatISO8601() (timeStr string) { + gmt := time.FixedZone("GMT", 0) + + return time.Now().In(gmt).Format("2006-01-02T15:04:05Z") +} + +func GetTimeInFormatRFC2616() (timeStr string) { + gmt := time.FixedZone("GMT", 0) + + return time.Now().In(gmt).Format("Mon, 02 Jan 2006 15:04:05 GMT") +} + +func GetUrlFormedMap(source map[string]string) (urlEncoded string) { + urlEncoder := url.Values{} + for key, value := range source { + urlEncoder.Add(key, value) + } + urlEncoded = urlEncoder.Encode() + return +} + +func InitStructWithDefaultTag(bean interface{}) { + configType := reflect.TypeOf(bean) + for i := 0; i < configType.Elem().NumField(); i++ { + field := configType.Elem().Field(i) + defaultValue := field.Tag.Get("default") + if defaultValue == "" { + continue + } + setter := reflect.ValueOf(bean).Elem().Field(i) + switch field.Type.String() { + case "int": + intValue, _ := strconv.ParseInt(defaultValue, 10, 64) + setter.SetInt(intValue) + case "time.Duration": + intValue, _ := strconv.ParseInt(defaultValue, 10, 64) + setter.SetInt(intValue) + case "string": + setter.SetString(defaultValue) + case "bool": + boolValue, _ := strconv.ParseBool(defaultValue) + setter.SetBool(boolValue) + } + } +} + +func NewUUID() UUID { + ns := UUID{} + safeRandom(ns[:]) + u := newFromHash(md5.New(), ns, RandStringBytes(16)) + u[6] = (u[6] & 0x0f) | (byte(2) << 4) + u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) + + return u +} + +func newFromHash(h hash.Hash, ns UUID, name string) UUID { + u := UUID{} + h.Write(ns[:]) + h.Write([]byte(name)) + copy(u[:], h.Sum(nil)) + + return u +} + +func safeRandom(dest []byte) { + if _, err := rand.Read(dest); err != nil { + panic(err) + } +} + +func (u UUID) String() string { + buf := make([]byte, 36) + + hex.Encode(buf[0:8], u[0:4]) + buf[8] = '-' + hex.Encode(buf[9:13], u[4:6]) + buf[13] = '-' + hex.Encode(buf[14:18], u[6:8]) + buf[18] = '-' + hex.Encode(buf[19:23], u[8:10]) + buf[23] = '-' + hex.Encode(buf[24:], u[10:]) + + return string(buf) +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain.go new file mode 100644 index 000000000..4e535c3ed --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain.go @@ -0,0 +1,113 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// AddDomain invokes the alidns.AddDomain API synchronously +// api document: https://help.aliyun.com/api/alidns/adddomain.html +func (client *Client) AddDomain(request *AddDomainRequest) (response *AddDomainResponse, err error) { + response = CreateAddDomainResponse() + err = client.DoAction(request, response) + return +} + +// AddDomainWithChan invokes the alidns.AddDomain API asynchronously +// api document: https://help.aliyun.com/api/alidns/adddomain.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddDomainWithChan(request *AddDomainRequest) (<-chan *AddDomainResponse, <-chan error) { + responseChan := make(chan *AddDomainResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.AddDomain(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// AddDomainWithCallback invokes the alidns.AddDomain API asynchronously +// api document: https://help.aliyun.com/api/alidns/adddomain.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddDomainWithCallback(request *AddDomainRequest, callback func(response *AddDomainResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *AddDomainResponse + var err error + defer close(result) + response, err = client.AddDomain(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// AddDomainRequest is the request struct for api AddDomain +type AddDomainRequest struct { + *requests.RpcRequest + ResourceGroupId string `position:"Query" name:"ResourceGroupId"` + GroupId string `position:"Query" name:"GroupId"` + DomainName string `position:"Query" name:"DomainName"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// AddDomainResponse is the response struct for api AddDomain +type AddDomainResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + DomainId string `json:"DomainId" xml:"DomainId"` + DomainName string `json:"DomainName" xml:"DomainName"` + PunyCode string `json:"PunyCode" xml:"PunyCode"` + GroupId string `json:"GroupId" xml:"GroupId"` + GroupName string `json:"GroupName" xml:"GroupName"` + DnsServers DnsServersInAddDomain `json:"DnsServers" xml:"DnsServers"` +} + +// CreateAddDomainRequest creates a request to invoke AddDomain API +func CreateAddDomainRequest() (request *AddDomainRequest) { + request = &AddDomainRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "AddDomain", "Alidns", "openAPI") + return +} + +// CreateAddDomainResponse creates a response to parse from AddDomain response +func CreateAddDomainResponse() (response *AddDomainResponse) { + response = &AddDomainResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain_group.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain_group.go new file mode 100644 index 000000000..e977e0436 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain_group.go @@ -0,0 +1,107 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// AddDomainGroup invokes the alidns.AddDomainGroup API synchronously +// api document: https://help.aliyun.com/api/alidns/adddomaingroup.html +func (client *Client) AddDomainGroup(request *AddDomainGroupRequest) (response *AddDomainGroupResponse, err error) { + response = CreateAddDomainGroupResponse() + err = client.DoAction(request, response) + return +} + +// AddDomainGroupWithChan invokes the alidns.AddDomainGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/adddomaingroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddDomainGroupWithChan(request *AddDomainGroupRequest) (<-chan *AddDomainGroupResponse, <-chan error) { + responseChan := make(chan *AddDomainGroupResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.AddDomainGroup(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// AddDomainGroupWithCallback invokes the alidns.AddDomainGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/adddomaingroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddDomainGroupWithCallback(request *AddDomainGroupRequest, callback func(response *AddDomainGroupResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *AddDomainGroupResponse + var err error + defer close(result) + response, err = client.AddDomainGroup(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// AddDomainGroupRequest is the request struct for api AddDomainGroup +type AddDomainGroupRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` + GroupName string `position:"Query" name:"GroupName"` +} + +// AddDomainGroupResponse is the response struct for api AddDomainGroup +type AddDomainGroupResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + GroupId string `json:"GroupId" xml:"GroupId"` + GroupName string `json:"GroupName" xml:"GroupName"` +} + +// CreateAddDomainGroupRequest creates a request to invoke AddDomainGroup API +func CreateAddDomainGroupRequest() (request *AddDomainGroupRequest) { + request = &AddDomainGroupRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "AddDomainGroup", "Alidns", "openAPI") + return +} + +// CreateAddDomainGroupResponse creates a response to parse from AddDomainGroup response +func CreateAddDomainGroupResponse() (response *AddDomainGroupResponse) { + response = &AddDomainGroupResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain_record.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain_record.go new file mode 100644 index 000000000..5346079f3 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_domain_record.go @@ -0,0 +1,112 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// AddDomainRecord invokes the alidns.AddDomainRecord API synchronously +// api document: https://help.aliyun.com/api/alidns/adddomainrecord.html +func (client *Client) AddDomainRecord(request *AddDomainRecordRequest) (response *AddDomainRecordResponse, err error) { + response = CreateAddDomainRecordResponse() + err = client.DoAction(request, response) + return +} + +// AddDomainRecordWithChan invokes the alidns.AddDomainRecord API asynchronously +// api document: https://help.aliyun.com/api/alidns/adddomainrecord.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddDomainRecordWithChan(request *AddDomainRecordRequest) (<-chan *AddDomainRecordResponse, <-chan error) { + responseChan := make(chan *AddDomainRecordResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.AddDomainRecord(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// AddDomainRecordWithCallback invokes the alidns.AddDomainRecord API asynchronously +// api document: https://help.aliyun.com/api/alidns/adddomainrecord.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddDomainRecordWithCallback(request *AddDomainRecordRequest, callback func(response *AddDomainRecordResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *AddDomainRecordResponse + var err error + defer close(result) + response, err = client.AddDomainRecord(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// AddDomainRecordRequest is the request struct for api AddDomainRecord +type AddDomainRecordRequest struct { + *requests.RpcRequest + RR string `position:"Query" name:"RR"` + Line string `position:"Query" name:"Line"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + Type string `position:"Query" name:"Type"` + Priority requests.Integer `position:"Query" name:"Priority"` + Value string `position:"Query" name:"Value"` + TTL requests.Integer `position:"Query" name:"TTL"` +} + +// AddDomainRecordResponse is the response struct for api AddDomainRecord +type AddDomainRecordResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + RecordId string `json:"RecordId" xml:"RecordId"` +} + +// CreateAddDomainRecordRequest creates a request to invoke AddDomainRecord API +func CreateAddDomainRecordRequest() (request *AddDomainRecordRequest) { + request = &AddDomainRecordRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "AddDomainRecord", "Alidns", "openAPI") + return +} + +// CreateAddDomainRecordResponse creates a response to parse from AddDomainRecord response +func CreateAddDomainRecordResponse() (response *AddDomainRecordResponse) { + response = &AddDomainRecordResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_access_strategy.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_access_strategy.go new file mode 100644 index 000000000..37d9d0d44 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_access_strategy.go @@ -0,0 +1,110 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// AddGtmAccessStrategy invokes the alidns.AddGtmAccessStrategy API synchronously +// api document: https://help.aliyun.com/api/alidns/addgtmaccessstrategy.html +func (client *Client) AddGtmAccessStrategy(request *AddGtmAccessStrategyRequest) (response *AddGtmAccessStrategyResponse, err error) { + response = CreateAddGtmAccessStrategyResponse() + err = client.DoAction(request, response) + return +} + +// AddGtmAccessStrategyWithChan invokes the alidns.AddGtmAccessStrategy API asynchronously +// api document: https://help.aliyun.com/api/alidns/addgtmaccessstrategy.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddGtmAccessStrategyWithChan(request *AddGtmAccessStrategyRequest) (<-chan *AddGtmAccessStrategyResponse, <-chan error) { + responseChan := make(chan *AddGtmAccessStrategyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.AddGtmAccessStrategy(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// AddGtmAccessStrategyWithCallback invokes the alidns.AddGtmAccessStrategy API asynchronously +// api document: https://help.aliyun.com/api/alidns/addgtmaccessstrategy.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddGtmAccessStrategyWithCallback(request *AddGtmAccessStrategyRequest, callback func(response *AddGtmAccessStrategyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *AddGtmAccessStrategyResponse + var err error + defer close(result) + response, err = client.AddGtmAccessStrategy(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// AddGtmAccessStrategyRequest is the request struct for api AddGtmAccessStrategy +type AddGtmAccessStrategyRequest struct { + *requests.RpcRequest + StrategyName string `position:"Query" name:"StrategyName"` + DefaultAddrPoolId string `position:"Query" name:"DefaultAddrPoolId"` + AccessLines string `position:"Query" name:"AccessLines"` + InstanceId string `position:"Query" name:"InstanceId"` + FailoverAddrPoolId string `position:"Query" name:"FailoverAddrPoolId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// AddGtmAccessStrategyResponse is the response struct for api AddGtmAccessStrategy +type AddGtmAccessStrategyResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + StrategyId string `json:"StrategyId" xml:"StrategyId"` +} + +// CreateAddGtmAccessStrategyRequest creates a request to invoke AddGtmAccessStrategy API +func CreateAddGtmAccessStrategyRequest() (request *AddGtmAccessStrategyRequest) { + request = &AddGtmAccessStrategyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "AddGtmAccessStrategy", "Alidns", "openAPI") + return +} + +// CreateAddGtmAccessStrategyResponse creates a response to parse from AddGtmAccessStrategy response +func CreateAddGtmAccessStrategyResponse() (response *AddGtmAccessStrategyResponse) { + response = &AddGtmAccessStrategyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_address_pool.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_address_pool.go new file mode 100644 index 000000000..5856bd626 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_address_pool.go @@ -0,0 +1,117 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// AddGtmAddressPool invokes the alidns.AddGtmAddressPool API synchronously +// api document: https://help.aliyun.com/api/alidns/addgtmaddresspool.html +func (client *Client) AddGtmAddressPool(request *AddGtmAddressPoolRequest) (response *AddGtmAddressPoolResponse, err error) { + response = CreateAddGtmAddressPoolResponse() + err = client.DoAction(request, response) + return +} + +// AddGtmAddressPoolWithChan invokes the alidns.AddGtmAddressPool API asynchronously +// api document: https://help.aliyun.com/api/alidns/addgtmaddresspool.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddGtmAddressPoolWithChan(request *AddGtmAddressPoolRequest) (<-chan *AddGtmAddressPoolResponse, <-chan error) { + responseChan := make(chan *AddGtmAddressPoolResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.AddGtmAddressPool(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// AddGtmAddressPoolWithCallback invokes the alidns.AddGtmAddressPool API asynchronously +// api document: https://help.aliyun.com/api/alidns/addgtmaddresspool.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddGtmAddressPoolWithCallback(request *AddGtmAddressPoolRequest, callback func(response *AddGtmAddressPoolResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *AddGtmAddressPoolResponse + var err error + defer close(result) + response, err = client.AddGtmAddressPool(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// AddGtmAddressPoolRequest is the request struct for api AddGtmAddressPool +type AddGtmAddressPoolRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Name string `position:"Query" name:"Name"` + Lang string `position:"Query" name:"Lang"` + Type string `position:"Query" name:"Type"` + Addr *[]AddGtmAddressPoolAddr `position:"Query" name:"Addr" type:"Repeated"` + MinAvailableAddrNum requests.Integer `position:"Query" name:"MinAvailableAddrNum"` +} + +// AddGtmAddressPoolAddr is a repeated param struct in AddGtmAddressPoolRequest +type AddGtmAddressPoolAddr struct { + Mode string `name:"Mode"` + LbaWeight string `name:"LbaWeight"` + Value string `name:"Value"` +} + +// AddGtmAddressPoolResponse is the response struct for api AddGtmAddressPool +type AddGtmAddressPoolResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + AddrPoolId string `json:"AddrPoolId" xml:"AddrPoolId"` +} + +// CreateAddGtmAddressPoolRequest creates a request to invoke AddGtmAddressPool API +func CreateAddGtmAddressPoolRequest() (request *AddGtmAddressPoolRequest) { + request = &AddGtmAddressPoolRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "AddGtmAddressPool", "Alidns", "openAPI") + return +} + +// CreateAddGtmAddressPoolResponse creates a response to parse from AddGtmAddressPool response +func CreateAddGtmAddressPoolResponse() (response *AddGtmAddressPoolResponse) { + response = &AddGtmAddressPoolResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_monitor.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_monitor.go new file mode 100644 index 000000000..259787062 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/add_gtm_monitor.go @@ -0,0 +1,119 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// AddGtmMonitor invokes the alidns.AddGtmMonitor API synchronously +// api document: https://help.aliyun.com/api/alidns/addgtmmonitor.html +func (client *Client) AddGtmMonitor(request *AddGtmMonitorRequest) (response *AddGtmMonitorResponse, err error) { + response = CreateAddGtmMonitorResponse() + err = client.DoAction(request, response) + return +} + +// AddGtmMonitorWithChan invokes the alidns.AddGtmMonitor API asynchronously +// api document: https://help.aliyun.com/api/alidns/addgtmmonitor.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddGtmMonitorWithChan(request *AddGtmMonitorRequest) (<-chan *AddGtmMonitorResponse, <-chan error) { + responseChan := make(chan *AddGtmMonitorResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.AddGtmMonitor(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// AddGtmMonitorWithCallback invokes the alidns.AddGtmMonitor API asynchronously +// api document: https://help.aliyun.com/api/alidns/addgtmmonitor.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) AddGtmMonitorWithCallback(request *AddGtmMonitorRequest, callback func(response *AddGtmMonitorResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *AddGtmMonitorResponse + var err error + defer close(result) + response, err = client.AddGtmMonitor(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// AddGtmMonitorRequest is the request struct for api AddGtmMonitor +type AddGtmMonitorRequest struct { + *requests.RpcRequest + MonitorExtendInfo string `position:"Query" name:"MonitorExtendInfo"` + AddrPoolId string `position:"Query" name:"AddrPoolId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Name string `position:"Query" name:"Name"` + EvaluationCount requests.Integer `position:"Query" name:"EvaluationCount"` + ProtocolType string `position:"Query" name:"ProtocolType"` + Interval requests.Integer `position:"Query" name:"Interval"` + Lang string `position:"Query" name:"Lang"` + Timeout requests.Integer `position:"Query" name:"Timeout"` + IspCityNode *[]AddGtmMonitorIspCityNode `position:"Query" name:"IspCityNode" type:"Repeated"` +} + +// AddGtmMonitorIspCityNode is a repeated param struct in AddGtmMonitorRequest +type AddGtmMonitorIspCityNode struct { + CityCode string `name:"CityCode"` + IspCode string `name:"IspCode"` +} + +// AddGtmMonitorResponse is the response struct for api AddGtmMonitor +type AddGtmMonitorResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + MonitorConfigId string `json:"MonitorConfigId" xml:"MonitorConfigId"` +} + +// CreateAddGtmMonitorRequest creates a request to invoke AddGtmMonitor API +func CreateAddGtmMonitorRequest() (request *AddGtmMonitorRequest) { + request = &AddGtmMonitorRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "AddGtmMonitor", "Alidns", "openAPI") + return +} + +// CreateAddGtmMonitorResponse creates a response to parse from AddGtmMonitor response +func CreateAddGtmMonitorResponse() (response *AddGtmMonitorResponse) { + response = &AddGtmMonitorResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/change_domain_group.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/change_domain_group.go new file mode 100644 index 000000000..ae9aa3d2e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/change_domain_group.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ChangeDomainGroup invokes the alidns.ChangeDomainGroup API synchronously +// api document: https://help.aliyun.com/api/alidns/changedomaingroup.html +func (client *Client) ChangeDomainGroup(request *ChangeDomainGroupRequest) (response *ChangeDomainGroupResponse, err error) { + response = CreateChangeDomainGroupResponse() + err = client.DoAction(request, response) + return +} + +// ChangeDomainGroupWithChan invokes the alidns.ChangeDomainGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/changedomaingroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ChangeDomainGroupWithChan(request *ChangeDomainGroupRequest) (<-chan *ChangeDomainGroupResponse, <-chan error) { + responseChan := make(chan *ChangeDomainGroupResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ChangeDomainGroup(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ChangeDomainGroupWithCallback invokes the alidns.ChangeDomainGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/changedomaingroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ChangeDomainGroupWithCallback(request *ChangeDomainGroupRequest, callback func(response *ChangeDomainGroupResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ChangeDomainGroupResponse + var err error + defer close(result) + response, err = client.ChangeDomainGroup(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ChangeDomainGroupRequest is the request struct for api ChangeDomainGroup +type ChangeDomainGroupRequest struct { + *requests.RpcRequest + GroupId string `position:"Query" name:"GroupId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` +} + +// ChangeDomainGroupResponse is the response struct for api ChangeDomainGroup +type ChangeDomainGroupResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + GroupId string `json:"GroupId" xml:"GroupId"` + GroupName string `json:"GroupName" xml:"GroupName"` +} + +// CreateChangeDomainGroupRequest creates a request to invoke ChangeDomainGroup API +func CreateChangeDomainGroupRequest() (request *ChangeDomainGroupRequest) { + request = &ChangeDomainGroupRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "ChangeDomainGroup", "Alidns", "openAPI") + return +} + +// CreateChangeDomainGroupResponse creates a response to parse from ChangeDomainGroup response +func CreateChangeDomainGroupResponse() (response *ChangeDomainGroupResponse) { + response = &ChangeDomainGroupResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/change_domain_of_dns_product.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/change_domain_of_dns_product.go new file mode 100644 index 000000000..9098327ce --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/change_domain_of_dns_product.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ChangeDomainOfDnsProduct invokes the alidns.ChangeDomainOfDnsProduct API synchronously +// api document: https://help.aliyun.com/api/alidns/changedomainofdnsproduct.html +func (client *Client) ChangeDomainOfDnsProduct(request *ChangeDomainOfDnsProductRequest) (response *ChangeDomainOfDnsProductResponse, err error) { + response = CreateChangeDomainOfDnsProductResponse() + err = client.DoAction(request, response) + return +} + +// ChangeDomainOfDnsProductWithChan invokes the alidns.ChangeDomainOfDnsProduct API asynchronously +// api document: https://help.aliyun.com/api/alidns/changedomainofdnsproduct.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ChangeDomainOfDnsProductWithChan(request *ChangeDomainOfDnsProductRequest) (<-chan *ChangeDomainOfDnsProductResponse, <-chan error) { + responseChan := make(chan *ChangeDomainOfDnsProductResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ChangeDomainOfDnsProduct(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ChangeDomainOfDnsProductWithCallback invokes the alidns.ChangeDomainOfDnsProduct API asynchronously +// api document: https://help.aliyun.com/api/alidns/changedomainofdnsproduct.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ChangeDomainOfDnsProductWithCallback(request *ChangeDomainOfDnsProductRequest, callback func(response *ChangeDomainOfDnsProductResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ChangeDomainOfDnsProductResponse + var err error + defer close(result) + response, err = client.ChangeDomainOfDnsProduct(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ChangeDomainOfDnsProductRequest is the request struct for api ChangeDomainOfDnsProduct +type ChangeDomainOfDnsProductRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + NewDomain string `position:"Query" name:"NewDomain"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Force requests.Boolean `position:"Query" name:"Force"` + Lang string `position:"Query" name:"Lang"` +} + +// ChangeDomainOfDnsProductResponse is the response struct for api ChangeDomainOfDnsProduct +type ChangeDomainOfDnsProductResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + OriginalDomain string `json:"OriginalDomain" xml:"OriginalDomain"` +} + +// CreateChangeDomainOfDnsProductRequest creates a request to invoke ChangeDomainOfDnsProduct API +func CreateChangeDomainOfDnsProductRequest() (request *ChangeDomainOfDnsProductRequest) { + request = &ChangeDomainOfDnsProductRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "ChangeDomainOfDnsProduct", "Alidns", "openAPI") + return +} + +// CreateChangeDomainOfDnsProductResponse creates a response to parse from ChangeDomainOfDnsProduct response +func CreateChangeDomainOfDnsProductResponse() (response *ChangeDomainOfDnsProductResponse) { + response = &ChangeDomainOfDnsProductResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/check_domain_record.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/check_domain_record.go new file mode 100644 index 000000000..898af6d7e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/check_domain_record.go @@ -0,0 +1,109 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// CheckDomainRecord invokes the alidns.CheckDomainRecord API synchronously +// api document: https://help.aliyun.com/api/alidns/checkdomainrecord.html +func (client *Client) CheckDomainRecord(request *CheckDomainRecordRequest) (response *CheckDomainRecordResponse, err error) { + response = CreateCheckDomainRecordResponse() + err = client.DoAction(request, response) + return +} + +// CheckDomainRecordWithChan invokes the alidns.CheckDomainRecord API asynchronously +// api document: https://help.aliyun.com/api/alidns/checkdomainrecord.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CheckDomainRecordWithChan(request *CheckDomainRecordRequest) (<-chan *CheckDomainRecordResponse, <-chan error) { + responseChan := make(chan *CheckDomainRecordResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.CheckDomainRecord(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// CheckDomainRecordWithCallback invokes the alidns.CheckDomainRecord API asynchronously +// api document: https://help.aliyun.com/api/alidns/checkdomainrecord.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CheckDomainRecordWithCallback(request *CheckDomainRecordRequest, callback func(response *CheckDomainRecordResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *CheckDomainRecordResponse + var err error + defer close(result) + response, err = client.CheckDomainRecord(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// CheckDomainRecordRequest is the request struct for api CheckDomainRecord +type CheckDomainRecordRequest struct { + *requests.RpcRequest + RR string `position:"Query" name:"RR"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + Type string `position:"Query" name:"Type"` + Value string `position:"Query" name:"Value"` +} + +// CheckDomainRecordResponse is the response struct for api CheckDomainRecord +type CheckDomainRecordResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + IsExist bool `json:"IsExist" xml:"IsExist"` +} + +// CreateCheckDomainRecordRequest creates a request to invoke CheckDomainRecord API +func CreateCheckDomainRecordRequest() (request *CheckDomainRecordRequest) { + request = &CheckDomainRecordRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "CheckDomainRecord", "Alidns", "openAPI") + return +} + +// CreateCheckDomainRecordResponse creates a response to parse from CheckDomainRecord response +func CreateCheckDomainRecordResponse() (response *CheckDomainRecordResponse) { + response = &CheckDomainRecordResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/client.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/client.go new file mode 100644 index 000000000..e3fe04992 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/client.go @@ -0,0 +1,104 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/provider" +) + +// Client is the sdk client struct, each func corresponds to an OpenAPI +type Client struct { + sdk.Client +} + +// NewClient creates a sdk client with environment variables +func NewClient() (client *Client, err error) { + client = &Client{} + err = client.Init() + return +} + +// NewClientWithProvider creates a sdk client with providers +// usage: https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md +func NewClientWithProvider(regionId string, providers ...provider.Provider) (client *Client, err error) { + client = &Client{} + var pc provider.Provider + if len(providers) == 0 { + pc = provider.DefaultChain + } else { + pc = provider.NewProviderChain(providers) + } + err = client.InitWithProviderChain(regionId, pc) + return +} + +// NewClientWithOptions creates a sdk client with regionId/sdkConfig/credential +// this is the common api to create a sdk client +func NewClientWithOptions(regionId string, config *sdk.Config, credential auth.Credential) (client *Client, err error) { + client = &Client{} + err = client.InitWithOptions(regionId, config, credential) + return +} + +// NewClientWithAccessKey is a shortcut to create sdk client with accesskey +// usage: https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md +func NewClientWithAccessKey(regionId, accessKeyId, accessKeySecret string) (client *Client, err error) { + client = &Client{} + err = client.InitWithAccessKey(regionId, accessKeyId, accessKeySecret) + return +} + +// NewClientWithStsToken is a shortcut to create sdk client with sts token +// usage: https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md +func NewClientWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken string) (client *Client, err error) { + client = &Client{} + err = client.InitWithStsToken(regionId, stsAccessKeyId, stsAccessKeySecret, stsToken) + return +} + +// NewClientWithRamRoleArn is a shortcut to create sdk client with ram roleArn +// usage: https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md +func NewClientWithRamRoleArn(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName string) (client *Client, err error) { + client = &Client{} + err = client.InitWithRamRoleArn(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName) + return +} + +// NewClientWithRamRoleArn is a shortcut to create sdk client with ram roleArn and policy +// usage: https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md +func NewClientWithRamRoleArnAndPolicy(regionId string, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy string) (client *Client, err error) { + client = &Client{} + err = client.InitWithRamRoleArnAndPolicy(regionId, accessKeyId, accessKeySecret, roleArn, roleSessionName, policy) + return +} + +// NewClientWithEcsRamRole is a shortcut to create sdk client with ecs ram role +// usage: https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md +func NewClientWithEcsRamRole(regionId string, roleName string) (client *Client, err error) { + client = &Client{} + err = client.InitWithEcsRamRole(regionId, roleName) + return +} + +// NewClientWithRsaKeyPair is a shortcut to create sdk client with rsa key pair +// usage: https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/docs/2-Client-EN.md +func NewClientWithRsaKeyPair(regionId string, publicKeyId, privateKey string, sessionExpiration int) (client *Client, err error) { + client = &Client{} + err = client.InitWithRsaKeyPair(regionId, publicKeyId, privateKey, sessionExpiration) + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/create_instance.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/create_instance.go new file mode 100644 index 000000000..c90b6bb83 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/create_instance.go @@ -0,0 +1,111 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// CreateInstance invokes the alidns.CreateInstance API synchronously +// api document: https://help.aliyun.com/api/alidns/createinstance.html +func (client *Client) CreateInstance(request *CreateInstanceRequest) (response *CreateInstanceResponse, err error) { + response = CreateCreateInstanceResponse() + err = client.DoAction(request, response) + return +} + +// CreateInstanceWithChan invokes the alidns.CreateInstance API asynchronously +// api document: https://help.aliyun.com/api/alidns/createinstance.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CreateInstanceWithChan(request *CreateInstanceRequest) (<-chan *CreateInstanceResponse, <-chan error) { + responseChan := make(chan *CreateInstanceResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.CreateInstance(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// CreateInstanceWithCallback invokes the alidns.CreateInstance API asynchronously +// api document: https://help.aliyun.com/api/alidns/createinstance.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) CreateInstanceWithCallback(request *CreateInstanceRequest, callback func(response *CreateInstanceResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *CreateInstanceResponse + var err error + defer close(result) + response, err = client.CreateInstance(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// CreateInstanceRequest is the request struct for api CreateInstance +type CreateInstanceRequest struct { + *requests.RpcRequest + Month requests.Integer `position:"Query" name:"Month"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + InstanceVersion string `position:"Query" name:"InstanceVersion"` + OwnerId requests.Integer `position:"Query" name:"OwnerId"` + Token string `position:"Query" name:"Token"` +} + +// CreateInstanceResponse is the response struct for api CreateInstance +type CreateInstanceResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + OrderId string `json:"OrderId" xml:"OrderId"` + InstanceId string `json:"InstanceId" xml:"InstanceId"` +} + +// CreateCreateInstanceRequest creates a request to invoke CreateInstance API +func CreateCreateInstanceRequest() (request *CreateInstanceRequest) { + request = &CreateInstanceRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "CreateInstance", "Alidns", "openAPI") + return +} + +// CreateCreateInstanceResponse creates a response to parse from CreateInstance response +func CreateCreateInstanceResponse() (response *CreateInstanceResponse) { + response = &CreateInstanceResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain.go new file mode 100644 index 000000000..67d471525 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain.go @@ -0,0 +1,106 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DeleteDomain invokes the alidns.DeleteDomain API synchronously +// api document: https://help.aliyun.com/api/alidns/deletedomain.html +func (client *Client) DeleteDomain(request *DeleteDomainRequest) (response *DeleteDomainResponse, err error) { + response = CreateDeleteDomainResponse() + err = client.DoAction(request, response) + return +} + +// DeleteDomainWithChan invokes the alidns.DeleteDomain API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletedomain.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteDomainWithChan(request *DeleteDomainRequest) (<-chan *DeleteDomainResponse, <-chan error) { + responseChan := make(chan *DeleteDomainResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DeleteDomain(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DeleteDomainWithCallback invokes the alidns.DeleteDomain API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletedomain.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteDomainWithCallback(request *DeleteDomainRequest, callback func(response *DeleteDomainResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DeleteDomainResponse + var err error + defer close(result) + response, err = client.DeleteDomain(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DeleteDomainRequest is the request struct for api DeleteDomain +type DeleteDomainRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` +} + +// DeleteDomainResponse is the response struct for api DeleteDomain +type DeleteDomainResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + DomainName string `json:"DomainName" xml:"DomainName"` +} + +// CreateDeleteDomainRequest creates a request to invoke DeleteDomain API +func CreateDeleteDomainRequest() (request *DeleteDomainRequest) { + request = &DeleteDomainRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DeleteDomain", "Alidns", "openAPI") + return +} + +// CreateDeleteDomainResponse creates a response to parse from DeleteDomain response +func CreateDeleteDomainResponse() (response *DeleteDomainResponse) { + response = &DeleteDomainResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain_group.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain_group.go new file mode 100644 index 000000000..d3395e6c6 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain_group.go @@ -0,0 +1,106 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DeleteDomainGroup invokes the alidns.DeleteDomainGroup API synchronously +// api document: https://help.aliyun.com/api/alidns/deletedomaingroup.html +func (client *Client) DeleteDomainGroup(request *DeleteDomainGroupRequest) (response *DeleteDomainGroupResponse, err error) { + response = CreateDeleteDomainGroupResponse() + err = client.DoAction(request, response) + return +} + +// DeleteDomainGroupWithChan invokes the alidns.DeleteDomainGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletedomaingroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteDomainGroupWithChan(request *DeleteDomainGroupRequest) (<-chan *DeleteDomainGroupResponse, <-chan error) { + responseChan := make(chan *DeleteDomainGroupResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DeleteDomainGroup(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DeleteDomainGroupWithCallback invokes the alidns.DeleteDomainGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletedomaingroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteDomainGroupWithCallback(request *DeleteDomainGroupRequest, callback func(response *DeleteDomainGroupResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DeleteDomainGroupResponse + var err error + defer close(result) + response, err = client.DeleteDomainGroup(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DeleteDomainGroupRequest is the request struct for api DeleteDomainGroup +type DeleteDomainGroupRequest struct { + *requests.RpcRequest + GroupId string `position:"Query" name:"GroupId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DeleteDomainGroupResponse is the response struct for api DeleteDomainGroup +type DeleteDomainGroupResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + GroupName string `json:"GroupName" xml:"GroupName"` +} + +// CreateDeleteDomainGroupRequest creates a request to invoke DeleteDomainGroup API +func CreateDeleteDomainGroupRequest() (request *DeleteDomainGroupRequest) { + request = &DeleteDomainGroupRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DeleteDomainGroup", "Alidns", "openAPI") + return +} + +// CreateDeleteDomainGroupResponse creates a response to parse from DeleteDomainGroup response +func CreateDeleteDomainGroupResponse() (response *DeleteDomainGroupResponse) { + response = &DeleteDomainGroupResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain_record.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain_record.go new file mode 100644 index 000000000..cd97d6503 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_domain_record.go @@ -0,0 +1,106 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DeleteDomainRecord invokes the alidns.DeleteDomainRecord API synchronously +// api document: https://help.aliyun.com/api/alidns/deletedomainrecord.html +func (client *Client) DeleteDomainRecord(request *DeleteDomainRecordRequest) (response *DeleteDomainRecordResponse, err error) { + response = CreateDeleteDomainRecordResponse() + err = client.DoAction(request, response) + return +} + +// DeleteDomainRecordWithChan invokes the alidns.DeleteDomainRecord API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletedomainrecord.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteDomainRecordWithChan(request *DeleteDomainRecordRequest) (<-chan *DeleteDomainRecordResponse, <-chan error) { + responseChan := make(chan *DeleteDomainRecordResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DeleteDomainRecord(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DeleteDomainRecordWithCallback invokes the alidns.DeleteDomainRecord API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletedomainrecord.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteDomainRecordWithCallback(request *DeleteDomainRecordRequest, callback func(response *DeleteDomainRecordResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DeleteDomainRecordResponse + var err error + defer close(result) + response, err = client.DeleteDomainRecord(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DeleteDomainRecordRequest is the request struct for api DeleteDomainRecord +type DeleteDomainRecordRequest struct { + *requests.RpcRequest + RecordId string `position:"Query" name:"RecordId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DeleteDomainRecordResponse is the response struct for api DeleteDomainRecord +type DeleteDomainRecordResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + RecordId string `json:"RecordId" xml:"RecordId"` +} + +// CreateDeleteDomainRecordRequest creates a request to invoke DeleteDomainRecord API +func CreateDeleteDomainRecordRequest() (request *DeleteDomainRecordRequest) { + request = &DeleteDomainRecordRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DeleteDomainRecord", "Alidns", "openAPI") + return +} + +// CreateDeleteDomainRecordResponse creates a response to parse from DeleteDomainRecord response +func CreateDeleteDomainRecordResponse() (response *DeleteDomainRecordResponse) { + response = &DeleteDomainRecordResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_gtm_access_strategy.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_gtm_access_strategy.go new file mode 100644 index 000000000..69cc60493 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_gtm_access_strategy.go @@ -0,0 +1,105 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DeleteGtmAccessStrategy invokes the alidns.DeleteGtmAccessStrategy API synchronously +// api document: https://help.aliyun.com/api/alidns/deletegtmaccessstrategy.html +func (client *Client) DeleteGtmAccessStrategy(request *DeleteGtmAccessStrategyRequest) (response *DeleteGtmAccessStrategyResponse, err error) { + response = CreateDeleteGtmAccessStrategyResponse() + err = client.DoAction(request, response) + return +} + +// DeleteGtmAccessStrategyWithChan invokes the alidns.DeleteGtmAccessStrategy API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletegtmaccessstrategy.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteGtmAccessStrategyWithChan(request *DeleteGtmAccessStrategyRequest) (<-chan *DeleteGtmAccessStrategyResponse, <-chan error) { + responseChan := make(chan *DeleteGtmAccessStrategyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DeleteGtmAccessStrategy(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DeleteGtmAccessStrategyWithCallback invokes the alidns.DeleteGtmAccessStrategy API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletegtmaccessstrategy.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteGtmAccessStrategyWithCallback(request *DeleteGtmAccessStrategyRequest, callback func(response *DeleteGtmAccessStrategyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DeleteGtmAccessStrategyResponse + var err error + defer close(result) + response, err = client.DeleteGtmAccessStrategy(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DeleteGtmAccessStrategyRequest is the request struct for api DeleteGtmAccessStrategy +type DeleteGtmAccessStrategyRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + StrategyId string `position:"Query" name:"StrategyId"` + Lang string `position:"Query" name:"Lang"` +} + +// DeleteGtmAccessStrategyResponse is the response struct for api DeleteGtmAccessStrategy +type DeleteGtmAccessStrategyResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateDeleteGtmAccessStrategyRequest creates a request to invoke DeleteGtmAccessStrategy API +func CreateDeleteGtmAccessStrategyRequest() (request *DeleteGtmAccessStrategyRequest) { + request = &DeleteGtmAccessStrategyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DeleteGtmAccessStrategy", "Alidns", "openAPI") + return +} + +// CreateDeleteGtmAccessStrategyResponse creates a response to parse from DeleteGtmAccessStrategy response +func CreateDeleteGtmAccessStrategyResponse() (response *DeleteGtmAccessStrategyResponse) { + response = &DeleteGtmAccessStrategyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_gtm_address_pool.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_gtm_address_pool.go new file mode 100644 index 000000000..4ca0aad95 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_gtm_address_pool.go @@ -0,0 +1,105 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DeleteGtmAddressPool invokes the alidns.DeleteGtmAddressPool API synchronously +// api document: https://help.aliyun.com/api/alidns/deletegtmaddresspool.html +func (client *Client) DeleteGtmAddressPool(request *DeleteGtmAddressPoolRequest) (response *DeleteGtmAddressPoolResponse, err error) { + response = CreateDeleteGtmAddressPoolResponse() + err = client.DoAction(request, response) + return +} + +// DeleteGtmAddressPoolWithChan invokes the alidns.DeleteGtmAddressPool API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletegtmaddresspool.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteGtmAddressPoolWithChan(request *DeleteGtmAddressPoolRequest) (<-chan *DeleteGtmAddressPoolResponse, <-chan error) { + responseChan := make(chan *DeleteGtmAddressPoolResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DeleteGtmAddressPool(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DeleteGtmAddressPoolWithCallback invokes the alidns.DeleteGtmAddressPool API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletegtmaddresspool.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteGtmAddressPoolWithCallback(request *DeleteGtmAddressPoolRequest, callback func(response *DeleteGtmAddressPoolResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DeleteGtmAddressPoolResponse + var err error + defer close(result) + response, err = client.DeleteGtmAddressPool(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DeleteGtmAddressPoolRequest is the request struct for api DeleteGtmAddressPool +type DeleteGtmAddressPoolRequest struct { + *requests.RpcRequest + AddrPoolId string `position:"Query" name:"AddrPoolId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DeleteGtmAddressPoolResponse is the response struct for api DeleteGtmAddressPool +type DeleteGtmAddressPoolResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateDeleteGtmAddressPoolRequest creates a request to invoke DeleteGtmAddressPool API +func CreateDeleteGtmAddressPoolRequest() (request *DeleteGtmAddressPoolRequest) { + request = &DeleteGtmAddressPoolRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DeleteGtmAddressPool", "Alidns", "openAPI") + return +} + +// CreateDeleteGtmAddressPoolResponse creates a response to parse from DeleteGtmAddressPool response +func CreateDeleteGtmAddressPoolResponse() (response *DeleteGtmAddressPoolResponse) { + response = &DeleteGtmAddressPoolResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_sub_domain_records.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_sub_domain_records.go new file mode 100644 index 000000000..9de84703b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/delete_sub_domain_records.go @@ -0,0 +1,109 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DeleteSubDomainRecords invokes the alidns.DeleteSubDomainRecords API synchronously +// api document: https://help.aliyun.com/api/alidns/deletesubdomainrecords.html +func (client *Client) DeleteSubDomainRecords(request *DeleteSubDomainRecordsRequest) (response *DeleteSubDomainRecordsResponse, err error) { + response = CreateDeleteSubDomainRecordsResponse() + err = client.DoAction(request, response) + return +} + +// DeleteSubDomainRecordsWithChan invokes the alidns.DeleteSubDomainRecords API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletesubdomainrecords.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteSubDomainRecordsWithChan(request *DeleteSubDomainRecordsRequest) (<-chan *DeleteSubDomainRecordsResponse, <-chan error) { + responseChan := make(chan *DeleteSubDomainRecordsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DeleteSubDomainRecords(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DeleteSubDomainRecordsWithCallback invokes the alidns.DeleteSubDomainRecords API asynchronously +// api document: https://help.aliyun.com/api/alidns/deletesubdomainrecords.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DeleteSubDomainRecordsWithCallback(request *DeleteSubDomainRecordsRequest, callback func(response *DeleteSubDomainRecordsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DeleteSubDomainRecordsResponse + var err error + defer close(result) + response, err = client.DeleteSubDomainRecords(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DeleteSubDomainRecordsRequest is the request struct for api DeleteSubDomainRecords +type DeleteSubDomainRecordsRequest struct { + *requests.RpcRequest + RR string `position:"Query" name:"RR"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + Type string `position:"Query" name:"Type"` +} + +// DeleteSubDomainRecordsResponse is the response struct for api DeleteSubDomainRecords +type DeleteSubDomainRecordsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + RR string `json:"RR" xml:"RR"` + TotalCount string `json:"TotalCount" xml:"TotalCount"` +} + +// CreateDeleteSubDomainRecordsRequest creates a request to invoke DeleteSubDomainRecords API +func CreateDeleteSubDomainRecordsRequest() (request *DeleteSubDomainRecordsRequest) { + request = &DeleteSubDomainRecordsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DeleteSubDomainRecords", "Alidns", "openAPI") + return +} + +// CreateDeleteSubDomainRecordsResponse creates a response to parse from DeleteSubDomainRecords response +func CreateDeleteSubDomainRecordsResponse() (response *DeleteSubDomainRecordsResponse) { + response = &DeleteSubDomainRecordsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_batch_result_count.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_batch_result_count.go new file mode 100644 index 000000000..a1100ed82 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_batch_result_count.go @@ -0,0 +1,113 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeBatchResultCount invokes the alidns.DescribeBatchResultCount API synchronously +// api document: https://help.aliyun.com/api/alidns/describebatchresultcount.html +func (client *Client) DescribeBatchResultCount(request *DescribeBatchResultCountRequest) (response *DescribeBatchResultCountResponse, err error) { + response = CreateDescribeBatchResultCountResponse() + err = client.DoAction(request, response) + return +} + +// DescribeBatchResultCountWithChan invokes the alidns.DescribeBatchResultCount API asynchronously +// api document: https://help.aliyun.com/api/alidns/describebatchresultcount.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeBatchResultCountWithChan(request *DescribeBatchResultCountRequest) (<-chan *DescribeBatchResultCountResponse, <-chan error) { + responseChan := make(chan *DescribeBatchResultCountResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeBatchResultCount(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeBatchResultCountWithCallback invokes the alidns.DescribeBatchResultCount API asynchronously +// api document: https://help.aliyun.com/api/alidns/describebatchresultcount.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeBatchResultCountWithCallback(request *DescribeBatchResultCountRequest, callback func(response *DescribeBatchResultCountResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeBatchResultCountResponse + var err error + defer close(result) + response, err = client.DescribeBatchResultCount(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeBatchResultCountRequest is the request struct for api DescribeBatchResultCount +type DescribeBatchResultCountRequest struct { + *requests.RpcRequest + BatchType string `position:"Query" name:"BatchType"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` + TaskId requests.Integer `position:"Query" name:"TaskId"` +} + +// DescribeBatchResultCountResponse is the response struct for api DescribeBatchResultCount +type DescribeBatchResultCountResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + Status int `json:"Status" xml:"Status"` + TotalCount int `json:"TotalCount" xml:"TotalCount"` + SuccessCount int `json:"SuccessCount" xml:"SuccessCount"` + FailedCount int `json:"FailedCount" xml:"FailedCount"` + Reason string `json:"Reason" xml:"Reason"` + BatchType string `json:"BatchType" xml:"BatchType"` + TaskId int64 `json:"TaskId" xml:"TaskId"` +} + +// CreateDescribeBatchResultCountRequest creates a request to invoke DescribeBatchResultCount API +func CreateDescribeBatchResultCountRequest() (request *DescribeBatchResultCountRequest) { + request = &DescribeBatchResultCountRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeBatchResultCount", "Alidns", "openAPI") + return +} + +// CreateDescribeBatchResultCountResponse creates a response to parse from DescribeBatchResultCount response +func CreateDescribeBatchResultCountResponse() (response *DescribeBatchResultCountResponse) { + response = &DescribeBatchResultCountResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_batch_result_detail.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_batch_result_detail.go new file mode 100644 index 000000000..8baa5b8fc --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_batch_result_detail.go @@ -0,0 +1,112 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeBatchResultDetail invokes the alidns.DescribeBatchResultDetail API synchronously +// api document: https://help.aliyun.com/api/alidns/describebatchresultdetail.html +func (client *Client) DescribeBatchResultDetail(request *DescribeBatchResultDetailRequest) (response *DescribeBatchResultDetailResponse, err error) { + response = CreateDescribeBatchResultDetailResponse() + err = client.DoAction(request, response) + return +} + +// DescribeBatchResultDetailWithChan invokes the alidns.DescribeBatchResultDetail API asynchronously +// api document: https://help.aliyun.com/api/alidns/describebatchresultdetail.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeBatchResultDetailWithChan(request *DescribeBatchResultDetailRequest) (<-chan *DescribeBatchResultDetailResponse, <-chan error) { + responseChan := make(chan *DescribeBatchResultDetailResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeBatchResultDetail(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeBatchResultDetailWithCallback invokes the alidns.DescribeBatchResultDetail API asynchronously +// api document: https://help.aliyun.com/api/alidns/describebatchresultdetail.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeBatchResultDetailWithCallback(request *DescribeBatchResultDetailRequest, callback func(response *DescribeBatchResultDetailResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeBatchResultDetailResponse + var err error + defer close(result) + response, err = client.DescribeBatchResultDetail(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeBatchResultDetailRequest is the request struct for api DescribeBatchResultDetail +type DescribeBatchResultDetailRequest struct { + *requests.RpcRequest + BatchType string `position:"Query" name:"BatchType"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` + TaskId requests.Integer `position:"Query" name:"TaskId"` +} + +// DescribeBatchResultDetailResponse is the response struct for api DescribeBatchResultDetail +type DescribeBatchResultDetailResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + BatchResultDetails BatchResultDetails `json:"BatchResultDetails" xml:"BatchResultDetails"` +} + +// CreateDescribeBatchResultDetailRequest creates a request to invoke DescribeBatchResultDetail API +func CreateDescribeBatchResultDetailRequest() (request *DescribeBatchResultDetailRequest) { + request = &DescribeBatchResultDetailRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeBatchResultDetail", "Alidns", "openAPI") + return +} + +// CreateDescribeBatchResultDetailResponse creates a response to parse from DescribeBatchResultDetail response +func CreateDescribeBatchResultDetailResponse() (response *DescribeBatchResultDetailResponse) { + response = &DescribeBatchResultDetailResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dns_product_instance.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dns_product_instance.go new file mode 100644 index 000000000..74f23ce6c --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dns_product_instance.go @@ -0,0 +1,137 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDnsProductInstance invokes the alidns.DescribeDnsProductInstance API synchronously +// api document: https://help.aliyun.com/api/alidns/describednsproductinstance.html +func (client *Client) DescribeDnsProductInstance(request *DescribeDnsProductInstanceRequest) (response *DescribeDnsProductInstanceResponse, err error) { + response = CreateDescribeDnsProductInstanceResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDnsProductInstanceWithChan invokes the alidns.DescribeDnsProductInstance API asynchronously +// api document: https://help.aliyun.com/api/alidns/describednsproductinstance.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDnsProductInstanceWithChan(request *DescribeDnsProductInstanceRequest) (<-chan *DescribeDnsProductInstanceResponse, <-chan error) { + responseChan := make(chan *DescribeDnsProductInstanceResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDnsProductInstance(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDnsProductInstanceWithCallback invokes the alidns.DescribeDnsProductInstance API asynchronously +// api document: https://help.aliyun.com/api/alidns/describednsproductinstance.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDnsProductInstanceWithCallback(request *DescribeDnsProductInstanceRequest, callback func(response *DescribeDnsProductInstanceResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDnsProductInstanceResponse + var err error + defer close(result) + response, err = client.DescribeDnsProductInstance(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDnsProductInstanceRequest is the request struct for api DescribeDnsProductInstance +type DescribeDnsProductInstanceRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeDnsProductInstanceResponse is the response struct for api DescribeDnsProductInstance +type DescribeDnsProductInstanceResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + InstanceId string `json:"InstanceId" xml:"InstanceId"` + VersionCode string `json:"VersionCode" xml:"VersionCode"` + VersionName string `json:"VersionName" xml:"VersionName"` + StartTime string `json:"StartTime" xml:"StartTime"` + StartTimestamp int64 `json:"StartTimestamp" xml:"StartTimestamp"` + EndTime string `json:"EndTime" xml:"EndTime"` + EndTimestamp int64 `json:"EndTimestamp" xml:"EndTimestamp"` + Domain string `json:"Domain" xml:"Domain"` + BindCount int64 `json:"BindCount" xml:"BindCount"` + BindUsedCount int64 `json:"BindUsedCount" xml:"BindUsedCount"` + TTLMinValue int64 `json:"TTLMinValue" xml:"TTLMinValue"` + SubDomainLevel int64 `json:"SubDomainLevel" xml:"SubDomainLevel"` + DnsSLBCount int64 `json:"DnsSLBCount" xml:"DnsSLBCount"` + URLForwardCount int64 `json:"URLForwardCount" xml:"URLForwardCount"` + DDosDefendFlow int64 `json:"DDosDefendFlow" xml:"DDosDefendFlow"` + DDosDefendQuery int64 `json:"DDosDefendQuery" xml:"DDosDefendQuery"` + OverseaDDosDefendFlow int64 `json:"OverseaDDosDefendFlow" xml:"OverseaDDosDefendFlow"` + SearchEngineLines string `json:"SearchEngineLines" xml:"SearchEngineLines"` + ISPLines string `json:"ISPLines" xml:"ISPLines"` + ISPRegionLines string `json:"ISPRegionLines" xml:"ISPRegionLines"` + OverseaLine string `json:"OverseaLine" xml:"OverseaLine"` + MonitorNodeCount int64 `json:"MonitorNodeCount" xml:"MonitorNodeCount"` + MonitorFrequency int64 `json:"MonitorFrequency" xml:"MonitorFrequency"` + MonitorTaskCount int64 `json:"MonitorTaskCount" xml:"MonitorTaskCount"` + RegionLines bool `json:"RegionLines" xml:"RegionLines"` + Gslb bool `json:"Gslb" xml:"Gslb"` + InClean bool `json:"InClean" xml:"InClean"` + InBlackHole bool `json:"InBlackHole" xml:"InBlackHole"` + BindDomainCount int64 `json:"BindDomainCount" xml:"BindDomainCount"` + BindDomainUsedCount int64 `json:"BindDomainUsedCount" xml:"BindDomainUsedCount"` + DnsSecurity string `json:"DnsSecurity" xml:"DnsSecurity"` + DnsServers DnsServersInDescribeDnsProductInstance `json:"DnsServers" xml:"DnsServers"` +} + +// CreateDescribeDnsProductInstanceRequest creates a request to invoke DescribeDnsProductInstance API +func CreateDescribeDnsProductInstanceRequest() (request *DescribeDnsProductInstanceRequest) { + request = &DescribeDnsProductInstanceRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDnsProductInstance", "Alidns", "openAPI") + return +} + +// CreateDescribeDnsProductInstanceResponse creates a response to parse from DescribeDnsProductInstance response +func CreateDescribeDnsProductInstanceResponse() (response *DescribeDnsProductInstanceResponse) { + response = &DescribeDnsProductInstanceResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dns_product_instances.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dns_product_instances.go new file mode 100644 index 000000000..c7c5c2e67 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dns_product_instances.go @@ -0,0 +1,111 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDnsProductInstances invokes the alidns.DescribeDnsProductInstances API synchronously +// api document: https://help.aliyun.com/api/alidns/describednsproductinstances.html +func (client *Client) DescribeDnsProductInstances(request *DescribeDnsProductInstancesRequest) (response *DescribeDnsProductInstancesResponse, err error) { + response = CreateDescribeDnsProductInstancesResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDnsProductInstancesWithChan invokes the alidns.DescribeDnsProductInstances API asynchronously +// api document: https://help.aliyun.com/api/alidns/describednsproductinstances.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDnsProductInstancesWithChan(request *DescribeDnsProductInstancesRequest) (<-chan *DescribeDnsProductInstancesResponse, <-chan error) { + responseChan := make(chan *DescribeDnsProductInstancesResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDnsProductInstances(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDnsProductInstancesWithCallback invokes the alidns.DescribeDnsProductInstances API asynchronously +// api document: https://help.aliyun.com/api/alidns/describednsproductinstances.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDnsProductInstancesWithCallback(request *DescribeDnsProductInstancesRequest, callback func(response *DescribeDnsProductInstancesResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDnsProductInstancesResponse + var err error + defer close(result) + response, err = client.DescribeDnsProductInstances(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDnsProductInstancesRequest is the request struct for api DescribeDnsProductInstances +type DescribeDnsProductInstancesRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + VersionCode string `position:"Query" name:"VersionCode"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeDnsProductInstancesResponse is the response struct for api DescribeDnsProductInstances +type DescribeDnsProductInstancesResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + DnsProducts DnsProducts `json:"DnsProducts" xml:"DnsProducts"` +} + +// CreateDescribeDnsProductInstancesRequest creates a request to invoke DescribeDnsProductInstances API +func CreateDescribeDnsProductInstancesRequest() (request *DescribeDnsProductInstancesRequest) { + request = &DescribeDnsProductInstancesRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDnsProductInstances", "Alidns", "openAPI") + return +} + +// CreateDescribeDnsProductInstancesResponse creates a response to parse from DescribeDnsProductInstances response +func CreateDescribeDnsProductInstancesResponse() (response *DescribeDnsProductInstancesResponse) { + response = &DescribeDnsProductInstancesResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dnsslb_sub_domains.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dnsslb_sub_domains.go new file mode 100644 index 000000000..818ca1ef9 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_dnsslb_sub_domains.go @@ -0,0 +1,111 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDNSSLBSubDomains invokes the alidns.DescribeDNSSLBSubDomains API synchronously +// api document: https://help.aliyun.com/api/alidns/describednsslbsubdomains.html +func (client *Client) DescribeDNSSLBSubDomains(request *DescribeDNSSLBSubDomainsRequest) (response *DescribeDNSSLBSubDomainsResponse, err error) { + response = CreateDescribeDNSSLBSubDomainsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDNSSLBSubDomainsWithChan invokes the alidns.DescribeDNSSLBSubDomains API asynchronously +// api document: https://help.aliyun.com/api/alidns/describednsslbsubdomains.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDNSSLBSubDomainsWithChan(request *DescribeDNSSLBSubDomainsRequest) (<-chan *DescribeDNSSLBSubDomainsResponse, <-chan error) { + responseChan := make(chan *DescribeDNSSLBSubDomainsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDNSSLBSubDomains(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDNSSLBSubDomainsWithCallback invokes the alidns.DescribeDNSSLBSubDomains API asynchronously +// api document: https://help.aliyun.com/api/alidns/describednsslbsubdomains.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDNSSLBSubDomainsWithCallback(request *DescribeDNSSLBSubDomainsRequest, callback func(response *DescribeDNSSLBSubDomainsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDNSSLBSubDomainsResponse + var err error + defer close(result) + response, err = client.DescribeDNSSLBSubDomains(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDNSSLBSubDomainsRequest is the request struct for api DescribeDNSSLBSubDomains +type DescribeDNSSLBSubDomainsRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeDNSSLBSubDomainsResponse is the response struct for api DescribeDNSSLBSubDomains +type DescribeDNSSLBSubDomainsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + SlbSubDomains SlbSubDomains `json:"SlbSubDomains" xml:"SlbSubDomains"` +} + +// CreateDescribeDNSSLBSubDomainsRequest creates a request to invoke DescribeDNSSLBSubDomains API +func CreateDescribeDNSSLBSubDomainsRequest() (request *DescribeDNSSLBSubDomainsRequest) { + request = &DescribeDNSSLBSubDomainsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDNSSLBSubDomains", "Alidns", "openAPI") + return +} + +// CreateDescribeDNSSLBSubDomainsResponse creates a response to parse from DescribeDNSSLBSubDomains response +func CreateDescribeDNSSLBSubDomainsResponse() (response *DescribeDNSSLBSubDomainsResponse) { + response = &DescribeDNSSLBSubDomainsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_dns_statistics.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_dns_statistics.go new file mode 100644 index 000000000..f3942fdd2 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_dns_statistics.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainDnsStatistics invokes the alidns.DescribeDomainDnsStatistics API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomaindnsstatistics.html +func (client *Client) DescribeDomainDnsStatistics(request *DescribeDomainDnsStatisticsRequest) (response *DescribeDomainDnsStatisticsResponse, err error) { + response = CreateDescribeDomainDnsStatisticsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainDnsStatisticsWithChan invokes the alidns.DescribeDomainDnsStatistics API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomaindnsstatistics.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainDnsStatisticsWithChan(request *DescribeDomainDnsStatisticsRequest) (<-chan *DescribeDomainDnsStatisticsResponse, <-chan error) { + responseChan := make(chan *DescribeDomainDnsStatisticsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainDnsStatistics(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainDnsStatisticsWithCallback invokes the alidns.DescribeDomainDnsStatistics API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomaindnsstatistics.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainDnsStatisticsWithCallback(request *DescribeDomainDnsStatisticsRequest, callback func(response *DescribeDomainDnsStatisticsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainDnsStatisticsResponse + var err error + defer close(result) + response, err = client.DescribeDomainDnsStatistics(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainDnsStatisticsRequest is the request struct for api DescribeDomainDnsStatistics +type DescribeDomainDnsStatisticsRequest struct { + *requests.RpcRequest + EndDate string `position:"Query" name:"EndDate"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + StartDate string `position:"Query" name:"StartDate"` +} + +// DescribeDomainDnsStatisticsResponse is the response struct for api DescribeDomainDnsStatistics +type DescribeDomainDnsStatisticsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + Statistics StatisticsInDescribeDomainDnsStatistics `json:"Statistics" xml:"Statistics"` +} + +// CreateDescribeDomainDnsStatisticsRequest creates a request to invoke DescribeDomainDnsStatistics API +func CreateDescribeDomainDnsStatisticsRequest() (request *DescribeDomainDnsStatisticsRequest) { + request = &DescribeDomainDnsStatisticsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainDnsStatistics", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainDnsStatisticsResponse creates a response to parse from DescribeDomainDnsStatistics response +func CreateDescribeDomainDnsStatisticsResponse() (response *DescribeDomainDnsStatisticsResponse) { + response = &DescribeDomainDnsStatisticsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_groups.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_groups.go new file mode 100644 index 000000000..081887393 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_groups.go @@ -0,0 +1,111 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainGroups invokes the alidns.DescribeDomainGroups API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomaingroups.html +func (client *Client) DescribeDomainGroups(request *DescribeDomainGroupsRequest) (response *DescribeDomainGroupsResponse, err error) { + response = CreateDescribeDomainGroupsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainGroupsWithChan invokes the alidns.DescribeDomainGroups API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomaingroups.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainGroupsWithChan(request *DescribeDomainGroupsRequest) (<-chan *DescribeDomainGroupsResponse, <-chan error) { + responseChan := make(chan *DescribeDomainGroupsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainGroups(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainGroupsWithCallback invokes the alidns.DescribeDomainGroups API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomaingroups.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainGroupsWithCallback(request *DescribeDomainGroupsRequest, callback func(response *DescribeDomainGroupsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainGroupsResponse + var err error + defer close(result) + response, err = client.DescribeDomainGroups(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainGroupsRequest is the request struct for api DescribeDomainGroups +type DescribeDomainGroupsRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + KeyWord string `position:"Query" name:"KeyWord"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeDomainGroupsResponse is the response struct for api DescribeDomainGroups +type DescribeDomainGroupsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + DomainGroups DomainGroups `json:"DomainGroups" xml:"DomainGroups"` +} + +// CreateDescribeDomainGroupsRequest creates a request to invoke DescribeDomainGroups API +func CreateDescribeDomainGroupsRequest() (request *DescribeDomainGroupsRequest) { + request = &DescribeDomainGroupsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainGroups", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainGroupsResponse creates a response to parse from DescribeDomainGroups response +func CreateDescribeDomainGroupsResponse() (response *DescribeDomainGroupsResponse) { + response = &DescribeDomainGroupsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_info.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_info.go new file mode 100644 index 000000000..5cd55af72 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_info.go @@ -0,0 +1,126 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainInfo invokes the alidns.DescribeDomainInfo API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomaininfo.html +func (client *Client) DescribeDomainInfo(request *DescribeDomainInfoRequest) (response *DescribeDomainInfoResponse, err error) { + response = CreateDescribeDomainInfoResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainInfoWithChan invokes the alidns.DescribeDomainInfo API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomaininfo.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainInfoWithChan(request *DescribeDomainInfoRequest) (<-chan *DescribeDomainInfoResponse, <-chan error) { + responseChan := make(chan *DescribeDomainInfoResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainInfo(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainInfoWithCallback invokes the alidns.DescribeDomainInfo API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomaininfo.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainInfoWithCallback(request *DescribeDomainInfoRequest, callback func(response *DescribeDomainInfoResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainInfoResponse + var err error + defer close(result) + response, err = client.DescribeDomainInfo(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainInfoRequest is the request struct for api DescribeDomainInfo +type DescribeDomainInfoRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + NeedDetailAttributes requests.Boolean `position:"Query" name:"NeedDetailAttributes"` +} + +// DescribeDomainInfoResponse is the response struct for api DescribeDomainInfo +type DescribeDomainInfoResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + DomainId string `json:"DomainId" xml:"DomainId"` + DomainName string `json:"DomainName" xml:"DomainName"` + PunyCode string `json:"PunyCode" xml:"PunyCode"` + AliDomain bool `json:"AliDomain" xml:"AliDomain"` + Remark string `json:"Remark" xml:"Remark"` + GroupId string `json:"GroupId" xml:"GroupId"` + GroupName string `json:"GroupName" xml:"GroupName"` + InstanceId string `json:"InstanceId" xml:"InstanceId"` + VersionCode string `json:"VersionCode" xml:"VersionCode"` + VersionName string `json:"VersionName" xml:"VersionName"` + MinTtl int64 `json:"MinTtl" xml:"MinTtl"` + RecordLineTreeJson string `json:"RecordLineTreeJson" xml:"RecordLineTreeJson"` + LineType string `json:"LineType" xml:"LineType"` + RegionLines bool `json:"RegionLines" xml:"RegionLines"` + InBlackHole bool `json:"InBlackHole" xml:"InBlackHole"` + InClean bool `json:"InClean" xml:"InClean"` + SlaveDns bool `json:"SlaveDns" xml:"SlaveDns"` + DnsServers DnsServersInDescribeDomainInfo `json:"DnsServers" xml:"DnsServers"` + AvailableTtls AvailableTtls `json:"AvailableTtls" xml:"AvailableTtls"` + RecordLines RecordLinesInDescribeDomainInfo `json:"RecordLines" xml:"RecordLines"` +} + +// CreateDescribeDomainInfoRequest creates a request to invoke DescribeDomainInfo API +func CreateDescribeDomainInfoRequest() (request *DescribeDomainInfoRequest) { + request = &DescribeDomainInfoRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainInfo", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainInfoResponse creates a response to parse from DescribeDomainInfo response +func CreateDescribeDomainInfoResponse() (response *DescribeDomainInfoResponse) { + response = &DescribeDomainInfoResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_logs.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_logs.go new file mode 100644 index 000000000..035c56053 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_logs.go @@ -0,0 +1,115 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainLogs invokes the alidns.DescribeDomainLogs API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomainlogs.html +func (client *Client) DescribeDomainLogs(request *DescribeDomainLogsRequest) (response *DescribeDomainLogsResponse, err error) { + response = CreateDescribeDomainLogsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainLogsWithChan invokes the alidns.DescribeDomainLogs API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainlogs.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainLogsWithChan(request *DescribeDomainLogsRequest) (<-chan *DescribeDomainLogsResponse, <-chan error) { + responseChan := make(chan *DescribeDomainLogsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainLogs(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainLogsWithCallback invokes the alidns.DescribeDomainLogs API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainlogs.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainLogsWithCallback(request *DescribeDomainLogsRequest, callback func(response *DescribeDomainLogsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainLogsResponse + var err error + defer close(result) + response, err = client.DescribeDomainLogs(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainLogsRequest is the request struct for api DescribeDomainLogs +type DescribeDomainLogsRequest struct { + *requests.RpcRequest + EndDate string `position:"Query" name:"endDate"` + GroupId string `position:"Query" name:"GroupId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + KeyWord string `position:"Query" name:"KeyWord"` + StartDate string `position:"Query" name:"StartDate"` + Type string `position:"Query" name:"Type"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeDomainLogsResponse is the response struct for api DescribeDomainLogs +type DescribeDomainLogsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + DomainLogs DomainLogs `json:"DomainLogs" xml:"DomainLogs"` +} + +// CreateDescribeDomainLogsRequest creates a request to invoke DescribeDomainLogs API +func CreateDescribeDomainLogsRequest() (request *DescribeDomainLogsRequest) { + request = &DescribeDomainLogsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainLogs", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainLogsResponse creates a response to parse from DescribeDomainLogs response +func CreateDescribeDomainLogsResponse() (response *DescribeDomainLogsResponse) { + response = &DescribeDomainLogsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_ns.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_ns.go new file mode 100644 index 000000000..e88cc864f --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_ns.go @@ -0,0 +1,109 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainNs invokes the alidns.DescribeDomainNs API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomainns.html +func (client *Client) DescribeDomainNs(request *DescribeDomainNsRequest) (response *DescribeDomainNsResponse, err error) { + response = CreateDescribeDomainNsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainNsWithChan invokes the alidns.DescribeDomainNs API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainns.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainNsWithChan(request *DescribeDomainNsRequest) (<-chan *DescribeDomainNsResponse, <-chan error) { + responseChan := make(chan *DescribeDomainNsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainNs(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainNsWithCallback invokes the alidns.DescribeDomainNs API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainns.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainNsWithCallback(request *DescribeDomainNsRequest, callback func(response *DescribeDomainNsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainNsResponse + var err error + defer close(result) + response, err = client.DescribeDomainNs(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainNsRequest is the request struct for api DescribeDomainNs +type DescribeDomainNsRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeDomainNsResponse is the response struct for api DescribeDomainNs +type DescribeDomainNsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + AllAliDns bool `json:"AllAliDns" xml:"AllAliDns"` + IncludeAliDns bool `json:"IncludeAliDns" xml:"IncludeAliDns"` + DnsServers DnsServersInDescribeDomainNs `json:"DnsServers" xml:"DnsServers"` + ExpectDnsServers ExpectDnsServers `json:"ExpectDnsServers" xml:"ExpectDnsServers"` +} + +// CreateDescribeDomainNsRequest creates a request to invoke DescribeDomainNs API +func CreateDescribeDomainNsRequest() (request *DescribeDomainNsRequest) { + request = &DescribeDomainNsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainNs", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainNsResponse creates a response to parse from DescribeDomainNs response +func CreateDescribeDomainNsResponse() (response *DescribeDomainNsResponse) { + response = &DescribeDomainNsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_record_info.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_record_info.go new file mode 100644 index 000000000..efe7c76e4 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_record_info.go @@ -0,0 +1,119 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainRecordInfo invokes the alidns.DescribeDomainRecordInfo API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomainrecordinfo.html +func (client *Client) DescribeDomainRecordInfo(request *DescribeDomainRecordInfoRequest) (response *DescribeDomainRecordInfoResponse, err error) { + response = CreateDescribeDomainRecordInfoResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainRecordInfoWithChan invokes the alidns.DescribeDomainRecordInfo API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainrecordinfo.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainRecordInfoWithChan(request *DescribeDomainRecordInfoRequest) (<-chan *DescribeDomainRecordInfoResponse, <-chan error) { + responseChan := make(chan *DescribeDomainRecordInfoResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainRecordInfo(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainRecordInfoWithCallback invokes the alidns.DescribeDomainRecordInfo API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainrecordinfo.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainRecordInfoWithCallback(request *DescribeDomainRecordInfoRequest, callback func(response *DescribeDomainRecordInfoResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainRecordInfoResponse + var err error + defer close(result) + response, err = client.DescribeDomainRecordInfo(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainRecordInfoRequest is the request struct for api DescribeDomainRecordInfo +type DescribeDomainRecordInfoRequest struct { + *requests.RpcRequest + RecordId string `position:"Query" name:"RecordId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeDomainRecordInfoResponse is the response struct for api DescribeDomainRecordInfo +type DescribeDomainRecordInfoResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + DomainId string `json:"DomainId" xml:"DomainId"` + DomainName string `json:"DomainName" xml:"DomainName"` + PunyCode string `json:"PunyCode" xml:"PunyCode"` + GroupId string `json:"GroupId" xml:"GroupId"` + GroupName string `json:"GroupName" xml:"GroupName"` + RecordId string `json:"RecordId" xml:"RecordId"` + RR string `json:"RR" xml:"RR"` + Type string `json:"Type" xml:"Type"` + Value string `json:"Value" xml:"Value"` + TTL int64 `json:"TTL" xml:"TTL"` + Priority int64 `json:"Priority" xml:"Priority"` + Line string `json:"Line" xml:"Line"` + Status string `json:"Status" xml:"Status"` + Locked bool `json:"Locked" xml:"Locked"` +} + +// CreateDescribeDomainRecordInfoRequest creates a request to invoke DescribeDomainRecordInfo API +func CreateDescribeDomainRecordInfoRequest() (request *DescribeDomainRecordInfoRequest) { + request = &DescribeDomainRecordInfoRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainRecordInfo", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainRecordInfoResponse creates a response to parse from DescribeDomainRecordInfo response +func CreateDescribeDomainRecordInfoResponse() (response *DescribeDomainRecordInfoResponse) { + response = &DescribeDomainRecordInfoResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_records.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_records.go new file mode 100644 index 000000000..d7ef1f7f1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_records.go @@ -0,0 +1,122 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainRecords invokes the alidns.DescribeDomainRecords API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomainrecords.html +func (client *Client) DescribeDomainRecords(request *DescribeDomainRecordsRequest) (response *DescribeDomainRecordsResponse, err error) { + response = CreateDescribeDomainRecordsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainRecordsWithChan invokes the alidns.DescribeDomainRecords API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainrecords.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainRecordsWithChan(request *DescribeDomainRecordsRequest) (<-chan *DescribeDomainRecordsResponse, <-chan error) { + responseChan := make(chan *DescribeDomainRecordsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainRecords(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainRecordsWithCallback invokes the alidns.DescribeDomainRecords API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainrecords.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainRecordsWithCallback(request *DescribeDomainRecordsRequest, callback func(response *DescribeDomainRecordsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainRecordsResponse + var err error + defer close(result) + response, err = client.DescribeDomainRecords(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainRecordsRequest is the request struct for api DescribeDomainRecords +type DescribeDomainRecordsRequest struct { + *requests.RpcRequest + ValueKeyWord string `position:"Query" name:"ValueKeyWord"` + Line string `position:"Query" name:"Line"` + GroupId requests.Integer `position:"Query" name:"GroupId"` + DomainName string `position:"Query" name:"DomainName"` + OrderBy string `position:"Query" name:"OrderBy"` + Type string `position:"Query" name:"Type"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + SearchMode string `position:"Query" name:"SearchMode"` + Lang string `position:"Query" name:"Lang"` + KeyWord string `position:"Query" name:"KeyWord"` + TypeKeyWord string `position:"Query" name:"TypeKeyWord"` + RRKeyWord string `position:"Query" name:"RRKeyWord"` + Direction string `position:"Query" name:"Direction"` + Status string `position:"Query" name:"Status"` +} + +// DescribeDomainRecordsResponse is the response struct for api DescribeDomainRecords +type DescribeDomainRecordsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + DomainRecords DomainRecordsInDescribeDomainRecords `json:"DomainRecords" xml:"DomainRecords"` +} + +// CreateDescribeDomainRecordsRequest creates a request to invoke DescribeDomainRecords API +func CreateDescribeDomainRecordsRequest() (request *DescribeDomainRecordsRequest) { + request = &DescribeDomainRecordsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainRecords", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainRecordsResponse creates a response to parse from DescribeDomainRecords response +func CreateDescribeDomainRecordsResponse() (response *DescribeDomainRecordsResponse) { + response = &DescribeDomainRecordsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_statistics.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_statistics.go new file mode 100644 index 000000000..15881be3d --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_statistics.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainStatistics invokes the alidns.DescribeDomainStatistics API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomainstatistics.html +func (client *Client) DescribeDomainStatistics(request *DescribeDomainStatisticsRequest) (response *DescribeDomainStatisticsResponse, err error) { + response = CreateDescribeDomainStatisticsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainStatisticsWithChan invokes the alidns.DescribeDomainStatistics API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainstatistics.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainStatisticsWithChan(request *DescribeDomainStatisticsRequest) (<-chan *DescribeDomainStatisticsResponse, <-chan error) { + responseChan := make(chan *DescribeDomainStatisticsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainStatistics(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainStatisticsWithCallback invokes the alidns.DescribeDomainStatistics API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainstatistics.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainStatisticsWithCallback(request *DescribeDomainStatisticsRequest, callback func(response *DescribeDomainStatisticsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainStatisticsResponse + var err error + defer close(result) + response, err = client.DescribeDomainStatistics(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainStatisticsRequest is the request struct for api DescribeDomainStatistics +type DescribeDomainStatisticsRequest struct { + *requests.RpcRequest + EndDate string `position:"Query" name:"EndDate"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + StartDate string `position:"Query" name:"StartDate"` +} + +// DescribeDomainStatisticsResponse is the response struct for api DescribeDomainStatistics +type DescribeDomainStatisticsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + Statistics StatisticsInDescribeDomainStatistics `json:"Statistics" xml:"Statistics"` +} + +// CreateDescribeDomainStatisticsRequest creates a request to invoke DescribeDomainStatistics API +func CreateDescribeDomainStatisticsRequest() (request *DescribeDomainStatisticsRequest) { + request = &DescribeDomainStatisticsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainStatistics", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainStatisticsResponse creates a response to parse from DescribeDomainStatistics response +func CreateDescribeDomainStatisticsResponse() (response *DescribeDomainStatisticsResponse) { + response = &DescribeDomainStatisticsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_statistics_summary.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_statistics_summary.go new file mode 100644 index 000000000..74251a724 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domain_statistics_summary.go @@ -0,0 +1,118 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomainStatisticsSummary invokes the alidns.DescribeDomainStatisticsSummary API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomainstatisticssummary.html +func (client *Client) DescribeDomainStatisticsSummary(request *DescribeDomainStatisticsSummaryRequest) (response *DescribeDomainStatisticsSummaryResponse, err error) { + response = CreateDescribeDomainStatisticsSummaryResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainStatisticsSummaryWithChan invokes the alidns.DescribeDomainStatisticsSummary API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainstatisticssummary.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainStatisticsSummaryWithChan(request *DescribeDomainStatisticsSummaryRequest) (<-chan *DescribeDomainStatisticsSummaryResponse, <-chan error) { + responseChan := make(chan *DescribeDomainStatisticsSummaryResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomainStatisticsSummary(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainStatisticsSummaryWithCallback invokes the alidns.DescribeDomainStatisticsSummary API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomainstatisticssummary.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainStatisticsSummaryWithCallback(request *DescribeDomainStatisticsSummaryRequest, callback func(response *DescribeDomainStatisticsSummaryResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainStatisticsSummaryResponse + var err error + defer close(result) + response, err = client.DescribeDomainStatisticsSummary(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainStatisticsSummaryRequest is the request struct for api DescribeDomainStatisticsSummary +type DescribeDomainStatisticsSummaryRequest struct { + *requests.RpcRequest + EndDate string `position:"Query" name:"EndDate"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + OrderBy string `position:"Query" name:"OrderBy"` + SearchMode string `position:"Query" name:"SearchMode"` + Threshold requests.Integer `position:"Query" name:"Threshold"` + Lang string `position:"Query" name:"Lang"` + StartDate string `position:"Query" name:"StartDate"` + Keyword string `position:"Query" name:"Keyword"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` + Direction string `position:"Query" name:"Direction"` +} + +// DescribeDomainStatisticsSummaryResponse is the response struct for api DescribeDomainStatisticsSummary +type DescribeDomainStatisticsSummaryResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalItems int `json:"TotalItems" xml:"TotalItems"` + TotalPages int `json:"TotalPages" xml:"TotalPages"` + PageSize int `json:"PageSize" xml:"PageSize"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + Statistics StatisticsInDescribeDomainStatisticsSummary `json:"Statistics" xml:"Statistics"` +} + +// CreateDescribeDomainStatisticsSummaryRequest creates a request to invoke DescribeDomainStatisticsSummary API +func CreateDescribeDomainStatisticsSummaryRequest() (request *DescribeDomainStatisticsSummaryRequest) { + request = &DescribeDomainStatisticsSummaryRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomainStatisticsSummary", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainStatisticsSummaryResponse creates a response to parse from DescribeDomainStatisticsSummary response +func CreateDescribeDomainStatisticsSummaryResponse() (response *DescribeDomainStatisticsSummaryResponse) { + response = &DescribeDomainStatisticsSummaryResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domains.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domains.go new file mode 100644 index 000000000..652347f9e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_domains.go @@ -0,0 +1,114 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeDomains invokes the alidns.DescribeDomains API synchronously +// api document: https://help.aliyun.com/api/alidns/describedomains.html +func (client *Client) DescribeDomains(request *DescribeDomainsRequest) (response *DescribeDomainsResponse, err error) { + response = CreateDescribeDomainsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeDomainsWithChan invokes the alidns.DescribeDomains API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomains.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainsWithChan(request *DescribeDomainsRequest) (<-chan *DescribeDomainsResponse, <-chan error) { + responseChan := make(chan *DescribeDomainsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeDomains(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeDomainsWithCallback invokes the alidns.DescribeDomains API asynchronously +// api document: https://help.aliyun.com/api/alidns/describedomains.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeDomainsWithCallback(request *DescribeDomainsRequest, callback func(response *DescribeDomainsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeDomainsResponse + var err error + defer close(result) + response, err = client.DescribeDomains(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeDomainsRequest is the request struct for api DescribeDomains +type DescribeDomainsRequest struct { + *requests.RpcRequest + ResourceGroupId string `position:"Query" name:"ResourceGroupId"` + GroupId string `position:"Query" name:"GroupId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + SearchMode string `position:"Query" name:"SearchMode"` + Lang string `position:"Query" name:"Lang"` + KeyWord string `position:"Query" name:"KeyWord"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeDomainsResponse is the response struct for api DescribeDomains +type DescribeDomainsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + Domains Domains `json:"Domains" xml:"Domains"` +} + +// CreateDescribeDomainsRequest creates a request to invoke DescribeDomains API +func CreateDescribeDomainsRequest() (request *DescribeDomainsRequest) { + request = &DescribeDomainsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeDomains", "Alidns", "openAPI") + return +} + +// CreateDescribeDomainsResponse creates a response to parse from DescribeDomains response +func CreateDescribeDomainsResponse() (response *DescribeDomainsResponse) { + response = &DescribeDomainsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategies.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategies.go new file mode 100644 index 000000000..ef3528ab0 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategies.go @@ -0,0 +1,112 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmAccessStrategies invokes the alidns.DescribeGtmAccessStrategies API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategies.html +func (client *Client) DescribeGtmAccessStrategies(request *DescribeGtmAccessStrategiesRequest) (response *DescribeGtmAccessStrategiesResponse, err error) { + response = CreateDescribeGtmAccessStrategiesResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmAccessStrategiesWithChan invokes the alidns.DescribeGtmAccessStrategies API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategies.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmAccessStrategiesWithChan(request *DescribeGtmAccessStrategiesRequest) (<-chan *DescribeGtmAccessStrategiesResponse, <-chan error) { + responseChan := make(chan *DescribeGtmAccessStrategiesResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmAccessStrategies(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmAccessStrategiesWithCallback invokes the alidns.DescribeGtmAccessStrategies API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategies.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmAccessStrategiesWithCallback(request *DescribeGtmAccessStrategiesRequest, callback func(response *DescribeGtmAccessStrategiesResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmAccessStrategiesResponse + var err error + defer close(result) + response, err = client.DescribeGtmAccessStrategies(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmAccessStrategiesRequest is the request struct for api DescribeGtmAccessStrategies +type DescribeGtmAccessStrategiesRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeGtmAccessStrategiesResponse is the response struct for api DescribeGtmAccessStrategies +type DescribeGtmAccessStrategiesResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalItems int `json:"TotalItems" xml:"TotalItems"` + TotalPages int `json:"TotalPages" xml:"TotalPages"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + PageSize int `json:"PageSize" xml:"PageSize"` + Strategies Strategies `json:"Strategies" xml:"Strategies"` +} + +// CreateDescribeGtmAccessStrategiesRequest creates a request to invoke DescribeGtmAccessStrategies API +func CreateDescribeGtmAccessStrategiesRequest() (request *DescribeGtmAccessStrategiesRequest) { + request = &DescribeGtmAccessStrategiesRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmAccessStrategies", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmAccessStrategiesResponse creates a response to parse from DescribeGtmAccessStrategies response +func CreateDescribeGtmAccessStrategiesResponse() (response *DescribeGtmAccessStrategiesResponse) { + response = &DescribeGtmAccessStrategiesResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategy.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategy.go new file mode 100644 index 000000000..d1851d6ce --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategy.go @@ -0,0 +1,116 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmAccessStrategy invokes the alidns.DescribeGtmAccessStrategy API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategy.html +func (client *Client) DescribeGtmAccessStrategy(request *DescribeGtmAccessStrategyRequest) (response *DescribeGtmAccessStrategyResponse, err error) { + response = CreateDescribeGtmAccessStrategyResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmAccessStrategyWithChan invokes the alidns.DescribeGtmAccessStrategy API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategy.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmAccessStrategyWithChan(request *DescribeGtmAccessStrategyRequest) (<-chan *DescribeGtmAccessStrategyResponse, <-chan error) { + responseChan := make(chan *DescribeGtmAccessStrategyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmAccessStrategy(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmAccessStrategyWithCallback invokes the alidns.DescribeGtmAccessStrategy API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategy.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmAccessStrategyWithCallback(request *DescribeGtmAccessStrategyRequest, callback func(response *DescribeGtmAccessStrategyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmAccessStrategyResponse + var err error + defer close(result) + response, err = client.DescribeGtmAccessStrategy(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmAccessStrategyRequest is the request struct for api DescribeGtmAccessStrategy +type DescribeGtmAccessStrategyRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + StrategyId string `position:"Query" name:"StrategyId"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmAccessStrategyResponse is the response struct for api DescribeGtmAccessStrategy +type DescribeGtmAccessStrategyResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + StrategyId string `json:"StrategyId" xml:"StrategyId"` + StrategyName string `json:"StrategyName" xml:"StrategyName"` + DefultAddrPoolId string `json:"DefultAddrPoolId" xml:"DefultAddrPoolId"` + DefaultAddrPoolName string `json:"DefaultAddrPoolName" xml:"DefaultAddrPoolName"` + FailoverAddrPoolId string `json:"FailoverAddrPoolId" xml:"FailoverAddrPoolId"` + FailoverAddrPoolName string `json:"FailoverAddrPoolName" xml:"FailoverAddrPoolName"` + StrategyMode string `json:"StrategyMode" xml:"StrategyMode"` + AccessMode string `json:"AccessMode" xml:"AccessMode"` + AccessStatus string `json:"AccessStatus" xml:"AccessStatus"` + InstanceId string `json:"InstanceId" xml:"InstanceId"` + Lines LinesInDescribeGtmAccessStrategy `json:"Lines" xml:"Lines"` +} + +// CreateDescribeGtmAccessStrategyRequest creates a request to invoke DescribeGtmAccessStrategy API +func CreateDescribeGtmAccessStrategyRequest() (request *DescribeGtmAccessStrategyRequest) { + request = &DescribeGtmAccessStrategyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmAccessStrategy", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmAccessStrategyResponse creates a response to parse from DescribeGtmAccessStrategy response +func CreateDescribeGtmAccessStrategyResponse() (response *DescribeGtmAccessStrategyResponse) { + response = &DescribeGtmAccessStrategyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategy_available_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategy_available_config.go new file mode 100644 index 000000000..f25d27f8a --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_access_strategy_available_config.go @@ -0,0 +1,107 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmAccessStrategyAvailableConfig invokes the alidns.DescribeGtmAccessStrategyAvailableConfig API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategyavailableconfig.html +func (client *Client) DescribeGtmAccessStrategyAvailableConfig(request *DescribeGtmAccessStrategyAvailableConfigRequest) (response *DescribeGtmAccessStrategyAvailableConfigResponse, err error) { + response = CreateDescribeGtmAccessStrategyAvailableConfigResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmAccessStrategyAvailableConfigWithChan invokes the alidns.DescribeGtmAccessStrategyAvailableConfig API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategyavailableconfig.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmAccessStrategyAvailableConfigWithChan(request *DescribeGtmAccessStrategyAvailableConfigRequest) (<-chan *DescribeGtmAccessStrategyAvailableConfigResponse, <-chan error) { + responseChan := make(chan *DescribeGtmAccessStrategyAvailableConfigResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmAccessStrategyAvailableConfig(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmAccessStrategyAvailableConfigWithCallback invokes the alidns.DescribeGtmAccessStrategyAvailableConfig API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmaccessstrategyavailableconfig.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmAccessStrategyAvailableConfigWithCallback(request *DescribeGtmAccessStrategyAvailableConfigRequest, callback func(response *DescribeGtmAccessStrategyAvailableConfigResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmAccessStrategyAvailableConfigResponse + var err error + defer close(result) + response, err = client.DescribeGtmAccessStrategyAvailableConfig(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmAccessStrategyAvailableConfigRequest is the request struct for api DescribeGtmAccessStrategyAvailableConfig +type DescribeGtmAccessStrategyAvailableConfigRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmAccessStrategyAvailableConfigResponse is the response struct for api DescribeGtmAccessStrategyAvailableConfig +type DescribeGtmAccessStrategyAvailableConfigResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + AddrPools AddrPoolsInDescribeGtmAccessStrategyAvailableConfig `json:"AddrPools" xml:"AddrPools"` + Lines LinesInDescribeGtmAccessStrategyAvailableConfig `json:"Lines" xml:"Lines"` +} + +// CreateDescribeGtmAccessStrategyAvailableConfigRequest creates a request to invoke DescribeGtmAccessStrategyAvailableConfig API +func CreateDescribeGtmAccessStrategyAvailableConfigRequest() (request *DescribeGtmAccessStrategyAvailableConfigRequest) { + request = &DescribeGtmAccessStrategyAvailableConfigRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmAccessStrategyAvailableConfig", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmAccessStrategyAvailableConfigResponse creates a response to parse from DescribeGtmAccessStrategyAvailableConfig response +func CreateDescribeGtmAccessStrategyAvailableConfigResponse() (response *DescribeGtmAccessStrategyAvailableConfigResponse) { + response = &DescribeGtmAccessStrategyAvailableConfigResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_available_alert_group.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_available_alert_group.go new file mode 100644 index 000000000..b79265dd7 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_available_alert_group.go @@ -0,0 +1,105 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmAvailableAlertGroup invokes the alidns.DescribeGtmAvailableAlertGroup API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtmavailablealertgroup.html +func (client *Client) DescribeGtmAvailableAlertGroup(request *DescribeGtmAvailableAlertGroupRequest) (response *DescribeGtmAvailableAlertGroupResponse, err error) { + response = CreateDescribeGtmAvailableAlertGroupResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmAvailableAlertGroupWithChan invokes the alidns.DescribeGtmAvailableAlertGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmavailablealertgroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmAvailableAlertGroupWithChan(request *DescribeGtmAvailableAlertGroupRequest) (<-chan *DescribeGtmAvailableAlertGroupResponse, <-chan error) { + responseChan := make(chan *DescribeGtmAvailableAlertGroupResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmAvailableAlertGroup(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmAvailableAlertGroupWithCallback invokes the alidns.DescribeGtmAvailableAlertGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmavailablealertgroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmAvailableAlertGroupWithCallback(request *DescribeGtmAvailableAlertGroupRequest, callback func(response *DescribeGtmAvailableAlertGroupResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmAvailableAlertGroupResponse + var err error + defer close(result) + response, err = client.DescribeGtmAvailableAlertGroup(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmAvailableAlertGroupRequest is the request struct for api DescribeGtmAvailableAlertGroup +type DescribeGtmAvailableAlertGroupRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmAvailableAlertGroupResponse is the response struct for api DescribeGtmAvailableAlertGroup +type DescribeGtmAvailableAlertGroupResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + AvailableAlertGroup string `json:"AvailableAlertGroup" xml:"AvailableAlertGroup"` +} + +// CreateDescribeGtmAvailableAlertGroupRequest creates a request to invoke DescribeGtmAvailableAlertGroup API +func CreateDescribeGtmAvailableAlertGroupRequest() (request *DescribeGtmAvailableAlertGroupRequest) { + request = &DescribeGtmAvailableAlertGroupRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmAvailableAlertGroup", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmAvailableAlertGroupResponse creates a response to parse from DescribeGtmAvailableAlertGroup response +func CreateDescribeGtmAvailableAlertGroupResponse() (response *DescribeGtmAvailableAlertGroupResponse) { + response = &DescribeGtmAvailableAlertGroupResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance.go new file mode 100644 index 000000000..faa7663ca --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance.go @@ -0,0 +1,118 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmInstance invokes the alidns.DescribeGtmInstance API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstance.html +func (client *Client) DescribeGtmInstance(request *DescribeGtmInstanceRequest) (response *DescribeGtmInstanceResponse, err error) { + response = CreateDescribeGtmInstanceResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmInstanceWithChan invokes the alidns.DescribeGtmInstance API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstance.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceWithChan(request *DescribeGtmInstanceRequest) (<-chan *DescribeGtmInstanceResponse, <-chan error) { + responseChan := make(chan *DescribeGtmInstanceResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmInstance(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmInstanceWithCallback invokes the alidns.DescribeGtmInstance API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstance.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceWithCallback(request *DescribeGtmInstanceRequest, callback func(response *DescribeGtmInstanceResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmInstanceResponse + var err error + defer close(result) + response, err = client.DescribeGtmInstance(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmInstanceRequest is the request struct for api DescribeGtmInstance +type DescribeGtmInstanceRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmInstanceResponse is the response struct for api DescribeGtmInstance +type DescribeGtmInstanceResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + InstanceId string `json:"InstanceId" xml:"InstanceId"` + InstanceName string `json:"InstanceName" xml:"InstanceName"` + VersionCode string `json:"VersionCode" xml:"VersionCode"` + ExpireTime string `json:"ExpireTime" xml:"ExpireTime"` + ExpireTimestamp int64 `json:"ExpireTimestamp" xml:"ExpireTimestamp"` + Cname string `json:"Cname" xml:"Cname"` + UserDomainName string `json:"UserDomainName" xml:"UserDomainName"` + Ttl int `json:"Ttl" xml:"Ttl"` + LbaStrategy string `json:"LbaStrategy" xml:"LbaStrategy"` + CreateTime string `json:"CreateTime" xml:"CreateTime"` + CreateTimestamp int64 `json:"CreateTimestamp" xml:"CreateTimestamp"` + AlertGroup string `json:"AlertGroup" xml:"AlertGroup"` + CnameMode string `json:"CnameMode" xml:"CnameMode"` +} + +// CreateDescribeGtmInstanceRequest creates a request to invoke DescribeGtmInstance API +func CreateDescribeGtmInstanceRequest() (request *DescribeGtmInstanceRequest) { + request = &DescribeGtmInstanceRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmInstance", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmInstanceResponse creates a response to parse from DescribeGtmInstance response +func CreateDescribeGtmInstanceResponse() (response *DescribeGtmInstanceResponse) { + response = &DescribeGtmInstanceResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_address_pool.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_address_pool.go new file mode 100644 index 000000000..fc518b6d8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_address_pool.go @@ -0,0 +1,118 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmInstanceAddressPool invokes the alidns.DescribeGtmInstanceAddressPool API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstanceaddresspool.html +func (client *Client) DescribeGtmInstanceAddressPool(request *DescribeGtmInstanceAddressPoolRequest) (response *DescribeGtmInstanceAddressPoolResponse, err error) { + response = CreateDescribeGtmInstanceAddressPoolResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmInstanceAddressPoolWithChan invokes the alidns.DescribeGtmInstanceAddressPool API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstanceaddresspool.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceAddressPoolWithChan(request *DescribeGtmInstanceAddressPoolRequest) (<-chan *DescribeGtmInstanceAddressPoolResponse, <-chan error) { + responseChan := make(chan *DescribeGtmInstanceAddressPoolResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmInstanceAddressPool(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmInstanceAddressPoolWithCallback invokes the alidns.DescribeGtmInstanceAddressPool API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstanceaddresspool.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceAddressPoolWithCallback(request *DescribeGtmInstanceAddressPoolRequest, callback func(response *DescribeGtmInstanceAddressPoolResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmInstanceAddressPoolResponse + var err error + defer close(result) + response, err = client.DescribeGtmInstanceAddressPool(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmInstanceAddressPoolRequest is the request struct for api DescribeGtmInstanceAddressPool +type DescribeGtmInstanceAddressPoolRequest struct { + *requests.RpcRequest + AddrPoolId string `position:"Query" name:"AddrPoolId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmInstanceAddressPoolResponse is the response struct for api DescribeGtmInstanceAddressPool +type DescribeGtmInstanceAddressPoolResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + AddrPoolId string `json:"AddrPoolId" xml:"AddrPoolId"` + CreateTime string `json:"CreateTime" xml:"CreateTime"` + CreateTimestamp int64 `json:"CreateTimestamp" xml:"CreateTimestamp"` + UpdateTime string `json:"UpdateTime" xml:"UpdateTime"` + UpdateTimestamp int64 `json:"UpdateTimestamp" xml:"UpdateTimestamp"` + AddrCount int `json:"AddrCount" xml:"AddrCount"` + MinAvailableAddrNum int `json:"MinAvailableAddrNum" xml:"MinAvailableAddrNum"` + MonitorConfigId string `json:"MonitorConfigId" xml:"MonitorConfigId"` + MonitorStatus string `json:"MonitorStatus" xml:"MonitorStatus"` + Name string `json:"Name" xml:"Name"` + Status string `json:"Status" xml:"Status"` + Type string `json:"Type" xml:"Type"` + Addrs Addrs `json:"Addrs" xml:"Addrs"` +} + +// CreateDescribeGtmInstanceAddressPoolRequest creates a request to invoke DescribeGtmInstanceAddressPool API +func CreateDescribeGtmInstanceAddressPoolRequest() (request *DescribeGtmInstanceAddressPoolRequest) { + request = &DescribeGtmInstanceAddressPoolRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmInstanceAddressPool", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmInstanceAddressPoolResponse creates a response to parse from DescribeGtmInstanceAddressPool response +func CreateDescribeGtmInstanceAddressPoolResponse() (response *DescribeGtmInstanceAddressPoolResponse) { + response = &DescribeGtmInstanceAddressPoolResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_address_pools.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_address_pools.go new file mode 100644 index 000000000..0bc65ed8c --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_address_pools.go @@ -0,0 +1,112 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmInstanceAddressPools invokes the alidns.DescribeGtmInstanceAddressPools API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstanceaddresspools.html +func (client *Client) DescribeGtmInstanceAddressPools(request *DescribeGtmInstanceAddressPoolsRequest) (response *DescribeGtmInstanceAddressPoolsResponse, err error) { + response = CreateDescribeGtmInstanceAddressPoolsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmInstanceAddressPoolsWithChan invokes the alidns.DescribeGtmInstanceAddressPools API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstanceaddresspools.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceAddressPoolsWithChan(request *DescribeGtmInstanceAddressPoolsRequest) (<-chan *DescribeGtmInstanceAddressPoolsResponse, <-chan error) { + responseChan := make(chan *DescribeGtmInstanceAddressPoolsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmInstanceAddressPools(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmInstanceAddressPoolsWithCallback invokes the alidns.DescribeGtmInstanceAddressPools API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstanceaddresspools.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceAddressPoolsWithCallback(request *DescribeGtmInstanceAddressPoolsRequest, callback func(response *DescribeGtmInstanceAddressPoolsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmInstanceAddressPoolsResponse + var err error + defer close(result) + response, err = client.DescribeGtmInstanceAddressPools(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmInstanceAddressPoolsRequest is the request struct for api DescribeGtmInstanceAddressPools +type DescribeGtmInstanceAddressPoolsRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeGtmInstanceAddressPoolsResponse is the response struct for api DescribeGtmInstanceAddressPools +type DescribeGtmInstanceAddressPoolsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalItems int `json:"TotalItems" xml:"TotalItems"` + TotalPages int `json:"TotalPages" xml:"TotalPages"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + PageSize int `json:"PageSize" xml:"PageSize"` + AddrPools AddrPoolsInDescribeGtmInstanceAddressPools `json:"AddrPools" xml:"AddrPools"` +} + +// CreateDescribeGtmInstanceAddressPoolsRequest creates a request to invoke DescribeGtmInstanceAddressPools API +func CreateDescribeGtmInstanceAddressPoolsRequest() (request *DescribeGtmInstanceAddressPoolsRequest) { + request = &DescribeGtmInstanceAddressPoolsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmInstanceAddressPools", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmInstanceAddressPoolsResponse creates a response to parse from DescribeGtmInstanceAddressPools response +func CreateDescribeGtmInstanceAddressPoolsResponse() (response *DescribeGtmInstanceAddressPoolsResponse) { + response = &DescribeGtmInstanceAddressPoolsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_status.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_status.go new file mode 100644 index 000000000..f65b578b5 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_status.go @@ -0,0 +1,107 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmInstanceStatus invokes the alidns.DescribeGtmInstanceStatus API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstancestatus.html +func (client *Client) DescribeGtmInstanceStatus(request *DescribeGtmInstanceStatusRequest) (response *DescribeGtmInstanceStatusResponse, err error) { + response = CreateDescribeGtmInstanceStatusResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmInstanceStatusWithChan invokes the alidns.DescribeGtmInstanceStatus API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstancestatus.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceStatusWithChan(request *DescribeGtmInstanceStatusRequest) (<-chan *DescribeGtmInstanceStatusResponse, <-chan error) { + responseChan := make(chan *DescribeGtmInstanceStatusResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmInstanceStatus(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmInstanceStatusWithCallback invokes the alidns.DescribeGtmInstanceStatus API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstancestatus.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceStatusWithCallback(request *DescribeGtmInstanceStatusRequest, callback func(response *DescribeGtmInstanceStatusResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmInstanceStatusResponse + var err error + defer close(result) + response, err = client.DescribeGtmInstanceStatus(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmInstanceStatusRequest is the request struct for api DescribeGtmInstanceStatus +type DescribeGtmInstanceStatusRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmInstanceStatusResponse is the response struct for api DescribeGtmInstanceStatus +type DescribeGtmInstanceStatusResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + AccessStatus string `json:"AccessStatus" xml:"AccessStatus"` + AlertStatus string `json:"AlertStatus" xml:"AlertStatus"` +} + +// CreateDescribeGtmInstanceStatusRequest creates a request to invoke DescribeGtmInstanceStatus API +func CreateDescribeGtmInstanceStatusRequest() (request *DescribeGtmInstanceStatusRequest) { + request = &DescribeGtmInstanceStatusRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmInstanceStatus", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmInstanceStatusResponse creates a response to parse from DescribeGtmInstanceStatus response +func CreateDescribeGtmInstanceStatusResponse() (response *DescribeGtmInstanceStatusResponse) { + response = &DescribeGtmInstanceStatusResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_system_cname.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_system_cname.go new file mode 100644 index 000000000..e94512809 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instance_system_cname.go @@ -0,0 +1,106 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmInstanceSystemCname invokes the alidns.DescribeGtmInstanceSystemCname API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstancesystemcname.html +func (client *Client) DescribeGtmInstanceSystemCname(request *DescribeGtmInstanceSystemCnameRequest) (response *DescribeGtmInstanceSystemCnameResponse, err error) { + response = CreateDescribeGtmInstanceSystemCnameResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmInstanceSystemCnameWithChan invokes the alidns.DescribeGtmInstanceSystemCname API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstancesystemcname.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceSystemCnameWithChan(request *DescribeGtmInstanceSystemCnameRequest) (<-chan *DescribeGtmInstanceSystemCnameResponse, <-chan error) { + responseChan := make(chan *DescribeGtmInstanceSystemCnameResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmInstanceSystemCname(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmInstanceSystemCnameWithCallback invokes the alidns.DescribeGtmInstanceSystemCname API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstancesystemcname.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstanceSystemCnameWithCallback(request *DescribeGtmInstanceSystemCnameRequest, callback func(response *DescribeGtmInstanceSystemCnameResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmInstanceSystemCnameResponse + var err error + defer close(result) + response, err = client.DescribeGtmInstanceSystemCname(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmInstanceSystemCnameRequest is the request struct for api DescribeGtmInstanceSystemCname +type DescribeGtmInstanceSystemCnameRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmInstanceSystemCnameResponse is the response struct for api DescribeGtmInstanceSystemCname +type DescribeGtmInstanceSystemCnameResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + SystemCname string `json:"SystemCname" xml:"SystemCname"` +} + +// CreateDescribeGtmInstanceSystemCnameRequest creates a request to invoke DescribeGtmInstanceSystemCname API +func CreateDescribeGtmInstanceSystemCnameRequest() (request *DescribeGtmInstanceSystemCnameRequest) { + request = &DescribeGtmInstanceSystemCnameRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmInstanceSystemCname", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmInstanceSystemCnameResponse creates a response to parse from DescribeGtmInstanceSystemCname response +func CreateDescribeGtmInstanceSystemCnameResponse() (response *DescribeGtmInstanceSystemCnameResponse) { + response = &DescribeGtmInstanceSystemCnameResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instances.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instances.go new file mode 100644 index 000000000..8ac4c101d --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_instances.go @@ -0,0 +1,113 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmInstances invokes the alidns.DescribeGtmInstances API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstances.html +func (client *Client) DescribeGtmInstances(request *DescribeGtmInstancesRequest) (response *DescribeGtmInstancesResponse, err error) { + response = CreateDescribeGtmInstancesResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmInstancesWithChan invokes the alidns.DescribeGtmInstances API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstances.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstancesWithChan(request *DescribeGtmInstancesRequest) (<-chan *DescribeGtmInstancesResponse, <-chan error) { + responseChan := make(chan *DescribeGtmInstancesResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmInstances(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmInstancesWithCallback invokes the alidns.DescribeGtmInstances API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtminstances.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmInstancesWithCallback(request *DescribeGtmInstancesRequest, callback func(response *DescribeGtmInstancesResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmInstancesResponse + var err error + defer close(result) + response, err = client.DescribeGtmInstances(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmInstancesRequest is the request struct for api DescribeGtmInstances +type DescribeGtmInstancesRequest struct { + *requests.RpcRequest + ResourceGroupId string `position:"Query" name:"ResourceGroupId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + Keyword string `position:"Query" name:"Keyword"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeGtmInstancesResponse is the response struct for api DescribeGtmInstances +type DescribeGtmInstancesResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + PageSize int `json:"PageSize" xml:"PageSize"` + TotalItems int `json:"TotalItems" xml:"TotalItems"` + TotalPages int `json:"TotalPages" xml:"TotalPages"` + GtmInstances GtmInstances `json:"GtmInstances" xml:"GtmInstances"` +} + +// CreateDescribeGtmInstancesRequest creates a request to invoke DescribeGtmInstances API +func CreateDescribeGtmInstancesRequest() (request *DescribeGtmInstancesRequest) { + request = &DescribeGtmInstancesRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmInstances", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmInstancesResponse creates a response to parse from DescribeGtmInstances response +func CreateDescribeGtmInstancesResponse() (response *DescribeGtmInstancesResponse) { + response = &DescribeGtmInstancesResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_logs.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_logs.go new file mode 100644 index 000000000..51452503d --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_logs.go @@ -0,0 +1,115 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmLogs invokes the alidns.DescribeGtmLogs API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtmlogs.html +func (client *Client) DescribeGtmLogs(request *DescribeGtmLogsRequest) (response *DescribeGtmLogsResponse, err error) { + response = CreateDescribeGtmLogsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmLogsWithChan invokes the alidns.DescribeGtmLogs API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmlogs.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmLogsWithChan(request *DescribeGtmLogsRequest) (<-chan *DescribeGtmLogsResponse, <-chan error) { + responseChan := make(chan *DescribeGtmLogsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmLogs(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmLogsWithCallback invokes the alidns.DescribeGtmLogs API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmlogs.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmLogsWithCallback(request *DescribeGtmLogsRequest, callback func(response *DescribeGtmLogsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmLogsResponse + var err error + defer close(result) + response, err = client.DescribeGtmLogs(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmLogsRequest is the request struct for api DescribeGtmLogs +type DescribeGtmLogsRequest struct { + *requests.RpcRequest + InstanceId string `position:"Query" name:"InstanceId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + Keyword string `position:"Query" name:"Keyword"` + StartTimestamp requests.Integer `position:"Query" name:"StartTimestamp"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` + EndTimestamp requests.Integer `position:"Query" name:"EndTimestamp"` +} + +// DescribeGtmLogsResponse is the response struct for api DescribeGtmLogs +type DescribeGtmLogsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalItems int `json:"TotalItems" xml:"TotalItems"` + TotalPages int `json:"TotalPages" xml:"TotalPages"` + PageSize int `json:"PageSize" xml:"PageSize"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + Logs Logs `json:"Logs" xml:"Logs"` +} + +// CreateDescribeGtmLogsRequest creates a request to invoke DescribeGtmLogs API +func CreateDescribeGtmLogsRequest() (request *DescribeGtmLogsRequest) { + request = &DescribeGtmLogsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmLogs", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmLogsResponse creates a response to parse from DescribeGtmLogs response +func CreateDescribeGtmLogsResponse() (response *DescribeGtmLogsResponse) { + response = &DescribeGtmLogsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_monitor_available_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_monitor_available_config.go new file mode 100644 index 000000000..1e36ed259 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_monitor_available_config.go @@ -0,0 +1,105 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmMonitorAvailableConfig invokes the alidns.DescribeGtmMonitorAvailableConfig API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtmmonitoravailableconfig.html +func (client *Client) DescribeGtmMonitorAvailableConfig(request *DescribeGtmMonitorAvailableConfigRequest) (response *DescribeGtmMonitorAvailableConfigResponse, err error) { + response = CreateDescribeGtmMonitorAvailableConfigResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmMonitorAvailableConfigWithChan invokes the alidns.DescribeGtmMonitorAvailableConfig API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmmonitoravailableconfig.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmMonitorAvailableConfigWithChan(request *DescribeGtmMonitorAvailableConfigRequest) (<-chan *DescribeGtmMonitorAvailableConfigResponse, <-chan error) { + responseChan := make(chan *DescribeGtmMonitorAvailableConfigResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmMonitorAvailableConfig(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmMonitorAvailableConfigWithCallback invokes the alidns.DescribeGtmMonitorAvailableConfig API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmmonitoravailableconfig.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmMonitorAvailableConfigWithCallback(request *DescribeGtmMonitorAvailableConfigRequest, callback func(response *DescribeGtmMonitorAvailableConfigResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmMonitorAvailableConfigResponse + var err error + defer close(result) + response, err = client.DescribeGtmMonitorAvailableConfig(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmMonitorAvailableConfigRequest is the request struct for api DescribeGtmMonitorAvailableConfig +type DescribeGtmMonitorAvailableConfigRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmMonitorAvailableConfigResponse is the response struct for api DescribeGtmMonitorAvailableConfig +type DescribeGtmMonitorAvailableConfigResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + IspCityNodes IspCityNodesInDescribeGtmMonitorAvailableConfig `json:"IspCityNodes" xml:"IspCityNodes"` +} + +// CreateDescribeGtmMonitorAvailableConfigRequest creates a request to invoke DescribeGtmMonitorAvailableConfig API +func CreateDescribeGtmMonitorAvailableConfigRequest() (request *DescribeGtmMonitorAvailableConfigRequest) { + request = &DescribeGtmMonitorAvailableConfigRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmMonitorAvailableConfig", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmMonitorAvailableConfigResponse creates a response to parse from DescribeGtmMonitorAvailableConfig response +func CreateDescribeGtmMonitorAvailableConfigResponse() (response *DescribeGtmMonitorAvailableConfigResponse) { + response = &DescribeGtmMonitorAvailableConfigResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_monitor_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_monitor_config.go new file mode 100644 index 000000000..0455ed8b9 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_gtm_monitor_config.go @@ -0,0 +1,117 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeGtmMonitorConfig invokes the alidns.DescribeGtmMonitorConfig API synchronously +// api document: https://help.aliyun.com/api/alidns/describegtmmonitorconfig.html +func (client *Client) DescribeGtmMonitorConfig(request *DescribeGtmMonitorConfigRequest) (response *DescribeGtmMonitorConfigResponse, err error) { + response = CreateDescribeGtmMonitorConfigResponse() + err = client.DoAction(request, response) + return +} + +// DescribeGtmMonitorConfigWithChan invokes the alidns.DescribeGtmMonitorConfig API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmmonitorconfig.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmMonitorConfigWithChan(request *DescribeGtmMonitorConfigRequest) (<-chan *DescribeGtmMonitorConfigResponse, <-chan error) { + responseChan := make(chan *DescribeGtmMonitorConfigResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeGtmMonitorConfig(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeGtmMonitorConfigWithCallback invokes the alidns.DescribeGtmMonitorConfig API asynchronously +// api document: https://help.aliyun.com/api/alidns/describegtmmonitorconfig.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeGtmMonitorConfigWithCallback(request *DescribeGtmMonitorConfigRequest, callback func(response *DescribeGtmMonitorConfigResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeGtmMonitorConfigResponse + var err error + defer close(result) + response, err = client.DescribeGtmMonitorConfig(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeGtmMonitorConfigRequest is the request struct for api DescribeGtmMonitorConfig +type DescribeGtmMonitorConfigRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + MonitorConfigId string `position:"Query" name:"MonitorConfigId"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeGtmMonitorConfigResponse is the response struct for api DescribeGtmMonitorConfig +type DescribeGtmMonitorConfigResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + MonitorConfigId string `json:"MonitorConfigId" xml:"MonitorConfigId"` + CreateTime string `json:"CreateTime" xml:"CreateTime"` + CreateTimestamp int64 `json:"CreateTimestamp" xml:"CreateTimestamp"` + UpdateTime string `json:"UpdateTime" xml:"UpdateTime"` + UpdateTimestamp int64 `json:"UpdateTimestamp" xml:"UpdateTimestamp"` + Name string `json:"Name" xml:"Name"` + ProtocolType string `json:"ProtocolType" xml:"ProtocolType"` + Interval int `json:"Interval" xml:"Interval"` + EvaluationCount int `json:"EvaluationCount" xml:"EvaluationCount"` + Timeout int `json:"Timeout" xml:"Timeout"` + MonitorExtendInfo string `json:"MonitorExtendInfo" xml:"MonitorExtendInfo"` + IspCityNodes IspCityNodesInDescribeGtmMonitorConfig `json:"IspCityNodes" xml:"IspCityNodes"` +} + +// CreateDescribeGtmMonitorConfigRequest creates a request to invoke DescribeGtmMonitorConfig API +func CreateDescribeGtmMonitorConfigRequest() (request *DescribeGtmMonitorConfigRequest) { + request = &DescribeGtmMonitorConfigRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeGtmMonitorConfig", "Alidns", "openAPI") + return +} + +// CreateDescribeGtmMonitorConfigResponse creates a response to parse from DescribeGtmMonitorConfig response +func CreateDescribeGtmMonitorConfigResponse() (response *DescribeGtmMonitorConfigResponse) { + response = &DescribeGtmMonitorConfigResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_logs.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_logs.go new file mode 100644 index 000000000..316715917 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_logs.go @@ -0,0 +1,114 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeRecordLogs invokes the alidns.DescribeRecordLogs API synchronously +// api document: https://help.aliyun.com/api/alidns/describerecordlogs.html +func (client *Client) DescribeRecordLogs(request *DescribeRecordLogsRequest) (response *DescribeRecordLogsResponse, err error) { + response = CreateDescribeRecordLogsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeRecordLogsWithChan invokes the alidns.DescribeRecordLogs API asynchronously +// api document: https://help.aliyun.com/api/alidns/describerecordlogs.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRecordLogsWithChan(request *DescribeRecordLogsRequest) (<-chan *DescribeRecordLogsResponse, <-chan error) { + responseChan := make(chan *DescribeRecordLogsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeRecordLogs(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeRecordLogsWithCallback invokes the alidns.DescribeRecordLogs API asynchronously +// api document: https://help.aliyun.com/api/alidns/describerecordlogs.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRecordLogsWithCallback(request *DescribeRecordLogsRequest, callback func(response *DescribeRecordLogsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeRecordLogsResponse + var err error + defer close(result) + response, err = client.DescribeRecordLogs(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeRecordLogsRequest is the request struct for api DescribeRecordLogs +type DescribeRecordLogsRequest struct { + *requests.RpcRequest + EndDate string `position:"Query" name:"endDate"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + Lang string `position:"Query" name:"Lang"` + KeyWord string `position:"Query" name:"KeyWord"` + StartDate string `position:"Query" name:"StartDate"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeRecordLogsResponse is the response struct for api DescribeRecordLogs +type DescribeRecordLogsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + RecordLogs RecordLogs `json:"RecordLogs" xml:"RecordLogs"` +} + +// CreateDescribeRecordLogsRequest creates a request to invoke DescribeRecordLogs API +func CreateDescribeRecordLogsRequest() (request *DescribeRecordLogsRequest) { + request = &DescribeRecordLogsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeRecordLogs", "Alidns", "openAPI") + return +} + +// CreateDescribeRecordLogsResponse creates a response to parse from DescribeRecordLogs response +func CreateDescribeRecordLogsResponse() (response *DescribeRecordLogsResponse) { + response = &DescribeRecordLogsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics.go new file mode 100644 index 000000000..63173f006 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics.go @@ -0,0 +1,109 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeRecordStatistics invokes the alidns.DescribeRecordStatistics API synchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatistics.html +func (client *Client) DescribeRecordStatistics(request *DescribeRecordStatisticsRequest) (response *DescribeRecordStatisticsResponse, err error) { + response = CreateDescribeRecordStatisticsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeRecordStatisticsWithChan invokes the alidns.DescribeRecordStatistics API asynchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatistics.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRecordStatisticsWithChan(request *DescribeRecordStatisticsRequest) (<-chan *DescribeRecordStatisticsResponse, <-chan error) { + responseChan := make(chan *DescribeRecordStatisticsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeRecordStatistics(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeRecordStatisticsWithCallback invokes the alidns.DescribeRecordStatistics API asynchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatistics.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRecordStatisticsWithCallback(request *DescribeRecordStatisticsRequest, callback func(response *DescribeRecordStatisticsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeRecordStatisticsResponse + var err error + defer close(result) + response, err = client.DescribeRecordStatistics(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeRecordStatisticsRequest is the request struct for api DescribeRecordStatistics +type DescribeRecordStatisticsRequest struct { + *requests.RpcRequest + Rr string `position:"Query" name:"Rr"` + EndDate string `position:"Query" name:"EndDate"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + StartDate string `position:"Query" name:"StartDate"` +} + +// DescribeRecordStatisticsResponse is the response struct for api DescribeRecordStatistics +type DescribeRecordStatisticsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + Statistics StatisticsInDescribeRecordStatistics `json:"Statistics" xml:"Statistics"` +} + +// CreateDescribeRecordStatisticsRequest creates a request to invoke DescribeRecordStatistics API +func CreateDescribeRecordStatisticsRequest() (request *DescribeRecordStatisticsRequest) { + request = &DescribeRecordStatisticsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeRecordStatistics", "Alidns", "openAPI") + return +} + +// CreateDescribeRecordStatisticsResponse creates a response to parse from DescribeRecordStatistics response +func CreateDescribeRecordStatisticsResponse() (response *DescribeRecordStatisticsResponse) { + response = &DescribeRecordStatisticsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics_history.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics_history.go new file mode 100644 index 000000000..505449326 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics_history.go @@ -0,0 +1,109 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeRecordStatisticsHistory invokes the alidns.DescribeRecordStatisticsHistory API synchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatisticshistory.html +func (client *Client) DescribeRecordStatisticsHistory(request *DescribeRecordStatisticsHistoryRequest) (response *DescribeRecordStatisticsHistoryResponse, err error) { + response = CreateDescribeRecordStatisticsHistoryResponse() + err = client.DoAction(request, response) + return +} + +// DescribeRecordStatisticsHistoryWithChan invokes the alidns.DescribeRecordStatisticsHistory API asynchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatisticshistory.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRecordStatisticsHistoryWithChan(request *DescribeRecordStatisticsHistoryRequest) (<-chan *DescribeRecordStatisticsHistoryResponse, <-chan error) { + responseChan := make(chan *DescribeRecordStatisticsHistoryResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeRecordStatisticsHistory(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeRecordStatisticsHistoryWithCallback invokes the alidns.DescribeRecordStatisticsHistory API asynchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatisticshistory.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRecordStatisticsHistoryWithCallback(request *DescribeRecordStatisticsHistoryRequest, callback func(response *DescribeRecordStatisticsHistoryResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeRecordStatisticsHistoryResponse + var err error + defer close(result) + response, err = client.DescribeRecordStatisticsHistory(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeRecordStatisticsHistoryRequest is the request struct for api DescribeRecordStatisticsHistory +type DescribeRecordStatisticsHistoryRequest struct { + *requests.RpcRequest + Rr string `position:"Query" name:"Rr"` + EndDate string `position:"Query" name:"EndDate"` + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` + StartDate string `position:"Query" name:"StartDate"` +} + +// DescribeRecordStatisticsHistoryResponse is the response struct for api DescribeRecordStatisticsHistory +type DescribeRecordStatisticsHistoryResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + Statistics StatisticsInDescribeRecordStatisticsHistory `json:"Statistics" xml:"Statistics"` +} + +// CreateDescribeRecordStatisticsHistoryRequest creates a request to invoke DescribeRecordStatisticsHistory API +func CreateDescribeRecordStatisticsHistoryRequest() (request *DescribeRecordStatisticsHistoryRequest) { + request = &DescribeRecordStatisticsHistoryRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeRecordStatisticsHistory", "Alidns", "openAPI") + return +} + +// CreateDescribeRecordStatisticsHistoryResponse creates a response to parse from DescribeRecordStatisticsHistory response +func CreateDescribeRecordStatisticsHistoryResponse() (response *DescribeRecordStatisticsHistoryResponse) { + response = &DescribeRecordStatisticsHistoryResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics_summary.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics_summary.go new file mode 100644 index 000000000..c7e814437 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_record_statistics_summary.go @@ -0,0 +1,119 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeRecordStatisticsSummary invokes the alidns.DescribeRecordStatisticsSummary API synchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatisticssummary.html +func (client *Client) DescribeRecordStatisticsSummary(request *DescribeRecordStatisticsSummaryRequest) (response *DescribeRecordStatisticsSummaryResponse, err error) { + response = CreateDescribeRecordStatisticsSummaryResponse() + err = client.DoAction(request, response) + return +} + +// DescribeRecordStatisticsSummaryWithChan invokes the alidns.DescribeRecordStatisticsSummary API asynchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatisticssummary.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRecordStatisticsSummaryWithChan(request *DescribeRecordStatisticsSummaryRequest) (<-chan *DescribeRecordStatisticsSummaryResponse, <-chan error) { + responseChan := make(chan *DescribeRecordStatisticsSummaryResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeRecordStatisticsSummary(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeRecordStatisticsSummaryWithCallback invokes the alidns.DescribeRecordStatisticsSummary API asynchronously +// api document: https://help.aliyun.com/api/alidns/describerecordstatisticssummary.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeRecordStatisticsSummaryWithCallback(request *DescribeRecordStatisticsSummaryRequest, callback func(response *DescribeRecordStatisticsSummaryResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeRecordStatisticsSummaryResponse + var err error + defer close(result) + response, err = client.DescribeRecordStatisticsSummary(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeRecordStatisticsSummaryRequest is the request struct for api DescribeRecordStatisticsSummary +type DescribeRecordStatisticsSummaryRequest struct { + *requests.RpcRequest + EndDate string `position:"Query" name:"EndDate"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + DomainName string `position:"Query" name:"DomainName"` + OrderBy string `position:"Query" name:"OrderBy"` + SearchMode string `position:"Query" name:"SearchMode"` + Threshold requests.Integer `position:"Query" name:"Threshold"` + Lang string `position:"Query" name:"Lang"` + StartDate string `position:"Query" name:"StartDate"` + Keyword string `position:"Query" name:"Keyword"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` + Direction string `position:"Query" name:"Direction"` +} + +// DescribeRecordStatisticsSummaryResponse is the response struct for api DescribeRecordStatisticsSummary +type DescribeRecordStatisticsSummaryResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalItems int `json:"TotalItems" xml:"TotalItems"` + TotalPages int `json:"TotalPages" xml:"TotalPages"` + PageSize int `json:"PageSize" xml:"PageSize"` + PageNumber int `json:"PageNumber" xml:"PageNumber"` + Statistics StatisticsInDescribeRecordStatisticsSummary `json:"Statistics" xml:"Statistics"` +} + +// CreateDescribeRecordStatisticsSummaryRequest creates a request to invoke DescribeRecordStatisticsSummary API +func CreateDescribeRecordStatisticsSummaryRequest() (request *DescribeRecordStatisticsSummaryRequest) { + request = &DescribeRecordStatisticsSummaryRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeRecordStatisticsSummary", "Alidns", "openAPI") + return +} + +// CreateDescribeRecordStatisticsSummaryResponse creates a response to parse from DescribeRecordStatisticsSummary response +func CreateDescribeRecordStatisticsSummaryResponse() (response *DescribeRecordStatisticsSummaryResponse) { + response = &DescribeRecordStatisticsSummaryResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_sub_domain_records.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_sub_domain_records.go new file mode 100644 index 000000000..4e342a46b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_sub_domain_records.go @@ -0,0 +1,113 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeSubDomainRecords invokes the alidns.DescribeSubDomainRecords API synchronously +// api document: https://help.aliyun.com/api/alidns/describesubdomainrecords.html +func (client *Client) DescribeSubDomainRecords(request *DescribeSubDomainRecordsRequest) (response *DescribeSubDomainRecordsResponse, err error) { + response = CreateDescribeSubDomainRecordsResponse() + err = client.DoAction(request, response) + return +} + +// DescribeSubDomainRecordsWithChan invokes the alidns.DescribeSubDomainRecords API asynchronously +// api document: https://help.aliyun.com/api/alidns/describesubdomainrecords.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeSubDomainRecordsWithChan(request *DescribeSubDomainRecordsRequest) (<-chan *DescribeSubDomainRecordsResponse, <-chan error) { + responseChan := make(chan *DescribeSubDomainRecordsResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeSubDomainRecords(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeSubDomainRecordsWithCallback invokes the alidns.DescribeSubDomainRecords API asynchronously +// api document: https://help.aliyun.com/api/alidns/describesubdomainrecords.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeSubDomainRecordsWithCallback(request *DescribeSubDomainRecordsRequest, callback func(response *DescribeSubDomainRecordsResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeSubDomainRecordsResponse + var err error + defer close(result) + response, err = client.DescribeSubDomainRecords(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeSubDomainRecordsRequest is the request struct for api DescribeSubDomainRecords +type DescribeSubDomainRecordsRequest struct { + *requests.RpcRequest + Line string `position:"Query" name:"Line"` + UserClientIp string `position:"Query" name:"UserClientIp"` + PageSize requests.Integer `position:"Query" name:"PageSize"` + SubDomain string `position:"Query" name:"SubDomain"` + Lang string `position:"Query" name:"Lang"` + Type string `position:"Query" name:"Type"` + PageNumber requests.Integer `position:"Query" name:"PageNumber"` +} + +// DescribeSubDomainRecordsResponse is the response struct for api DescribeSubDomainRecords +type DescribeSubDomainRecordsResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TotalCount int64 `json:"TotalCount" xml:"TotalCount"` + PageNumber int64 `json:"PageNumber" xml:"PageNumber"` + PageSize int64 `json:"PageSize" xml:"PageSize"` + DomainRecords DomainRecordsInDescribeSubDomainRecords `json:"DomainRecords" xml:"DomainRecords"` +} + +// CreateDescribeSubDomainRecordsRequest creates a request to invoke DescribeSubDomainRecords API +func CreateDescribeSubDomainRecordsRequest() (request *DescribeSubDomainRecordsRequest) { + request = &DescribeSubDomainRecordsRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeSubDomainRecords", "Alidns", "openAPI") + return +} + +// CreateDescribeSubDomainRecordsResponse creates a response to parse from DescribeSubDomainRecords response +func CreateDescribeSubDomainRecordsResponse() (response *DescribeSubDomainRecordsResponse) { + response = &DescribeSubDomainRecordsResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_support_lines.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_support_lines.go new file mode 100644 index 000000000..00b262151 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/describe_support_lines.go @@ -0,0 +1,106 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// DescribeSupportLines invokes the alidns.DescribeSupportLines API synchronously +// api document: https://help.aliyun.com/api/alidns/describesupportlines.html +func (client *Client) DescribeSupportLines(request *DescribeSupportLinesRequest) (response *DescribeSupportLinesResponse, err error) { + response = CreateDescribeSupportLinesResponse() + err = client.DoAction(request, response) + return +} + +// DescribeSupportLinesWithChan invokes the alidns.DescribeSupportLines API asynchronously +// api document: https://help.aliyun.com/api/alidns/describesupportlines.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeSupportLinesWithChan(request *DescribeSupportLinesRequest) (<-chan *DescribeSupportLinesResponse, <-chan error) { + responseChan := make(chan *DescribeSupportLinesResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.DescribeSupportLines(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// DescribeSupportLinesWithCallback invokes the alidns.DescribeSupportLines API asynchronously +// api document: https://help.aliyun.com/api/alidns/describesupportlines.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) DescribeSupportLinesWithCallback(request *DescribeSupportLinesRequest, callback func(response *DescribeSupportLinesResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *DescribeSupportLinesResponse + var err error + defer close(result) + response, err = client.DescribeSupportLines(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// DescribeSupportLinesRequest is the request struct for api DescribeSupportLines +type DescribeSupportLinesRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` +} + +// DescribeSupportLinesResponse is the response struct for api DescribeSupportLines +type DescribeSupportLinesResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + RecordLines RecordLinesInDescribeSupportLines `json:"RecordLines" xml:"RecordLines"` +} + +// CreateDescribeSupportLinesRequest creates a request to invoke DescribeSupportLines API +func CreateDescribeSupportLinesRequest() (request *DescribeSupportLinesRequest) { + request = &DescribeSupportLinesRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "DescribeSupportLines", "Alidns", "openAPI") + return +} + +// CreateDescribeSupportLinesResponse creates a response to parse from DescribeSupportLines response +func CreateDescribeSupportLinesResponse() (response *DescribeSupportLinesResponse) { + response = &DescribeSupportLinesResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/get_main_domain_name.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/get_main_domain_name.go new file mode 100644 index 000000000..e7ea6658a --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/get_main_domain_name.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// GetMainDomainName invokes the alidns.GetMainDomainName API synchronously +// api document: https://help.aliyun.com/api/alidns/getmaindomainname.html +func (client *Client) GetMainDomainName(request *GetMainDomainNameRequest) (response *GetMainDomainNameResponse, err error) { + response = CreateGetMainDomainNameResponse() + err = client.DoAction(request, response) + return +} + +// GetMainDomainNameWithChan invokes the alidns.GetMainDomainName API asynchronously +// api document: https://help.aliyun.com/api/alidns/getmaindomainname.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) GetMainDomainNameWithChan(request *GetMainDomainNameRequest) (<-chan *GetMainDomainNameResponse, <-chan error) { + responseChan := make(chan *GetMainDomainNameResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.GetMainDomainName(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// GetMainDomainNameWithCallback invokes the alidns.GetMainDomainName API asynchronously +// api document: https://help.aliyun.com/api/alidns/getmaindomainname.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) GetMainDomainNameWithCallback(request *GetMainDomainNameRequest, callback func(response *GetMainDomainNameResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *GetMainDomainNameResponse + var err error + defer close(result) + response, err = client.GetMainDomainName(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// GetMainDomainNameRequest is the request struct for api GetMainDomainName +type GetMainDomainNameRequest struct { + *requests.RpcRequest + InputString string `position:"Query" name:"InputString"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` +} + +// GetMainDomainNameResponse is the response struct for api GetMainDomainName +type GetMainDomainNameResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + DomainName string `json:"DomainName" xml:"DomainName"` + RR string `json:"RR" xml:"RR"` + DomainLevel int64 `json:"DomainLevel" xml:"DomainLevel"` +} + +// CreateGetMainDomainNameRequest creates a request to invoke GetMainDomainName API +func CreateGetMainDomainNameRequest() (request *GetMainDomainNameRequest) { + request = &GetMainDomainNameRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "GetMainDomainName", "Alidns", "openAPI") + return +} + +// CreateGetMainDomainNameResponse creates a response to parse from GetMainDomainName response +func CreateGetMainDomainNameResponse() (response *GetMainDomainNameResponse) { + response = &GetMainDomainNameResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/modify_hichina_domain_dns.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/modify_hichina_domain_dns.go new file mode 100644 index 000000000..1934d3ee1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/modify_hichina_domain_dns.go @@ -0,0 +1,107 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// ModifyHichinaDomainDNS invokes the alidns.ModifyHichinaDomainDNS API synchronously +// api document: https://help.aliyun.com/api/alidns/modifyhichinadomaindns.html +func (client *Client) ModifyHichinaDomainDNS(request *ModifyHichinaDomainDNSRequest) (response *ModifyHichinaDomainDNSResponse, err error) { + response = CreateModifyHichinaDomainDNSResponse() + err = client.DoAction(request, response) + return +} + +// ModifyHichinaDomainDNSWithChan invokes the alidns.ModifyHichinaDomainDNS API asynchronously +// api document: https://help.aliyun.com/api/alidns/modifyhichinadomaindns.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ModifyHichinaDomainDNSWithChan(request *ModifyHichinaDomainDNSRequest) (<-chan *ModifyHichinaDomainDNSResponse, <-chan error) { + responseChan := make(chan *ModifyHichinaDomainDNSResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.ModifyHichinaDomainDNS(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// ModifyHichinaDomainDNSWithCallback invokes the alidns.ModifyHichinaDomainDNS API asynchronously +// api document: https://help.aliyun.com/api/alidns/modifyhichinadomaindns.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) ModifyHichinaDomainDNSWithCallback(request *ModifyHichinaDomainDNSRequest, callback func(response *ModifyHichinaDomainDNSResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *ModifyHichinaDomainDNSResponse + var err error + defer close(result) + response, err = client.ModifyHichinaDomainDNS(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// ModifyHichinaDomainDNSRequest is the request struct for api ModifyHichinaDomainDNS +type ModifyHichinaDomainDNSRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainName string `position:"Query" name:"DomainName"` + Lang string `position:"Query" name:"Lang"` +} + +// ModifyHichinaDomainDNSResponse is the response struct for api ModifyHichinaDomainDNS +type ModifyHichinaDomainDNSResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + OriginalDnsServers OriginalDnsServers `json:"OriginalDnsServers" xml:"OriginalDnsServers"` + NewDnsServers NewDnsServers `json:"NewDnsServers" xml:"NewDnsServers"` +} + +// CreateModifyHichinaDomainDNSRequest creates a request to invoke ModifyHichinaDomainDNS API +func CreateModifyHichinaDomainDNSRequest() (request *ModifyHichinaDomainDNSRequest) { + request = &ModifyHichinaDomainDNSRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "ModifyHichinaDomainDNS", "Alidns", "openAPI") + return +} + +// CreateModifyHichinaDomainDNSResponse creates a response to parse from ModifyHichinaDomainDNS response +func CreateModifyHichinaDomainDNSResponse() (response *ModifyHichinaDomainDNSResponse) { + response = &ModifyHichinaDomainDNSResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/operate_batch_domain.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/operate_batch_domain.go new file mode 100644 index 000000000..7a496fbc8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/operate_batch_domain.go @@ -0,0 +1,121 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// OperateBatchDomain invokes the alidns.OperateBatchDomain API synchronously +// api document: https://help.aliyun.com/api/alidns/operatebatchdomain.html +func (client *Client) OperateBatchDomain(request *OperateBatchDomainRequest) (response *OperateBatchDomainResponse, err error) { + response = CreateOperateBatchDomainResponse() + err = client.DoAction(request, response) + return +} + +// OperateBatchDomainWithChan invokes the alidns.OperateBatchDomain API asynchronously +// api document: https://help.aliyun.com/api/alidns/operatebatchdomain.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) OperateBatchDomainWithChan(request *OperateBatchDomainRequest) (<-chan *OperateBatchDomainResponse, <-chan error) { + responseChan := make(chan *OperateBatchDomainResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.OperateBatchDomain(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// OperateBatchDomainWithCallback invokes the alidns.OperateBatchDomain API asynchronously +// api document: https://help.aliyun.com/api/alidns/operatebatchdomain.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) OperateBatchDomainWithCallback(request *OperateBatchDomainRequest, callback func(response *OperateBatchDomainResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *OperateBatchDomainResponse + var err error + defer close(result) + response, err = client.OperateBatchDomain(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// OperateBatchDomainRequest is the request struct for api OperateBatchDomain +type OperateBatchDomainRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + DomainRecordInfo *[]OperateBatchDomainDomainRecordInfo `position:"Query" name:"DomainRecordInfo" type:"Repeated"` + Lang string `position:"Query" name:"Lang"` + Type string `position:"Query" name:"Type"` +} + +// OperateBatchDomainDomainRecordInfo is a repeated param struct in OperateBatchDomainRequest +type OperateBatchDomainDomainRecordInfo struct { + Rr string `name:"Rr"` + NewType string `name:"NewType"` + NewValue string `name:"NewValue"` + Line string `name:"Line"` + Domain string `name:"Domain"` + Type string `name:"Type"` + Priority string `name:"Priority"` + Value string `name:"Value"` + Ttl string `name:"Ttl"` + NewRr string `name:"NewRr"` +} + +// OperateBatchDomainResponse is the response struct for api OperateBatchDomain +type OperateBatchDomainResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + TaskId int64 `json:"TaskId" xml:"TaskId"` +} + +// CreateOperateBatchDomainRequest creates a request to invoke OperateBatchDomain API +func CreateOperateBatchDomainRequest() (request *OperateBatchDomainRequest) { + request = &OperateBatchDomainRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "OperateBatchDomain", "Alidns", "openAPI") + return +} + +// CreateOperateBatchDomainResponse creates a response to parse from OperateBatchDomain response +func CreateOperateBatchDomainResponse() (response *OperateBatchDomainResponse) { + response = &OperateBatchDomainResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/query_create_instance_price.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/query_create_instance_price.go new file mode 100644 index 000000000..c96be9074 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/query_create_instance_price.go @@ -0,0 +1,112 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// QueryCreateInstancePrice invokes the alidns.QueryCreateInstancePrice API synchronously +// api document: https://help.aliyun.com/api/alidns/querycreateinstanceprice.html +func (client *Client) QueryCreateInstancePrice(request *QueryCreateInstancePriceRequest) (response *QueryCreateInstancePriceResponse, err error) { + response = CreateQueryCreateInstancePriceResponse() + err = client.DoAction(request, response) + return +} + +// QueryCreateInstancePriceWithChan invokes the alidns.QueryCreateInstancePrice API asynchronously +// api document: https://help.aliyun.com/api/alidns/querycreateinstanceprice.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) QueryCreateInstancePriceWithChan(request *QueryCreateInstancePriceRequest) (<-chan *QueryCreateInstancePriceResponse, <-chan error) { + responseChan := make(chan *QueryCreateInstancePriceResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.QueryCreateInstancePrice(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// QueryCreateInstancePriceWithCallback invokes the alidns.QueryCreateInstancePrice API asynchronously +// api document: https://help.aliyun.com/api/alidns/querycreateinstanceprice.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) QueryCreateInstancePriceWithCallback(request *QueryCreateInstancePriceRequest, callback func(response *QueryCreateInstancePriceResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *QueryCreateInstancePriceResponse + var err error + defer close(result) + response, err = client.QueryCreateInstancePrice(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// QueryCreateInstancePriceRequest is the request struct for api QueryCreateInstancePrice +type QueryCreateInstancePriceRequest struct { + *requests.RpcRequest + Month requests.Integer `position:"Query" name:"Month"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` + InstanceVersion string `position:"Query" name:"InstanceVersion"` + OwnerId requests.Integer `position:"Query" name:"OwnerId"` +} + +// QueryCreateInstancePriceResponse is the response struct for api QueryCreateInstancePrice +type QueryCreateInstancePriceResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + Origin string `json:"Origin" xml:"Origin"` + Discount string `json:"Discount" xml:"Discount"` + Amount string `json:"Amount" xml:"Amount"` + Currency string `json:"Currency" xml:"Currency"` + Rules Rules `json:"Rules" xml:"Rules"` +} + +// CreateQueryCreateInstancePriceRequest creates a request to invoke QueryCreateInstancePrice API +func CreateQueryCreateInstancePriceRequest() (request *QueryCreateInstancePriceRequest) { + request = &QueryCreateInstancePriceRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "QueryCreateInstancePrice", "Alidns", "openAPI") + return +} + +// CreateQueryCreateInstancePriceResponse creates a response to parse from QueryCreateInstancePrice response +func CreateQueryCreateInstancePriceResponse() (response *QueryCreateInstancePriceResponse) { + response = &QueryCreateInstancePriceResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_dnsslb_status.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_dnsslb_status.go new file mode 100644 index 000000000..ea212bbc1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_dnsslb_status.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// SetDNSSLBStatus invokes the alidns.SetDNSSLBStatus API synchronously +// api document: https://help.aliyun.com/api/alidns/setdnsslbstatus.html +func (client *Client) SetDNSSLBStatus(request *SetDNSSLBStatusRequest) (response *SetDNSSLBStatusResponse, err error) { + response = CreateSetDNSSLBStatusResponse() + err = client.DoAction(request, response) + return +} + +// SetDNSSLBStatusWithChan invokes the alidns.SetDNSSLBStatus API asynchronously +// api document: https://help.aliyun.com/api/alidns/setdnsslbstatus.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) SetDNSSLBStatusWithChan(request *SetDNSSLBStatusRequest) (<-chan *SetDNSSLBStatusResponse, <-chan error) { + responseChan := make(chan *SetDNSSLBStatusResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.SetDNSSLBStatus(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// SetDNSSLBStatusWithCallback invokes the alidns.SetDNSSLBStatus API asynchronously +// api document: https://help.aliyun.com/api/alidns/setdnsslbstatus.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) SetDNSSLBStatusWithCallback(request *SetDNSSLBStatusRequest, callback func(response *SetDNSSLBStatusResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *SetDNSSLBStatusResponse + var err error + defer close(result) + response, err = client.SetDNSSLBStatus(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// SetDNSSLBStatusRequest is the request struct for api SetDNSSLBStatus +type SetDNSSLBStatusRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + SubDomain string `position:"Query" name:"SubDomain"` + Lang string `position:"Query" name:"Lang"` + Open requests.Boolean `position:"Query" name:"Open"` +} + +// SetDNSSLBStatusResponse is the response struct for api SetDNSSLBStatus +type SetDNSSLBStatusResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + RecordCount int64 `json:"RecordCount" xml:"RecordCount"` + Open bool `json:"Open" xml:"Open"` +} + +// CreateSetDNSSLBStatusRequest creates a request to invoke SetDNSSLBStatus API +func CreateSetDNSSLBStatusRequest() (request *SetDNSSLBStatusRequest) { + request = &SetDNSSLBStatusRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "SetDNSSLBStatus", "Alidns", "openAPI") + return +} + +// CreateSetDNSSLBStatusResponse creates a response to parse from SetDNSSLBStatus response +func CreateSetDNSSLBStatusResponse() (response *SetDNSSLBStatusResponse) { + response = &SetDNSSLBStatusResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_domain_record_status.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_domain_record_status.go new file mode 100644 index 000000000..1dd08dd16 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_domain_record_status.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// SetDomainRecordStatus invokes the alidns.SetDomainRecordStatus API synchronously +// api document: https://help.aliyun.com/api/alidns/setdomainrecordstatus.html +func (client *Client) SetDomainRecordStatus(request *SetDomainRecordStatusRequest) (response *SetDomainRecordStatusResponse, err error) { + response = CreateSetDomainRecordStatusResponse() + err = client.DoAction(request, response) + return +} + +// SetDomainRecordStatusWithChan invokes the alidns.SetDomainRecordStatus API asynchronously +// api document: https://help.aliyun.com/api/alidns/setdomainrecordstatus.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) SetDomainRecordStatusWithChan(request *SetDomainRecordStatusRequest) (<-chan *SetDomainRecordStatusResponse, <-chan error) { + responseChan := make(chan *SetDomainRecordStatusResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.SetDomainRecordStatus(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// SetDomainRecordStatusWithCallback invokes the alidns.SetDomainRecordStatus API asynchronously +// api document: https://help.aliyun.com/api/alidns/setdomainrecordstatus.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) SetDomainRecordStatusWithCallback(request *SetDomainRecordStatusRequest, callback func(response *SetDomainRecordStatusResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *SetDomainRecordStatusResponse + var err error + defer close(result) + response, err = client.SetDomainRecordStatus(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// SetDomainRecordStatusRequest is the request struct for api SetDomainRecordStatus +type SetDomainRecordStatusRequest struct { + *requests.RpcRequest + RecordId string `position:"Query" name:"RecordId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` + Status string `position:"Query" name:"Status"` +} + +// SetDomainRecordStatusResponse is the response struct for api SetDomainRecordStatus +type SetDomainRecordStatusResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + RecordId string `json:"RecordId" xml:"RecordId"` + Status string `json:"Status" xml:"Status"` +} + +// CreateSetDomainRecordStatusRequest creates a request to invoke SetDomainRecordStatus API +func CreateSetDomainRecordStatusRequest() (request *SetDomainRecordStatusRequest) { + request = &SetDomainRecordStatusRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "SetDomainRecordStatus", "Alidns", "openAPI") + return +} + +// CreateSetDomainRecordStatusResponse creates a response to parse from SetDomainRecordStatus response +func CreateSetDomainRecordStatusResponse() (response *SetDomainRecordStatusResponse) { + response = &SetDomainRecordStatusResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_gtm_access_mode.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_gtm_access_mode.go new file mode 100644 index 000000000..f318455a1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_gtm_access_mode.go @@ -0,0 +1,106 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// SetGtmAccessMode invokes the alidns.SetGtmAccessMode API synchronously +// api document: https://help.aliyun.com/api/alidns/setgtmaccessmode.html +func (client *Client) SetGtmAccessMode(request *SetGtmAccessModeRequest) (response *SetGtmAccessModeResponse, err error) { + response = CreateSetGtmAccessModeResponse() + err = client.DoAction(request, response) + return +} + +// SetGtmAccessModeWithChan invokes the alidns.SetGtmAccessMode API asynchronously +// api document: https://help.aliyun.com/api/alidns/setgtmaccessmode.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) SetGtmAccessModeWithChan(request *SetGtmAccessModeRequest) (<-chan *SetGtmAccessModeResponse, <-chan error) { + responseChan := make(chan *SetGtmAccessModeResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.SetGtmAccessMode(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// SetGtmAccessModeWithCallback invokes the alidns.SetGtmAccessMode API asynchronously +// api document: https://help.aliyun.com/api/alidns/setgtmaccessmode.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) SetGtmAccessModeWithCallback(request *SetGtmAccessModeRequest, callback func(response *SetGtmAccessModeResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *SetGtmAccessModeResponse + var err error + defer close(result) + response, err = client.SetGtmAccessMode(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// SetGtmAccessModeRequest is the request struct for api SetGtmAccessMode +type SetGtmAccessModeRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + StrategyId string `position:"Query" name:"StrategyId"` + Lang string `position:"Query" name:"Lang"` + AccessMode string `position:"Query" name:"AccessMode"` +} + +// SetGtmAccessModeResponse is the response struct for api SetGtmAccessMode +type SetGtmAccessModeResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateSetGtmAccessModeRequest creates a request to invoke SetGtmAccessMode API +func CreateSetGtmAccessModeRequest() (request *SetGtmAccessModeRequest) { + request = &SetGtmAccessModeRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "SetGtmAccessMode", "Alidns", "openAPI") + return +} + +// CreateSetGtmAccessModeResponse creates a response to parse from SetGtmAccessMode response +func CreateSetGtmAccessModeResponse() (response *SetGtmAccessModeResponse) { + response = &SetGtmAccessModeResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_gtm_monitor_status.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_gtm_monitor_status.go new file mode 100644 index 000000000..15a86ba70 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/set_gtm_monitor_status.go @@ -0,0 +1,106 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// SetGtmMonitorStatus invokes the alidns.SetGtmMonitorStatus API synchronously +// api document: https://help.aliyun.com/api/alidns/setgtmmonitorstatus.html +func (client *Client) SetGtmMonitorStatus(request *SetGtmMonitorStatusRequest) (response *SetGtmMonitorStatusResponse, err error) { + response = CreateSetGtmMonitorStatusResponse() + err = client.DoAction(request, response) + return +} + +// SetGtmMonitorStatusWithChan invokes the alidns.SetGtmMonitorStatus API asynchronously +// api document: https://help.aliyun.com/api/alidns/setgtmmonitorstatus.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) SetGtmMonitorStatusWithChan(request *SetGtmMonitorStatusRequest) (<-chan *SetGtmMonitorStatusResponse, <-chan error) { + responseChan := make(chan *SetGtmMonitorStatusResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.SetGtmMonitorStatus(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// SetGtmMonitorStatusWithCallback invokes the alidns.SetGtmMonitorStatus API asynchronously +// api document: https://help.aliyun.com/api/alidns/setgtmmonitorstatus.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) SetGtmMonitorStatusWithCallback(request *SetGtmMonitorStatusRequest, callback func(response *SetGtmMonitorStatusResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *SetGtmMonitorStatusResponse + var err error + defer close(result) + response, err = client.SetGtmMonitorStatus(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// SetGtmMonitorStatusRequest is the request struct for api SetGtmMonitorStatus +type SetGtmMonitorStatusRequest struct { + *requests.RpcRequest + UserClientIp string `position:"Query" name:"UserClientIp"` + MonitorConfigId string `position:"Query" name:"MonitorConfigId"` + Lang string `position:"Query" name:"Lang"` + Status string `position:"Query" name:"Status"` +} + +// SetGtmMonitorStatusResponse is the response struct for api SetGtmMonitorStatus +type SetGtmMonitorStatusResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateSetGtmMonitorStatusRequest creates a request to invoke SetGtmMonitorStatus API +func CreateSetGtmMonitorStatusRequest() (request *SetGtmMonitorStatusRequest) { + request = &SetGtmMonitorStatusRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "SetGtmMonitorStatus", "Alidns", "openAPI") + return +} + +// CreateSetGtmMonitorStatusResponse creates a response to parse from SetGtmMonitorStatus response +func CreateSetGtmMonitorStatusResponse() (response *SetGtmMonitorStatusResponse) { + response = &SetGtmMonitorStatusResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr.go new file mode 100644 index 000000000..649662bba --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr.go @@ -0,0 +1,29 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Addr is a nested struct in alidns response +type Addr struct { + AddrId int64 `json:"AddrId" xml:"AddrId"` + CreateTime string `json:"CreateTime" xml:"CreateTime"` + CreateTimestamp int64 `json:"CreateTimestamp" xml:"CreateTimestamp"` + UpdateTime string `json:"UpdateTime" xml:"UpdateTime"` + UpdateTimestamp int64 `json:"UpdateTimestamp" xml:"UpdateTimestamp"` + Value string `json:"Value" xml:"Value"` + LbaWeight int `json:"LbaWeight" xml:"LbaWeight"` + Mode string `json:"Mode" xml:"Mode"` + AlertStatus string `json:"AlertStatus" xml:"AlertStatus"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pool.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pool.go new file mode 100644 index 000000000..185c79ff1 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pool.go @@ -0,0 +1,33 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// AddrPool is a nested struct in alidns response +type AddrPool struct { + AddrCount int `json:"AddrCount" xml:"AddrCount"` + Name string `json:"Name" xml:"Name"` + MinAvailableAddrNum int `json:"MinAvailableAddrNum" xml:"MinAvailableAddrNum"` + UpdateTime string `json:"UpdateTime" xml:"UpdateTime"` + MonitorConfigId string `json:"MonitorConfigId" xml:"MonitorConfigId"` + CreateTimestamp int64 `json:"CreateTimestamp" xml:"CreateTimestamp"` + CreateTime string `json:"CreateTime" xml:"CreateTime"` + AddrPoolName string `json:"AddrPoolName" xml:"AddrPoolName"` + AddrPoolId string `json:"AddrPoolId" xml:"AddrPoolId"` + UpdateTimestamp int64 `json:"UpdateTimestamp" xml:"UpdateTimestamp"` + Status string `json:"Status" xml:"Status"` + MonitorStatus string `json:"MonitorStatus" xml:"MonitorStatus"` + Type string `json:"Type" xml:"Type"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pools_in_describe_gtm_access_strategy_available_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pools_in_describe_gtm_access_strategy_available_config.go new file mode 100644 index 000000000..dddb2fe6e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pools_in_describe_gtm_access_strategy_available_config.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// AddrPoolsInDescribeGtmAccessStrategyAvailableConfig is a nested struct in alidns response +type AddrPoolsInDescribeGtmAccessStrategyAvailableConfig struct { + AddrPool []AddrPool `json:"AddrPool" xml:"AddrPool"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pools_in_describe_gtm_instance_address_pools.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pools_in_describe_gtm_instance_address_pools.go new file mode 100644 index 000000000..2d340d818 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addr_pools_in_describe_gtm_instance_address_pools.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// AddrPoolsInDescribeGtmInstanceAddressPools is a nested struct in alidns response +type AddrPoolsInDescribeGtmInstanceAddressPools struct { + AddrPool []AddrPool `json:"AddrPool" xml:"AddrPool"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addrs.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addrs.go new file mode 100644 index 000000000..66bf0836e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_addrs.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Addrs is a nested struct in alidns response +type Addrs struct { + Addr []Addr `json:"Addr" xml:"Addr"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_available_ttls.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_available_ttls.go new file mode 100644 index 000000000..e1d0ac7d5 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_available_ttls.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// AvailableTtls is a nested struct in alidns response +type AvailableTtls struct { + AvailableTtl []string `json:"AvailableTtl" xml:"AvailableTtl"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_batch_result_detail.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_batch_result_detail.go new file mode 100644 index 000000000..fdad37292 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_batch_result_detail.go @@ -0,0 +1,36 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// BatchResultDetail is a nested struct in alidns response +type BatchResultDetail struct { + Domain string `json:"Domain" xml:"Domain"` + Type string `json:"Type" xml:"Type"` + Rr string `json:"Rr" xml:"Rr"` + Value string `json:"Value" xml:"Value"` + Status bool `json:"Status" xml:"Status"` + Reason string `json:"Reason" xml:"Reason"` + NewRr string `json:"NewRr" xml:"NewRr"` + NewValue string `json:"NewValue" xml:"NewValue"` + BatchType string `json:"BatchType" xml:"BatchType"` + OperateDateStr string `json:"OperateDateStr" xml:"OperateDateStr"` + Line string `json:"Line" xml:"Line"` + Priority string `json:"Priority" xml:"Priority"` + Ttl string `json:"Ttl" xml:"Ttl"` + RecordId string `json:"RecordId" xml:"RecordId"` + Remark string `json:"Remark" xml:"Remark"` + RrStatus string `json:"RrStatus" xml:"RrStatus"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_batch_result_details.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_batch_result_details.go new file mode 100644 index 000000000..b2655d454 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_batch_result_details.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// BatchResultDetails is a nested struct in alidns response +type BatchResultDetails struct { + BatchResultDetail []BatchResultDetail `json:"BatchResultDetail" xml:"BatchResultDetail"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_product.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_product.go new file mode 100644 index 000000000..2f5390f0c --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_product.go @@ -0,0 +1,51 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DnsProduct is a nested struct in alidns response +type DnsProduct struct { + InstanceId string `json:"InstanceId" xml:"InstanceId"` + VersionCode string `json:"VersionCode" xml:"VersionCode"` + VersionName string `json:"VersionName" xml:"VersionName"` + StartTime string `json:"StartTime" xml:"StartTime"` + EndTime string `json:"EndTime" xml:"EndTime"` + StartTimestamp int64 `json:"StartTimestamp" xml:"StartTimestamp"` + EndTimestamp int64 `json:"EndTimestamp" xml:"EndTimestamp"` + Domain string `json:"Domain" xml:"Domain"` + BindCount int64 `json:"BindCount" xml:"BindCount"` + BindUsedCount int64 `json:"BindUsedCount" xml:"BindUsedCount"` + TTLMinValue int64 `json:"TTLMinValue" xml:"TTLMinValue"` + SubDomainLevel int64 `json:"SubDomainLevel" xml:"SubDomainLevel"` + DnsSLBCount int64 `json:"DnsSLBCount" xml:"DnsSLBCount"` + URLForwardCount int64 `json:"URLForwardCount" xml:"URLForwardCount"` + DDosDefendFlow int64 `json:"DDosDefendFlow" xml:"DDosDefendFlow"` + DDosDefendQuery int64 `json:"DDosDefendQuery" xml:"DDosDefendQuery"` + OverseaDDosDefendFlow int64 `json:"OverseaDDosDefendFlow" xml:"OverseaDDosDefendFlow"` + SearchEngineLines string `json:"SearchEngineLines" xml:"SearchEngineLines"` + ISPLines string `json:"ISPLines" xml:"ISPLines"` + ISPRegionLines string `json:"ISPRegionLines" xml:"ISPRegionLines"` + OverseaLine string `json:"OverseaLine" xml:"OverseaLine"` + MonitorNodeCount int64 `json:"MonitorNodeCount" xml:"MonitorNodeCount"` + MonitorFrequency int64 `json:"MonitorFrequency" xml:"MonitorFrequency"` + MonitorTaskCount int64 `json:"MonitorTaskCount" xml:"MonitorTaskCount"` + RegionLines bool `json:"RegionLines" xml:"RegionLines"` + Gslb bool `json:"Gslb" xml:"Gslb"` + InClean bool `json:"InClean" xml:"InClean"` + InBlackHole bool `json:"InBlackHole" xml:"InBlackHole"` + BindDomainCount int64 `json:"BindDomainCount" xml:"BindDomainCount"` + BindDomainUsedCount int64 `json:"BindDomainUsedCount" xml:"BindDomainUsedCount"` + DnsSecurity string `json:"DnsSecurity" xml:"DnsSecurity"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_products.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_products.go new file mode 100644 index 000000000..636a96ff0 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_products.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DnsProducts is a nested struct in alidns response +type DnsProducts struct { + DnsProduct []DnsProduct `json:"DnsProduct" xml:"DnsProduct"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_add_domain.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_add_domain.go new file mode 100644 index 000000000..d6f5bfb2b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_add_domain.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DnsServersInAddDomain is a nested struct in alidns response +type DnsServersInAddDomain struct { + DnsServer []string `json:"DnsServer" xml:"DnsServer"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_dns_product_instance.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_dns_product_instance.go new file mode 100644 index 000000000..64d0db2ff --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_dns_product_instance.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DnsServersInDescribeDnsProductInstance is a nested struct in alidns response +type DnsServersInDescribeDnsProductInstance struct { + DnsServer []string `json:"DnsServer" xml:"DnsServer"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domain_info.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domain_info.go new file mode 100644 index 000000000..debe6483b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domain_info.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DnsServersInDescribeDomainInfo is a nested struct in alidns response +type DnsServersInDescribeDomainInfo struct { + DnsServer []string `json:"DnsServer" xml:"DnsServer"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domain_ns.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domain_ns.go new file mode 100644 index 000000000..67d752ec9 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domain_ns.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DnsServersInDescribeDomainNs is a nested struct in alidns response +type DnsServersInDescribeDomainNs struct { + DnsServer []string `json:"DnsServer" xml:"DnsServer"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domains.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domains.go new file mode 100644 index 000000000..dada40af2 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_dns_servers_in_describe_domains.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DnsServersInDescribeDomains is a nested struct in alidns response +type DnsServersInDescribeDomains struct { + DnsServer []string `json:"DnsServer" xml:"DnsServer"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain.go new file mode 100644 index 000000000..5068d39fa --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain.go @@ -0,0 +1,35 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Domain is a nested struct in alidns response +type Domain struct { + DomainId string `json:"DomainId" xml:"DomainId"` + DomainName string `json:"DomainName" xml:"DomainName"` + PunyCode string `json:"PunyCode" xml:"PunyCode"` + AliDomain bool `json:"AliDomain" xml:"AliDomain"` + RecordCount int64 `json:"RecordCount" xml:"RecordCount"` + RegistrantEmail string `json:"RegistrantEmail" xml:"RegistrantEmail"` + Remark string `json:"Remark" xml:"Remark"` + GroupId string `json:"GroupId" xml:"GroupId"` + GroupName string `json:"GroupName" xml:"GroupName"` + InstanceId string `json:"InstanceId" xml:"InstanceId"` + VersionCode string `json:"VersionCode" xml:"VersionCode"` + VersionName string `json:"VersionName" xml:"VersionName"` + InstanceEndTime string `json:"InstanceEndTime" xml:"InstanceEndTime"` + InstanceExpired bool `json:"InstanceExpired" xml:"InstanceExpired"` + DnsServers DnsServersInDescribeDomains `json:"DnsServers" xml:"DnsServers"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_group.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_group.go new file mode 100644 index 000000000..f0e644aba --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_group.go @@ -0,0 +1,23 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DomainGroup is a nested struct in alidns response +type DomainGroup struct { + GroupId string `json:"GroupId" xml:"GroupId"` + GroupName string `json:"GroupName" xml:"GroupName"` + DomainCount int64 `json:"DomainCount" xml:"DomainCount"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_groups.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_groups.go new file mode 100644 index 000000000..ce193d883 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_groups.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DomainGroups is a nested struct in alidns response +type DomainGroups struct { + DomainGroup []DomainGroup `json:"DomainGroup" xml:"DomainGroup"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_log.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_log.go new file mode 100644 index 000000000..f0bc25354 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_log.go @@ -0,0 +1,27 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DomainLog is a nested struct in alidns response +type DomainLog struct { + ActionTime string `json:"ActionTime" xml:"ActionTime"` + ActionTimestamp int64 `json:"ActionTimestamp" xml:"ActionTimestamp"` + DomainName string `json:"DomainName" xml:"DomainName"` + Action string `json:"Action" xml:"Action"` + Message string `json:"Message" xml:"Message"` + ClientIp string `json:"ClientIp" xml:"ClientIp"` + ZoneId string `json:"ZoneId" xml:"ZoneId"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_logs.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_logs.go new file mode 100644 index 000000000..3964d02b5 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_logs.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DomainLogs is a nested struct in alidns response +type DomainLogs struct { + DomainLog []DomainLog `json:"DomainLog" xml:"DomainLog"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_records_in_describe_domain_records.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_records_in_describe_domain_records.go new file mode 100644 index 000000000..5ef972598 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_records_in_describe_domain_records.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DomainRecordsInDescribeDomainRecords is a nested struct in alidns response +type DomainRecordsInDescribeDomainRecords struct { + Record []Record `json:"Record" xml:"Record"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_records_in_describe_sub_domain_records.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_records_in_describe_sub_domain_records.go new file mode 100644 index 000000000..9b64ba0c8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domain_records_in_describe_sub_domain_records.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// DomainRecordsInDescribeSubDomainRecords is a nested struct in alidns response +type DomainRecordsInDescribeSubDomainRecords struct { + Record []Record `json:"Record" xml:"Record"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domains.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domains.go new file mode 100644 index 000000000..aff37f854 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_domains.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Domains is a nested struct in alidns response +type Domains struct { + Domain []Domain `json:"Domain" xml:"Domain"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_expect_dns_servers.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_expect_dns_servers.go new file mode 100644 index 000000000..9befd95b8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_expect_dns_servers.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// ExpectDnsServers is a nested struct in alidns response +type ExpectDnsServers struct { + ExpectDnsServer []string `json:"ExpectDnsServer" xml:"ExpectDnsServer"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_gtm_instance.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_gtm_instance.go new file mode 100644 index 000000000..8ba998c10 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_gtm_instance.go @@ -0,0 +1,33 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// GtmInstance is a nested struct in alidns response +type GtmInstance struct { + InstanceId string `json:"InstanceId" xml:"InstanceId"` + InstanceName string `json:"InstanceName" xml:"InstanceName"` + Cname string `json:"Cname" xml:"Cname"` + UserDomainName string `json:"UserDomainName" xml:"UserDomainName"` + VersionCode string `json:"VersionCode" xml:"VersionCode"` + Ttl int `json:"Ttl" xml:"Ttl"` + LbaStrategy string `json:"LbaStrategy" xml:"LbaStrategy"` + CreateTime string `json:"CreateTime" xml:"CreateTime"` + CreateTimestamp int64 `json:"CreateTimestamp" xml:"CreateTimestamp"` + ExpireTime string `json:"ExpireTime" xml:"ExpireTime"` + ExpireTimestamp int64 `json:"ExpireTimestamp" xml:"ExpireTimestamp"` + AlertGroup string `json:"AlertGroup" xml:"AlertGroup"` + CnameMode string `json:"CnameMode" xml:"CnameMode"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_gtm_instances.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_gtm_instances.go new file mode 100644 index 000000000..0609ce251 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_gtm_instances.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// GtmInstances is a nested struct in alidns response +type GtmInstances struct { + GtmInstance []GtmInstance `json:"GtmInstance" xml:"GtmInstance"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_node.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_node.go new file mode 100644 index 000000000..5549e2d96 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_node.go @@ -0,0 +1,28 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// IspCityNode is a nested struct in alidns response +type IspCityNode struct { + CityCode string `json:"CityCode" xml:"CityCode"` + DefaultSelected bool `json:"DefaultSelected" xml:"DefaultSelected"` + IspName string `json:"IspName" xml:"IspName"` + CountryName string `json:"CountryName" xml:"CountryName"` + CityName string `json:"CityName" xml:"CityName"` + Mainland bool `json:"Mainland" xml:"Mainland"` + CountryCode string `json:"CountryCode" xml:"CountryCode"` + IspCode string `json:"IspCode" xml:"IspCode"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_nodes_in_describe_gtm_monitor_available_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_nodes_in_describe_gtm_monitor_available_config.go new file mode 100644 index 000000000..82c86e997 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_nodes_in_describe_gtm_monitor_available_config.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// IspCityNodesInDescribeGtmMonitorAvailableConfig is a nested struct in alidns response +type IspCityNodesInDescribeGtmMonitorAvailableConfig struct { + IspCityNode []IspCityNode `json:"IspCityNode" xml:"IspCityNode"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_nodes_in_describe_gtm_monitor_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_nodes_in_describe_gtm_monitor_config.go new file mode 100644 index 000000000..7f531d449 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_isp_city_nodes_in_describe_gtm_monitor_config.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// IspCityNodesInDescribeGtmMonitorConfig is a nested struct in alidns response +type IspCityNodesInDescribeGtmMonitorConfig struct { + IspCityNode []IspCityNode `json:"IspCityNode" xml:"IspCityNode"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_line.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_line.go new file mode 100644 index 000000000..76487a7d2 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_line.go @@ -0,0 +1,25 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Line is a nested struct in alidns response +type Line struct { + GroupCode string `json:"GroupCode" xml:"GroupCode"` + LineCode string `json:"LineCode" xml:"LineCode"` + LineName string `json:"LineName" xml:"LineName"` + GroupName string `json:"GroupName" xml:"GroupName"` + Status string `json:"Status" xml:"Status"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategies.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategies.go new file mode 100644 index 000000000..75defbd04 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategies.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// LinesInDescribeGtmAccessStrategies is a nested struct in alidns response +type LinesInDescribeGtmAccessStrategies struct { + Line []Line `json:"Line" xml:"Line"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategy.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategy.go new file mode 100644 index 000000000..86d10f668 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategy.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// LinesInDescribeGtmAccessStrategy is a nested struct in alidns response +type LinesInDescribeGtmAccessStrategy struct { + Line []Line `json:"Line" xml:"Line"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategy_available_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategy_available_config.go new file mode 100644 index 000000000..7289ff376 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_lines_in_describe_gtm_access_strategy_available_config.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// LinesInDescribeGtmAccessStrategyAvailableConfig is a nested struct in alidns response +type LinesInDescribeGtmAccessStrategyAvailableConfig struct { + Line []Line `json:"Line" xml:"Line"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_log.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_log.go new file mode 100644 index 000000000..489378f47 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_log.go @@ -0,0 +1,29 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Log is a nested struct in alidns response +type Log struct { + OperTime string `json:"OperTime" xml:"OperTime"` + OperAction string `json:"OperAction" xml:"OperAction"` + EntityType string `json:"EntityType" xml:"EntityType"` + EntityId string `json:"EntityId" xml:"EntityId"` + EntityName string `json:"EntityName" xml:"EntityName"` + OperIp string `json:"OperIp" xml:"OperIp"` + OperTimestamp int64 `json:"OperTimestamp" xml:"OperTimestamp"` + Id int64 `json:"Id" xml:"Id"` + Content string `json:"Content" xml:"Content"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_logs.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_logs.go new file mode 100644 index 000000000..9ae457176 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_logs.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Logs is a nested struct in alidns response +type Logs struct { + Log []Log `json:"Log" xml:"Log"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_new_dns_servers.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_new_dns_servers.go new file mode 100644 index 000000000..5fd8b180f --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_new_dns_servers.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// NewDnsServers is a nested struct in alidns response +type NewDnsServers struct { + DnsServer []string `json:"DnsServer" xml:"DnsServer"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_original_dns_servers.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_original_dns_servers.go new file mode 100644 index 000000000..b6f90bb3d --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_original_dns_servers.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// OriginalDnsServers is a nested struct in alidns response +type OriginalDnsServers struct { + DnsServer []string `json:"DnsServer" xml:"DnsServer"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record.go new file mode 100644 index 000000000..59df2f74b --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record.go @@ -0,0 +1,32 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Record is a nested struct in alidns response +type Record struct { + Value string `json:"Value" xml:"Value"` + TTL int64 `json:"TTL" xml:"TTL"` + Remark string `json:"Remark" xml:"Remark"` + DomainName string `json:"DomainName" xml:"DomainName"` + RR string `json:"RR" xml:"RR"` + Priority int64 `json:"Priority" xml:"Priority"` + RecordId string `json:"RecordId" xml:"RecordId"` + Status string `json:"Status" xml:"Status"` + Locked bool `json:"Locked" xml:"Locked"` + Weight int `json:"Weight" xml:"Weight"` + Line string `json:"Line" xml:"Line"` + Type string `json:"Type" xml:"Type"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_line.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_line.go new file mode 100644 index 000000000..d4db70380 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_line.go @@ -0,0 +1,24 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// RecordLine is a nested struct in alidns response +type RecordLine struct { + LineDisplayName string `json:"LineDisplayName" xml:"LineDisplayName"` + LineCode string `json:"LineCode" xml:"LineCode"` + LineName string `json:"LineName" xml:"LineName"` + FatherCode string `json:"FatherCode" xml:"FatherCode"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_lines_in_describe_domain_info.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_lines_in_describe_domain_info.go new file mode 100644 index 000000000..203f525b2 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_lines_in_describe_domain_info.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// RecordLinesInDescribeDomainInfo is a nested struct in alidns response +type RecordLinesInDescribeDomainInfo struct { + RecordLine []RecordLine `json:"RecordLine" xml:"RecordLine"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_lines_in_describe_support_lines.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_lines_in_describe_support_lines.go new file mode 100644 index 000000000..5c2e05f20 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_lines_in_describe_support_lines.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// RecordLinesInDescribeSupportLines is a nested struct in alidns response +type RecordLinesInDescribeSupportLines struct { + RecordLine []RecordLine `json:"RecordLine" xml:"RecordLine"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_log.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_log.go new file mode 100644 index 000000000..e6bf34f33 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_log.go @@ -0,0 +1,25 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// RecordLog is a nested struct in alidns response +type RecordLog struct { + ActionTime string `json:"ActionTime" xml:"ActionTime"` + ActionTimestamp int64 `json:"ActionTimestamp" xml:"ActionTimestamp"` + Action string `json:"Action" xml:"Action"` + Message string `json:"Message" xml:"Message"` + ClientIp string `json:"ClientIp" xml:"ClientIp"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_logs.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_logs.go new file mode 100644 index 000000000..b5a42b5eb --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_record_logs.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// RecordLogs is a nested struct in alidns response +type RecordLogs struct { + RecordLog []RecordLog `json:"RecordLog" xml:"RecordLog"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_rule.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_rule.go new file mode 100644 index 000000000..e7dcc83e8 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_rule.go @@ -0,0 +1,23 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Rule is a nested struct in alidns response +type Rule struct { + RuleId int64 `json:"RuleId" xml:"RuleId"` + Name string `json:"Name" xml:"Name"` + Title string `json:"Title" xml:"Title"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_rules.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_rules.go new file mode 100644 index 000000000..067a95886 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_rules.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Rules is a nested struct in alidns response +type Rules struct { + Rule []Rule `json:"Rule" xml:"Rule"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_slb_sub_domain.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_slb_sub_domain.go new file mode 100644 index 000000000..d16fb9ad9 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_slb_sub_domain.go @@ -0,0 +1,24 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// SlbSubDomain is a nested struct in alidns response +type SlbSubDomain struct { + SubDomain string `json:"SubDomain" xml:"SubDomain"` + RecordCount int64 `json:"RecordCount" xml:"RecordCount"` + Open bool `json:"Open" xml:"Open"` + Type string `json:"Type" xml:"Type"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_slb_sub_domains.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_slb_sub_domains.go new file mode 100644 index 000000000..4618d59c3 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_slb_sub_domains.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// SlbSubDomains is a nested struct in alidns response +type SlbSubDomains struct { + SlbSubDomain []SlbSubDomain `json:"SlbSubDomain" xml:"SlbSubDomain"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistic.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistic.go new file mode 100644 index 000000000..7aaa95a8e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistic.go @@ -0,0 +1,24 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Statistic is a nested struct in alidns response +type Statistic struct { + Timestamp int64 `json:"Timestamp" xml:"Timestamp"` + Count int64 `json:"Count" xml:"Count"` + DomainName string `json:"DomainName" xml:"DomainName"` + SubDomain string `json:"SubDomain" xml:"SubDomain"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_dns_statistics.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_dns_statistics.go new file mode 100644 index 000000000..0fb034ffd --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_dns_statistics.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// StatisticsInDescribeDomainDnsStatistics is a nested struct in alidns response +type StatisticsInDescribeDomainDnsStatistics struct { + Statistic []Statistic `json:"Statistic" xml:"Statistic"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_statistics.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_statistics.go new file mode 100644 index 000000000..462322d75 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_statistics.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// StatisticsInDescribeDomainStatistics is a nested struct in alidns response +type StatisticsInDescribeDomainStatistics struct { + Statistic []Statistic `json:"Statistic" xml:"Statistic"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_statistics_summary.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_statistics_summary.go new file mode 100644 index 000000000..27418d0ba --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_domain_statistics_summary.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// StatisticsInDescribeDomainStatisticsSummary is a nested struct in alidns response +type StatisticsInDescribeDomainStatisticsSummary struct { + Statistic []Statistic `json:"Statistic" xml:"Statistic"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics.go new file mode 100644 index 000000000..7303c1a39 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// StatisticsInDescribeRecordStatistics is a nested struct in alidns response +type StatisticsInDescribeRecordStatistics struct { + Statistic []Statistic `json:"Statistic" xml:"Statistic"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics_history.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics_history.go new file mode 100644 index 000000000..b0660050e --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics_history.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// StatisticsInDescribeRecordStatisticsHistory is a nested struct in alidns response +type StatisticsInDescribeRecordStatisticsHistory struct { + Statistic []Statistic `json:"Statistic" xml:"Statistic"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics_summary.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics_summary.go new file mode 100644 index 000000000..fcda10250 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_statistics_in_describe_record_statistics_summary.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// StatisticsInDescribeRecordStatisticsSummary is a nested struct in alidns response +type StatisticsInDescribeRecordStatisticsSummary struct { + Statistic []Statistic `json:"Statistic" xml:"Statistic"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_strategies.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_strategies.go new file mode 100644 index 000000000..abe9988f5 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_strategies.go @@ -0,0 +1,21 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Strategies is a nested struct in alidns response +type Strategies struct { + Strategy []Strategy `json:"Strategy" xml:"Strategy"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_strategy.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_strategy.go new file mode 100644 index 000000000..62318749c --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/struct_strategy.go @@ -0,0 +1,33 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// Strategy is a nested struct in alidns response +type Strategy struct { + StrategyId string `json:"StrategyId" xml:"StrategyId"` + StrategyName string `json:"StrategyName" xml:"StrategyName"` + CreateTime string `json:"CreateTime" xml:"CreateTime"` + CreateTimestamp int64 `json:"CreateTimestamp" xml:"CreateTimestamp"` + DefaultAddrPoolId string `json:"DefaultAddrPoolId" xml:"DefaultAddrPoolId"` + DefaultAddrPoolName string `json:"DefaultAddrPoolName" xml:"DefaultAddrPoolName"` + FailoverAddrPoolId string `json:"FailoverAddrPoolId" xml:"FailoverAddrPoolId"` + FailoverAddrPoolName string `json:"FailoverAddrPoolName" xml:"FailoverAddrPoolName"` + AccessMode string `json:"AccessMode" xml:"AccessMode"` + AccessStatus string `json:"AccessStatus" xml:"AccessStatus"` + StrategyMode string `json:"StrategyMode" xml:"StrategyMode"` + InstanceId string `json:"InstanceId" xml:"InstanceId"` + Lines LinesInDescribeGtmAccessStrategies `json:"Lines" xml:"Lines"` +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_dnsslb_weight.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_dnsslb_weight.go new file mode 100644 index 000000000..49df52fe4 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_dnsslb_weight.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UpdateDNSSLBWeight invokes the alidns.UpdateDNSSLBWeight API synchronously +// api document: https://help.aliyun.com/api/alidns/updatednsslbweight.html +func (client *Client) UpdateDNSSLBWeight(request *UpdateDNSSLBWeightRequest) (response *UpdateDNSSLBWeightResponse, err error) { + response = CreateUpdateDNSSLBWeightResponse() + err = client.DoAction(request, response) + return +} + +// UpdateDNSSLBWeightWithChan invokes the alidns.UpdateDNSSLBWeight API asynchronously +// api document: https://help.aliyun.com/api/alidns/updatednsslbweight.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateDNSSLBWeightWithChan(request *UpdateDNSSLBWeightRequest) (<-chan *UpdateDNSSLBWeightResponse, <-chan error) { + responseChan := make(chan *UpdateDNSSLBWeightResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UpdateDNSSLBWeight(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UpdateDNSSLBWeightWithCallback invokes the alidns.UpdateDNSSLBWeight API asynchronously +// api document: https://help.aliyun.com/api/alidns/updatednsslbweight.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateDNSSLBWeightWithCallback(request *UpdateDNSSLBWeightRequest, callback func(response *UpdateDNSSLBWeightResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UpdateDNSSLBWeightResponse + var err error + defer close(result) + response, err = client.UpdateDNSSLBWeight(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UpdateDNSSLBWeightRequest is the request struct for api UpdateDNSSLBWeight +type UpdateDNSSLBWeightRequest struct { + *requests.RpcRequest + RecordId string `position:"Query" name:"RecordId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Weight requests.Integer `position:"Query" name:"Weight"` + Lang string `position:"Query" name:"Lang"` +} + +// UpdateDNSSLBWeightResponse is the response struct for api UpdateDNSSLBWeight +type UpdateDNSSLBWeightResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + RecordId string `json:"RecordId" xml:"RecordId"` + Weight int `json:"Weight" xml:"Weight"` +} + +// CreateUpdateDNSSLBWeightRequest creates a request to invoke UpdateDNSSLBWeight API +func CreateUpdateDNSSLBWeightRequest() (request *UpdateDNSSLBWeightRequest) { + request = &UpdateDNSSLBWeightRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "UpdateDNSSLBWeight", "Alidns", "openAPI") + return +} + +// CreateUpdateDNSSLBWeightResponse creates a response to parse from UpdateDNSSLBWeight response +func CreateUpdateDNSSLBWeightResponse() (response *UpdateDNSSLBWeightResponse) { + response = &UpdateDNSSLBWeightResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_domain_group.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_domain_group.go new file mode 100644 index 000000000..7d95763d0 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_domain_group.go @@ -0,0 +1,108 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UpdateDomainGroup invokes the alidns.UpdateDomainGroup API synchronously +// api document: https://help.aliyun.com/api/alidns/updatedomaingroup.html +func (client *Client) UpdateDomainGroup(request *UpdateDomainGroupRequest) (response *UpdateDomainGroupResponse, err error) { + response = CreateUpdateDomainGroupResponse() + err = client.DoAction(request, response) + return +} + +// UpdateDomainGroupWithChan invokes the alidns.UpdateDomainGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/updatedomaingroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateDomainGroupWithChan(request *UpdateDomainGroupRequest) (<-chan *UpdateDomainGroupResponse, <-chan error) { + responseChan := make(chan *UpdateDomainGroupResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UpdateDomainGroup(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UpdateDomainGroupWithCallback invokes the alidns.UpdateDomainGroup API asynchronously +// api document: https://help.aliyun.com/api/alidns/updatedomaingroup.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateDomainGroupWithCallback(request *UpdateDomainGroupRequest, callback func(response *UpdateDomainGroupResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UpdateDomainGroupResponse + var err error + defer close(result) + response, err = client.UpdateDomainGroup(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UpdateDomainGroupRequest is the request struct for api UpdateDomainGroup +type UpdateDomainGroupRequest struct { + *requests.RpcRequest + GroupId string `position:"Query" name:"GroupId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` + GroupName string `position:"Query" name:"GroupName"` +} + +// UpdateDomainGroupResponse is the response struct for api UpdateDomainGroup +type UpdateDomainGroupResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + GroupId string `json:"GroupId" xml:"GroupId"` + GroupName string `json:"GroupName" xml:"GroupName"` +} + +// CreateUpdateDomainGroupRequest creates a request to invoke UpdateDomainGroup API +func CreateUpdateDomainGroupRequest() (request *UpdateDomainGroupRequest) { + request = &UpdateDomainGroupRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "UpdateDomainGroup", "Alidns", "openAPI") + return +} + +// CreateUpdateDomainGroupResponse creates a response to parse from UpdateDomainGroup response +func CreateUpdateDomainGroupResponse() (response *UpdateDomainGroupResponse) { + response = &UpdateDomainGroupResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_domain_record.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_domain_record.go new file mode 100644 index 000000000..3371e6870 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_domain_record.go @@ -0,0 +1,112 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UpdateDomainRecord invokes the alidns.UpdateDomainRecord API synchronously +// api document: https://help.aliyun.com/api/alidns/updatedomainrecord.html +func (client *Client) UpdateDomainRecord(request *UpdateDomainRecordRequest) (response *UpdateDomainRecordResponse, err error) { + response = CreateUpdateDomainRecordResponse() + err = client.DoAction(request, response) + return +} + +// UpdateDomainRecordWithChan invokes the alidns.UpdateDomainRecord API asynchronously +// api document: https://help.aliyun.com/api/alidns/updatedomainrecord.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateDomainRecordWithChan(request *UpdateDomainRecordRequest) (<-chan *UpdateDomainRecordResponse, <-chan error) { + responseChan := make(chan *UpdateDomainRecordResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UpdateDomainRecord(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UpdateDomainRecordWithCallback invokes the alidns.UpdateDomainRecord API asynchronously +// api document: https://help.aliyun.com/api/alidns/updatedomainrecord.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateDomainRecordWithCallback(request *UpdateDomainRecordRequest, callback func(response *UpdateDomainRecordResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UpdateDomainRecordResponse + var err error + defer close(result) + response, err = client.UpdateDomainRecord(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UpdateDomainRecordRequest is the request struct for api UpdateDomainRecord +type UpdateDomainRecordRequest struct { + *requests.RpcRequest + RecordId string `position:"Query" name:"RecordId"` + RR string `position:"Query" name:"RR"` + Line string `position:"Query" name:"Line"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Lang string `position:"Query" name:"Lang"` + Type string `position:"Query" name:"Type"` + Priority requests.Integer `position:"Query" name:"Priority"` + Value string `position:"Query" name:"Value"` + TTL requests.Integer `position:"Query" name:"TTL"` +} + +// UpdateDomainRecordResponse is the response struct for api UpdateDomainRecord +type UpdateDomainRecordResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` + RecordId string `json:"RecordId" xml:"RecordId"` +} + +// CreateUpdateDomainRecordRequest creates a request to invoke UpdateDomainRecord API +func CreateUpdateDomainRecordRequest() (request *UpdateDomainRecordRequest) { + request = &UpdateDomainRecordRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "UpdateDomainRecord", "Alidns", "openAPI") + return +} + +// CreateUpdateDomainRecordResponse creates a response to parse from UpdateDomainRecord response +func CreateUpdateDomainRecordResponse() (response *UpdateDomainRecordResponse) { + response = &UpdateDomainRecordResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_access_strategy.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_access_strategy.go new file mode 100644 index 000000000..e0437eb57 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_access_strategy.go @@ -0,0 +1,109 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UpdateGtmAccessStrategy invokes the alidns.UpdateGtmAccessStrategy API synchronously +// api document: https://help.aliyun.com/api/alidns/updategtmaccessstrategy.html +func (client *Client) UpdateGtmAccessStrategy(request *UpdateGtmAccessStrategyRequest) (response *UpdateGtmAccessStrategyResponse, err error) { + response = CreateUpdateGtmAccessStrategyResponse() + err = client.DoAction(request, response) + return +} + +// UpdateGtmAccessStrategyWithChan invokes the alidns.UpdateGtmAccessStrategy API asynchronously +// api document: https://help.aliyun.com/api/alidns/updategtmaccessstrategy.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateGtmAccessStrategyWithChan(request *UpdateGtmAccessStrategyRequest) (<-chan *UpdateGtmAccessStrategyResponse, <-chan error) { + responseChan := make(chan *UpdateGtmAccessStrategyResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UpdateGtmAccessStrategy(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UpdateGtmAccessStrategyWithCallback invokes the alidns.UpdateGtmAccessStrategy API asynchronously +// api document: https://help.aliyun.com/api/alidns/updategtmaccessstrategy.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateGtmAccessStrategyWithCallback(request *UpdateGtmAccessStrategyRequest, callback func(response *UpdateGtmAccessStrategyResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UpdateGtmAccessStrategyResponse + var err error + defer close(result) + response, err = client.UpdateGtmAccessStrategy(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UpdateGtmAccessStrategyRequest is the request struct for api UpdateGtmAccessStrategy +type UpdateGtmAccessStrategyRequest struct { + *requests.RpcRequest + StrategyName string `position:"Query" name:"StrategyName"` + DefaultAddrPoolId string `position:"Query" name:"DefaultAddrPoolId"` + AccessLines string `position:"Query" name:"AccessLines"` + FailoverAddrPoolId string `position:"Query" name:"FailoverAddrPoolId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + StrategyId string `position:"Query" name:"StrategyId"` + Lang string `position:"Query" name:"Lang"` +} + +// UpdateGtmAccessStrategyResponse is the response struct for api UpdateGtmAccessStrategy +type UpdateGtmAccessStrategyResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateUpdateGtmAccessStrategyRequest creates a request to invoke UpdateGtmAccessStrategy API +func CreateUpdateGtmAccessStrategyRequest() (request *UpdateGtmAccessStrategyRequest) { + request = &UpdateGtmAccessStrategyRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "UpdateGtmAccessStrategy", "Alidns", "openAPI") + return +} + +// CreateUpdateGtmAccessStrategyResponse creates a response to parse from UpdateGtmAccessStrategy response +func CreateUpdateGtmAccessStrategyResponse() (response *UpdateGtmAccessStrategyResponse) { + response = &UpdateGtmAccessStrategyResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_address_pool.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_address_pool.go new file mode 100644 index 000000000..cdbd6fc45 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_address_pool.go @@ -0,0 +1,116 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UpdateGtmAddressPool invokes the alidns.UpdateGtmAddressPool API synchronously +// api document: https://help.aliyun.com/api/alidns/updategtmaddresspool.html +func (client *Client) UpdateGtmAddressPool(request *UpdateGtmAddressPoolRequest) (response *UpdateGtmAddressPoolResponse, err error) { + response = CreateUpdateGtmAddressPoolResponse() + err = client.DoAction(request, response) + return +} + +// UpdateGtmAddressPoolWithChan invokes the alidns.UpdateGtmAddressPool API asynchronously +// api document: https://help.aliyun.com/api/alidns/updategtmaddresspool.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateGtmAddressPoolWithChan(request *UpdateGtmAddressPoolRequest) (<-chan *UpdateGtmAddressPoolResponse, <-chan error) { + responseChan := make(chan *UpdateGtmAddressPoolResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UpdateGtmAddressPool(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UpdateGtmAddressPoolWithCallback invokes the alidns.UpdateGtmAddressPool API asynchronously +// api document: https://help.aliyun.com/api/alidns/updategtmaddresspool.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateGtmAddressPoolWithCallback(request *UpdateGtmAddressPoolRequest, callback func(response *UpdateGtmAddressPoolResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UpdateGtmAddressPoolResponse + var err error + defer close(result) + response, err = client.UpdateGtmAddressPool(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UpdateGtmAddressPoolRequest is the request struct for api UpdateGtmAddressPool +type UpdateGtmAddressPoolRequest struct { + *requests.RpcRequest + AddrPoolId string `position:"Query" name:"AddrPoolId"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Name string `position:"Query" name:"Name"` + Lang string `position:"Query" name:"Lang"` + Type string `position:"Query" name:"Type"` + Addr *[]UpdateGtmAddressPoolAddr `position:"Query" name:"Addr" type:"Repeated"` + MinAvailableAddrNum requests.Integer `position:"Query" name:"MinAvailableAddrNum"` +} + +// UpdateGtmAddressPoolAddr is a repeated param struct in UpdateGtmAddressPoolRequest +type UpdateGtmAddressPoolAddr struct { + Mode string `name:"Mode"` + LbaWeight string `name:"LbaWeight"` + Value string `name:"Value"` +} + +// UpdateGtmAddressPoolResponse is the response struct for api UpdateGtmAddressPool +type UpdateGtmAddressPoolResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateUpdateGtmAddressPoolRequest creates a request to invoke UpdateGtmAddressPool API +func CreateUpdateGtmAddressPoolRequest() (request *UpdateGtmAddressPoolRequest) { + request = &UpdateGtmAddressPoolRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "UpdateGtmAddressPool", "Alidns", "openAPI") + return +} + +// CreateUpdateGtmAddressPoolResponse creates a response to parse from UpdateGtmAddressPool response +func CreateUpdateGtmAddressPoolResponse() (response *UpdateGtmAddressPoolResponse) { + response = &UpdateGtmAddressPoolResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_instance_global_config.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_instance_global_config.go new file mode 100644 index 000000000..38a857230 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_instance_global_config.go @@ -0,0 +1,112 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UpdateGtmInstanceGlobalConfig invokes the alidns.UpdateGtmInstanceGlobalConfig API synchronously +// api document: https://help.aliyun.com/api/alidns/updategtminstanceglobalconfig.html +func (client *Client) UpdateGtmInstanceGlobalConfig(request *UpdateGtmInstanceGlobalConfigRequest) (response *UpdateGtmInstanceGlobalConfigResponse, err error) { + response = CreateUpdateGtmInstanceGlobalConfigResponse() + err = client.DoAction(request, response) + return +} + +// UpdateGtmInstanceGlobalConfigWithChan invokes the alidns.UpdateGtmInstanceGlobalConfig API asynchronously +// api document: https://help.aliyun.com/api/alidns/updategtminstanceglobalconfig.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateGtmInstanceGlobalConfigWithChan(request *UpdateGtmInstanceGlobalConfigRequest) (<-chan *UpdateGtmInstanceGlobalConfigResponse, <-chan error) { + responseChan := make(chan *UpdateGtmInstanceGlobalConfigResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UpdateGtmInstanceGlobalConfig(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UpdateGtmInstanceGlobalConfigWithCallback invokes the alidns.UpdateGtmInstanceGlobalConfig API asynchronously +// api document: https://help.aliyun.com/api/alidns/updategtminstanceglobalconfig.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateGtmInstanceGlobalConfigWithCallback(request *UpdateGtmInstanceGlobalConfigRequest, callback func(response *UpdateGtmInstanceGlobalConfigResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UpdateGtmInstanceGlobalConfigResponse + var err error + defer close(result) + response, err = client.UpdateGtmInstanceGlobalConfig(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UpdateGtmInstanceGlobalConfigRequest is the request struct for api UpdateGtmInstanceGlobalConfig +type UpdateGtmInstanceGlobalConfigRequest struct { + *requests.RpcRequest + AlertGroup string `position:"Query" name:"AlertGroup"` + InstanceId string `position:"Query" name:"InstanceId"` + InstanceName string `position:"Query" name:"InstanceName"` + UserDomainName string `position:"Query" name:"UserDomainName"` + CnameMode string `position:"Query" name:"CnameMode"` + UserClientIp string `position:"Query" name:"UserClientIp"` + LbaStrategy string `position:"Query" name:"LbaStrategy"` + Lang string `position:"Query" name:"Lang"` + Ttl requests.Integer `position:"Query" name:"Ttl"` + CnameCustomDomainName string `position:"Query" name:"CnameCustomDomainName"` +} + +// UpdateGtmInstanceGlobalConfigResponse is the response struct for api UpdateGtmInstanceGlobalConfig +type UpdateGtmInstanceGlobalConfigResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateUpdateGtmInstanceGlobalConfigRequest creates a request to invoke UpdateGtmInstanceGlobalConfig API +func CreateUpdateGtmInstanceGlobalConfigRequest() (request *UpdateGtmInstanceGlobalConfigRequest) { + request = &UpdateGtmInstanceGlobalConfigRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "UpdateGtmInstanceGlobalConfig", "Alidns", "openAPI") + return +} + +// CreateUpdateGtmInstanceGlobalConfigResponse creates a response to parse from UpdateGtmInstanceGlobalConfig response +func CreateUpdateGtmInstanceGlobalConfigResponse() (response *UpdateGtmInstanceGlobalConfigResponse) { + response = &UpdateGtmInstanceGlobalConfigResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_monitor.go b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_monitor.go new file mode 100644 index 000000000..c6280f269 --- /dev/null +++ b/vendor/github.com/aliyun/alibaba-cloud-sdk-go/services/alidns/update_gtm_monitor.go @@ -0,0 +1,118 @@ +package alidns + +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +// +// Code generated by Alibaba Cloud SDK Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses" +) + +// UpdateGtmMonitor invokes the alidns.UpdateGtmMonitor API synchronously +// api document: https://help.aliyun.com/api/alidns/updategtmmonitor.html +func (client *Client) UpdateGtmMonitor(request *UpdateGtmMonitorRequest) (response *UpdateGtmMonitorResponse, err error) { + response = CreateUpdateGtmMonitorResponse() + err = client.DoAction(request, response) + return +} + +// UpdateGtmMonitorWithChan invokes the alidns.UpdateGtmMonitor API asynchronously +// api document: https://help.aliyun.com/api/alidns/updategtmmonitor.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateGtmMonitorWithChan(request *UpdateGtmMonitorRequest) (<-chan *UpdateGtmMonitorResponse, <-chan error) { + responseChan := make(chan *UpdateGtmMonitorResponse, 1) + errChan := make(chan error, 1) + err := client.AddAsyncTask(func() { + defer close(responseChan) + defer close(errChan) + response, err := client.UpdateGtmMonitor(request) + if err != nil { + errChan <- err + } else { + responseChan <- response + } + }) + if err != nil { + errChan <- err + close(responseChan) + close(errChan) + } + return responseChan, errChan +} + +// UpdateGtmMonitorWithCallback invokes the alidns.UpdateGtmMonitor API asynchronously +// api document: https://help.aliyun.com/api/alidns/updategtmmonitor.html +// asynchronous document: https://help.aliyun.com/document_detail/66220.html +func (client *Client) UpdateGtmMonitorWithCallback(request *UpdateGtmMonitorRequest, callback func(response *UpdateGtmMonitorResponse, err error)) <-chan int { + result := make(chan int, 1) + err := client.AddAsyncTask(func() { + var response *UpdateGtmMonitorResponse + var err error + defer close(result) + response, err = client.UpdateGtmMonitor(request) + callback(response, err) + result <- 1 + }) + if err != nil { + defer close(result) + callback(nil, err) + result <- 0 + } + return result +} + +// UpdateGtmMonitorRequest is the request struct for api UpdateGtmMonitor +type UpdateGtmMonitorRequest struct { + *requests.RpcRequest + MonitorExtendInfo string `position:"Query" name:"MonitorExtendInfo"` + UserClientIp string `position:"Query" name:"UserClientIp"` + Name string `position:"Query" name:"Name"` + MonitorConfigId string `position:"Query" name:"MonitorConfigId"` + EvaluationCount requests.Integer `position:"Query" name:"EvaluationCount"` + ProtocolType string `position:"Query" name:"ProtocolType"` + Interval requests.Integer `position:"Query" name:"Interval"` + Lang string `position:"Query" name:"Lang"` + Timeout requests.Integer `position:"Query" name:"Timeout"` + IspCityNode *[]UpdateGtmMonitorIspCityNode `position:"Query" name:"IspCityNode" type:"Repeated"` +} + +// UpdateGtmMonitorIspCityNode is a repeated param struct in UpdateGtmMonitorRequest +type UpdateGtmMonitorIspCityNode struct { + CityCode string `name:"CityCode"` + IspCode string `name:"IspCode"` +} + +// UpdateGtmMonitorResponse is the response struct for api UpdateGtmMonitor +type UpdateGtmMonitorResponse struct { + *responses.BaseResponse + RequestId string `json:"RequestId" xml:"RequestId"` +} + +// CreateUpdateGtmMonitorRequest creates a request to invoke UpdateGtmMonitor API +func CreateUpdateGtmMonitorRequest() (request *UpdateGtmMonitorRequest) { + request = &UpdateGtmMonitorRequest{ + RpcRequest: &requests.RpcRequest{}, + } + request.InitWithApiInfo("Alidns", "2015-01-09", "UpdateGtmMonitor", "Alidns", "openAPI") + return +} + +// CreateUpdateGtmMonitorResponse creates a response to parse from UpdateGtmMonitor response +func CreateUpdateGtmMonitorResponse() (response *UpdateGtmMonitorResponse) { + response = &UpdateGtmMonitorResponse{ + BaseResponse: &responses.BaseResponse{}, + } + return +} diff --git a/vendor/github.com/aws/aws-sdk-go/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/LICENSE.txt @@ -0,0 +1,202 @@ + + 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. diff --git a/vendor/github.com/aws/aws-sdk-go/NOTICE.txt b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt new file mode 100644 index 000000000..899129ecc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/NOTICE.txt @@ -0,0 +1,3 @@ +AWS SDK for Go +Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Copyright 2014-2015 Stripe, Inc. diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go new file mode 100644 index 000000000..99849c0e1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go @@ -0,0 +1,164 @@ +// Package awserr represents API error interface accessors for the SDK. +package awserr + +// An Error wraps lower level errors with code, message and an original error. +// The underlying concrete error type may also satisfy other interfaces which +// can be to used to obtain more specific information about the error. +// +// Calling Error() or String() will always include the full information about +// an error based on its underlying type. +// +// Example: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Get error details +// log.Println("Error:", awsErr.Code(), awsErr.Message()) +// +// // Prints out full error message, including original error if there was one. +// log.Println("Error:", awsErr.Error()) +// +// // Get original error +// if origErr := awsErr.OrigErr(); origErr != nil { +// // operate on original error. +// } +// } else { +// fmt.Println(err.Error()) +// } +// } +// +type Error interface { + // Satisfy the generic error interface. + error + + // Returns the short phrase depicting the classification of the error. + Code() string + + // Returns the error details message. + Message() string + + // Returns the original error if one was set. Nil is returned if not set. + OrigErr() error +} + +// BatchError is a batch of errors which also wraps lower level errors with +// code, message, and original errors. Calling Error() will include all errors +// that occurred in the batch. +// +// Deprecated: Replaced with BatchedErrors. Only defined for backwards +// compatibility. +type BatchError interface { + // Satisfy the generic error interface. + error + + // Returns the short phrase depicting the classification of the error. + Code() string + + // Returns the error details message. + Message() string + + // Returns the original error if one was set. Nil is returned if not set. + OrigErrs() []error +} + +// BatchedErrors is a batch of errors which also wraps lower level errors with +// code, message, and original errors. Calling Error() will include all errors +// that occurred in the batch. +// +// Replaces BatchError +type BatchedErrors interface { + // Satisfy the base Error interface. + Error + + // Returns the original error if one was set. Nil is returned if not set. + OrigErrs() []error +} + +// New returns an Error object described by the code, message, and origErr. +// +// If origErr satisfies the Error interface it will not be wrapped within a new +// Error object and will instead be returned. +func New(code, message string, origErr error) Error { + var errs []error + if origErr != nil { + errs = append(errs, origErr) + } + return newBaseError(code, message, errs) +} + +// NewBatchError returns an BatchedErrors with a collection of errors as an +// array of errors. +func NewBatchError(code, message string, errs []error) BatchedErrors { + return newBaseError(code, message, errs) +} + +// A RequestFailure is an interface to extract request failure information from +// an Error such as the request ID of the failed request returned by a service. +// RequestFailures may not always have a requestID value if the request failed +// prior to reaching the service such as a connection error. +// +// Example: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if reqerr, ok := err.(RequestFailure); ok { +// log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID()) +// } else { +// log.Println("Error:", err.Error()) +// } +// } +// +// Combined with awserr.Error: +// +// output, err := s3manage.Upload(svc, input, opts) +// if err != nil { +// if awsErr, ok := err.(awserr.Error); ok { +// // Generic AWS Error with Code, Message, and original error (if any) +// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr()) +// +// if reqErr, ok := err.(awserr.RequestFailure); ok { +// // A service error occurred +// fmt.Println(reqErr.StatusCode(), reqErr.RequestID()) +// } +// } else { +// fmt.Println(err.Error()) +// } +// } +// +type RequestFailure interface { + Error + + // The status code of the HTTP response. + StatusCode() int + + // The request ID returned by the service for a request failure. This will + // be empty if no request ID is available such as the request failed due + // to a connection error. + RequestID() string +} + +// NewRequestFailure returns a wrapped error with additional information for +// request status code, and service requestID. +// +// Should be used to wrap all request which involve service requests. Even if +// the request failed without a service response, but had an HTTP status code +// that may be meaningful. +func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure { + return newRequestError(err, statusCode, reqID) +} + +// UnmarshalError provides the interface for the SDK failing to unmarshal data. +type UnmarshalError interface { + awsError + Bytes() []byte +} + +// NewUnmarshalError returns an initialized UnmarshalError error wrapper adding +// the bytes that fail to unmarshal to the error. +func NewUnmarshalError(err error, msg string, bytes []byte) UnmarshalError { + return &unmarshalError{ + awsError: New("UnmarshalError", msg, err), + bytes: bytes, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go new file mode 100644 index 000000000..9cf7eaf40 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go @@ -0,0 +1,221 @@ +package awserr + +import ( + "encoding/hex" + "fmt" +) + +// SprintError returns a string of the formatted error code. +// +// Both extra and origErr are optional. If they are included their lines +// will be added, but if they are not included their lines will be ignored. +func SprintError(code, message, extra string, origErr error) string { + msg := fmt.Sprintf("%s: %s", code, message) + if extra != "" { + msg = fmt.Sprintf("%s\n\t%s", msg, extra) + } + if origErr != nil { + msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error()) + } + return msg +} + +// A baseError wraps the code and message which defines an error. It also +// can be used to wrap an original error object. +// +// Should be used as the root for errors satisfying the awserr.Error. Also +// for any error which does not fit into a specific error wrapper type. +type baseError struct { + // Classification of error + code string + + // Detailed information about error + message string + + // Optional original error this error is based off of. Allows building + // chained errors. + errs []error +} + +// newBaseError returns an error object for the code, message, and errors. +// +// code is a short no whitespace phrase depicting the classification of +// the error that is being created. +// +// message is the free flow string containing detailed information about the +// error. +// +// origErrs is the error objects which will be nested under the new errors to +// be returned. +func newBaseError(code, message string, origErrs []error) *baseError { + b := &baseError{ + code: code, + message: message, + errs: origErrs, + } + + return b +} + +// Error returns the string representation of the error. +// +// See ErrorWithExtra for formatting. +// +// Satisfies the error interface. +func (b baseError) Error() string { + size := len(b.errs) + if size > 0 { + return SprintError(b.code, b.message, "", errorList(b.errs)) + } + + return SprintError(b.code, b.message, "", nil) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (b baseError) String() string { + return b.Error() +} + +// Code returns the short phrase depicting the classification of the error. +func (b baseError) Code() string { + return b.code +} + +// Message returns the error details message. +func (b baseError) Message() string { + return b.message +} + +// OrigErr returns the original error if one was set. Nil is returned if no +// error was set. This only returns the first element in the list. If the full +// list is needed, use BatchedErrors. +func (b baseError) OrigErr() error { + switch len(b.errs) { + case 0: + return nil + case 1: + return b.errs[0] + default: + if err, ok := b.errs[0].(Error); ok { + return NewBatchError(err.Code(), err.Message(), b.errs[1:]) + } + return NewBatchError("BatchedErrors", + "multiple errors occurred", b.errs) + } +} + +// OrigErrs returns the original errors if one was set. An empty slice is +// returned if no error was set. +func (b baseError) OrigErrs() []error { + return b.errs +} + +// So that the Error interface type can be included as an anonymous field +// in the requestError struct and not conflict with the error.Error() method. +type awsError Error + +// A requestError wraps a request or service error. +// +// Composed of baseError for code, message, and original error. +type requestError struct { + awsError + statusCode int + requestID string + bytes []byte +} + +// newRequestError returns a wrapped error with additional information for +// request status code, and service requestID. +// +// Should be used to wrap all request which involve service requests. Even if +// the request failed without a service response, but had an HTTP status code +// that may be meaningful. +// +// Also wraps original errors via the baseError. +func newRequestError(err Error, statusCode int, requestID string) *requestError { + return &requestError{ + awsError: err, + statusCode: statusCode, + requestID: requestID, + } +} + +// Error returns the string representation of the error. +// Satisfies the error interface. +func (r requestError) Error() string { + extra := fmt.Sprintf("status code: %d, request id: %s", + r.statusCode, r.requestID) + return SprintError(r.Code(), r.Message(), extra, r.OrigErr()) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (r requestError) String() string { + return r.Error() +} + +// StatusCode returns the wrapped status code for the error +func (r requestError) StatusCode() int { + return r.statusCode +} + +// RequestID returns the wrapped requestID +func (r requestError) RequestID() string { + return r.requestID +} + +// OrigErrs returns the original errors if one was set. An empty slice is +// returned if no error was set. +func (r requestError) OrigErrs() []error { + if b, ok := r.awsError.(BatchedErrors); ok { + return b.OrigErrs() + } + return []error{r.OrigErr()} +} + +type unmarshalError struct { + awsError + bytes []byte +} + +// Error returns the string representation of the error. +// Satisfies the error interface. +func (e unmarshalError) Error() string { + extra := hex.Dump(e.bytes) + return SprintError(e.Code(), e.Message(), extra, e.OrigErr()) +} + +// String returns the string representation of the error. +// Alias for Error to satisfy the stringer interface. +func (e unmarshalError) String() string { + return e.Error() +} + +// Bytes returns the bytes that failed to unmarshal. +func (e unmarshalError) Bytes() []byte { + return e.bytes +} + +// An error list that satisfies the golang interface +type errorList []error + +// Error returns the string representation of the error. +// +// Satisfies the error interface. +func (e errorList) Error() string { + msg := "" + // How do we want to handle the array size being zero + if size := len(e); size > 0 { + for i := 0; i < size; i++ { + msg += e[i].Error() + // We check the next index to see if it is within the slice. + // If it is, then we append a newline. We do this, because unit tests + // could be broken with the additional '\n' + if i+1 < size { + msg += "\n" + } + } + } + return msg +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go new file mode 100644 index 000000000..1a3d106d5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go @@ -0,0 +1,108 @@ +package awsutil + +import ( + "io" + "reflect" + "time" +) + +// Copy deeply copies a src structure to dst. Useful for copying request and +// response structures. +// +// Can copy between structs of different type, but will only copy fields which +// are assignable, and exist in both structs. Fields which are not assignable, +// or do not exist in both structs are ignored. +func Copy(dst, src interface{}) { + dstval := reflect.ValueOf(dst) + if !dstval.IsValid() { + panic("Copy dst cannot be nil") + } + + rcopy(dstval, reflect.ValueOf(src), true) +} + +// CopyOf returns a copy of src while also allocating the memory for dst. +// src must be a pointer type or this operation will fail. +func CopyOf(src interface{}) (dst interface{}) { + dsti := reflect.New(reflect.TypeOf(src).Elem()) + dst = dsti.Interface() + rcopy(dsti, reflect.ValueOf(src), true) + return +} + +// rcopy performs a recursive copy of values from the source to destination. +// +// root is used to skip certain aspects of the copy which are not valid +// for the root node of a object. +func rcopy(dst, src reflect.Value, root bool) { + if !src.IsValid() { + return + } + + switch src.Kind() { + case reflect.Ptr: + if _, ok := src.Interface().(io.Reader); ok { + if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() { + dst.Elem().Set(src) + } else if dst.CanSet() { + dst.Set(src) + } + } else { + e := src.Type().Elem() + if dst.CanSet() && !src.IsNil() { + if _, ok := src.Interface().(*time.Time); !ok { + dst.Set(reflect.New(e)) + } else { + tempValue := reflect.New(e) + tempValue.Elem().Set(src.Elem()) + // Sets time.Time's unexported values + dst.Set(tempValue) + } + } + if src.Elem().IsValid() { + // Keep the current root state since the depth hasn't changed + rcopy(dst.Elem(), src.Elem(), root) + } + } + case reflect.Struct: + t := dst.Type() + for i := 0; i < t.NumField(); i++ { + name := t.Field(i).Name + srcVal := src.FieldByName(name) + dstVal := dst.FieldByName(name) + if srcVal.IsValid() && dstVal.CanSet() { + rcopy(dstVal, srcVal, false) + } + } + case reflect.Slice: + if src.IsNil() { + break + } + + s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap()) + dst.Set(s) + for i := 0; i < src.Len(); i++ { + rcopy(dst.Index(i), src.Index(i), false) + } + case reflect.Map: + if src.IsNil() { + break + } + + s := reflect.MakeMap(src.Type()) + dst.Set(s) + for _, k := range src.MapKeys() { + v := src.MapIndex(k) + v2 := reflect.New(v.Type()).Elem() + rcopy(v2, v, false) + dst.SetMapIndex(k, v2) + } + default: + // Assign the value if possible. If its not assignable, the value would + // need to be converted and the impact of that may be unexpected, or is + // not compatible with the dst type. + if src.Type().AssignableTo(dst.Type()) { + dst.Set(src) + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go new file mode 100644 index 000000000..142a7a01c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go @@ -0,0 +1,27 @@ +package awsutil + +import ( + "reflect" +) + +// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual. +// In addition to this, this method will also dereference the input values if +// possible so the DeepEqual performed will not fail if one parameter is a +// pointer and the other is not. +// +// DeepEqual will not perform indirection of nested values of the input parameters. +func DeepEqual(a, b interface{}) bool { + ra := reflect.Indirect(reflect.ValueOf(a)) + rb := reflect.Indirect(reflect.ValueOf(b)) + + if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid { + // If the elements are both nil, and of the same type they are equal + // If they are of different types they are not equal + return reflect.TypeOf(a) == reflect.TypeOf(b) + } else if raValid != rbValid { + // Both values must be valid to be equal + return false + } + + return reflect.DeepEqual(ra.Interface(), rb.Interface()) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go new file mode 100644 index 000000000..285e54d67 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go @@ -0,0 +1,221 @@ +package awsutil + +import ( + "reflect" + "regexp" + "strconv" + "strings" + + "github.com/jmespath/go-jmespath" +) + +var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`) + +// rValuesAtPath returns a slice of values found in value v. The values +// in v are explored recursively so all nested values are collected. +func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value { + pathparts := strings.Split(path, "||") + if len(pathparts) > 1 { + for _, pathpart := range pathparts { + vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm) + if len(vals) > 0 { + return vals + } + } + return nil + } + + values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))} + components := strings.Split(path, ".") + for len(values) > 0 && len(components) > 0 { + var index *int64 + var indexStar bool + c := strings.TrimSpace(components[0]) + if c == "" { // no actual component, illegal syntax + return nil + } else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] { + // TODO normalize case for user + return nil // don't support unexported fields + } + + // parse this component + if m := indexRe.FindStringSubmatch(c); m != nil { + c = m[1] + if m[2] == "" { + index = nil + indexStar = true + } else { + i, _ := strconv.ParseInt(m[2], 10, 32) + index = &i + indexStar = false + } + } + + nextvals := []reflect.Value{} + for _, value := range values { + // pull component name out of struct member + if value.Kind() != reflect.Struct { + continue + } + + if c == "*" { // pull all members + for i := 0; i < value.NumField(); i++ { + if f := reflect.Indirect(value.Field(i)); f.IsValid() { + nextvals = append(nextvals, f) + } + } + continue + } + + value = value.FieldByNameFunc(func(name string) bool { + if c == name { + return true + } else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) { + return true + } + return false + }) + + if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 { + if !value.IsNil() { + value.Set(reflect.Zero(value.Type())) + } + return []reflect.Value{value} + } + + if createPath && value.Kind() == reflect.Ptr && value.IsNil() { + // TODO if the value is the terminus it should not be created + // if the value to be set to its position is nil. + value.Set(reflect.New(value.Type().Elem())) + value = value.Elem() + } else { + value = reflect.Indirect(value) + } + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !createPath && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + + if value.IsValid() { + nextvals = append(nextvals, value) + } + } + values = nextvals + + if indexStar || index != nil { + nextvals = []reflect.Value{} + for _, valItem := range values { + value := reflect.Indirect(valItem) + if value.Kind() != reflect.Slice { + continue + } + + if indexStar { // grab all indices + for i := 0; i < value.Len(); i++ { + idx := reflect.Indirect(value.Index(i)) + if idx.IsValid() { + nextvals = append(nextvals, idx) + } + } + continue + } + + // pull out index + i := int(*index) + if i >= value.Len() { // check out of bounds + if createPath { + // TODO resize slice + } else { + continue + } + } else if i < 0 { // support negative indexing + i = value.Len() + i + } + value = reflect.Indirect(value.Index(i)) + + if value.Kind() == reflect.Slice || value.Kind() == reflect.Map { + if !createPath && value.IsNil() { + value = reflect.ValueOf(nil) + } + } + + if value.IsValid() { + nextvals = append(nextvals, value) + } + } + values = nextvals + } + + components = components[1:] + } + return values +} + +// ValuesAtPath returns a list of values at the case insensitive lexical +// path inside of a structure. +func ValuesAtPath(i interface{}, path string) ([]interface{}, error) { + result, err := jmespath.Search(path, i) + if err != nil { + return nil, err + } + + v := reflect.ValueOf(result) + if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) { + return nil, nil + } + if s, ok := result.([]interface{}); ok { + return s, err + } + if v.Kind() == reflect.Map && v.Len() == 0 { + return nil, nil + } + if v.Kind() == reflect.Slice { + out := make([]interface{}, v.Len()) + for i := 0; i < v.Len(); i++ { + out[i] = v.Index(i).Interface() + } + return out, nil + } + + return []interface{}{result}, nil +} + +// SetValueAtPath sets a value at the case insensitive lexical path inside +// of a structure. +func SetValueAtPath(i interface{}, path string, v interface{}) { + rvals := rValuesAtPath(i, path, true, false, v == nil) + for _, rval := range rvals { + if rval.Kind() == reflect.Ptr && rval.IsNil() { + continue + } + setValue(rval, v) + } +} + +func setValue(dstVal reflect.Value, src interface{}) { + if dstVal.Kind() == reflect.Ptr { + dstVal = reflect.Indirect(dstVal) + } + srcVal := reflect.ValueOf(src) + + if !srcVal.IsValid() { // src is literal nil + if dstVal.CanAddr() { + // Convert to pointer so that pointer's value can be nil'ed + // dstVal = dstVal.Addr() + } + dstVal.Set(reflect.Zero(dstVal.Type())) + + } else if srcVal.Kind() == reflect.Ptr { + if srcVal.IsNil() { + srcVal = reflect.Zero(dstVal.Type()) + } else { + srcVal = reflect.ValueOf(src).Elem() + } + dstVal.Set(srcVal) + } else { + dstVal.Set(srcVal) + } + +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go new file mode 100644 index 000000000..710eb432f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go @@ -0,0 +1,113 @@ +package awsutil + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strings" +) + +// Prettify returns the string representation of a value. +func Prettify(i interface{}) string { + var buf bytes.Buffer + prettify(reflect.ValueOf(i), 0, &buf) + return buf.String() +} + +// prettify will recursively walk value v to build a textual +// representation of the value. +func prettify(v reflect.Value, indent int, buf *bytes.Buffer) { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + strtype := v.Type().String() + if strtype == "time.Time" { + fmt.Fprintf(buf, "%s", v.Interface()) + break + } else if strings.HasPrefix(strtype, "io.") { + buf.WriteString("") + break + } + + buf.WriteString("{\n") + + names := []string{} + for i := 0; i < v.Type().NumField(); i++ { + name := v.Type().Field(i).Name + f := v.Field(i) + if name[0:1] == strings.ToLower(name[0:1]) { + continue // ignore unexported fields + } + if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() { + continue // ignore unset fields + } + names = append(names, name) + } + + for i, n := range names { + val := v.FieldByName(n) + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(n + ": ") + prettify(val, indent+2, buf) + + if i < len(names)-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + case reflect.Slice: + strtype := v.Type().String() + if strtype == "[]uint8" { + fmt.Fprintf(buf, " len %d", v.Len()) + break + } + + nl, id, id2 := "", "", "" + if v.Len() > 3 { + nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) + } + buf.WriteString("[" + nl) + for i := 0; i < v.Len(); i++ { + buf.WriteString(id2) + prettify(v.Index(i), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString("," + nl) + } + } + + buf.WriteString(nl + id + "]") + case reflect.Map: + buf.WriteString("{\n") + + for i, k := range v.MapKeys() { + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(k.String() + ": ") + prettify(v.MapIndex(k), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + default: + if !v.IsValid() { + fmt.Fprint(buf, "") + return + } + format := "%v" + switch v.Interface().(type) { + case string: + format = "%q" + case io.ReadSeeker, io.Reader: + format = "buffer(%p)" + } + fmt.Fprintf(buf, format, v.Interface()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go new file mode 100644 index 000000000..645df2450 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go @@ -0,0 +1,88 @@ +package awsutil + +import ( + "bytes" + "fmt" + "reflect" + "strings" +) + +// StringValue returns the string representation of a value. +func StringValue(i interface{}) string { + var buf bytes.Buffer + stringValue(reflect.ValueOf(i), 0, &buf) + return buf.String() +} + +func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) { + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + buf.WriteString("{\n") + + for i := 0; i < v.Type().NumField(); i++ { + ft := v.Type().Field(i) + fv := v.Field(i) + + if ft.Name[0:1] == strings.ToLower(ft.Name[0:1]) { + continue // ignore unexported fields + } + if (fv.Kind() == reflect.Ptr || fv.Kind() == reflect.Slice) && fv.IsNil() { + continue // ignore unset fields + } + + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(ft.Name + ": ") + + if tag := ft.Tag.Get("sensitive"); tag == "true" { + buf.WriteString("") + } else { + stringValue(fv, indent+2, buf) + } + + buf.WriteString(",\n") + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + case reflect.Slice: + nl, id, id2 := "", "", "" + if v.Len() > 3 { + nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2) + } + buf.WriteString("[" + nl) + for i := 0; i < v.Len(); i++ { + buf.WriteString(id2) + stringValue(v.Index(i), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString("," + nl) + } + } + + buf.WriteString(nl + id + "]") + case reflect.Map: + buf.WriteString("{\n") + + for i, k := range v.MapKeys() { + buf.WriteString(strings.Repeat(" ", indent+2)) + buf.WriteString(k.String() + ": ") + stringValue(v.MapIndex(k), indent+2, buf) + + if i < v.Len()-1 { + buf.WriteString(",\n") + } + } + + buf.WriteString("\n" + strings.Repeat(" ", indent) + "}") + default: + format := "%v" + switch v.Interface().(type) { + case string: + format = "%q" + } + fmt.Fprintf(buf, format, v.Interface()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go new file mode 100644 index 000000000..709605384 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go @@ -0,0 +1,96 @@ +package client + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +// A Config provides configuration to a service client instance. +type Config struct { + Config *aws.Config + Handlers request.Handlers + Endpoint string + SigningRegion string + SigningName string + + // States that the signing name did not come from a modeled source but + // was derived based on other data. Used by service client constructors + // to determine if the signin name can be overridden based on metadata the + // service has. + SigningNameDerived bool +} + +// ConfigProvider provides a generic way for a service client to receive +// the ClientConfig without circular dependencies. +type ConfigProvider interface { + ClientConfig(serviceName string, cfgs ...*aws.Config) Config +} + +// ConfigNoResolveEndpointProvider same as ConfigProvider except it will not +// resolve the endpoint automatically. The service client's endpoint must be +// provided via the aws.Config.Endpoint field. +type ConfigNoResolveEndpointProvider interface { + ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) Config +} + +// A Client implements the base client request and response handling +// used by all service clients. +type Client struct { + request.Retryer + metadata.ClientInfo + + Config aws.Config + Handlers request.Handlers +} + +// New will return a pointer to a new initialized service client. +func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client { + svc := &Client{ + Config: cfg, + ClientInfo: info, + Handlers: handlers.Copy(), + } + + switch retryer, ok := cfg.Retryer.(request.Retryer); { + case ok: + svc.Retryer = retryer + case cfg.Retryer != nil && cfg.Logger != nil: + s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer) + cfg.Logger.Log(s) + fallthrough + default: + maxRetries := aws.IntValue(cfg.MaxRetries) + if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries { + maxRetries = 3 + } + svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries} + } + + svc.AddDebugHandlers() + + for _, option := range options { + option(svc) + } + + return svc +} + +// NewRequest returns a new Request pointer for the service API +// operation and parameters. +func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request { + return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data) +} + +// AddDebugHandlers injects debug logging handlers into the service to log request +// debug information. +func (c *Client) AddDebugHandlers() { + if !c.Config.LogLevel.AtLeast(aws.LogDebug) { + return + } + + c.Handlers.Send.PushFrontNamed(LogHTTPRequestHandler) + c.Handlers.Send.PushBackNamed(LogHTTPResponseHandler) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go new file mode 100644 index 000000000..1df4b992d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go @@ -0,0 +1,103 @@ +package client + +import ( + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/sdkrand" +) + +// DefaultRetryer implements basic retry logic using exponential backoff for +// most services. If you want to implement custom retry logic, implement the +// request.Retryer interface or create a structure type that composes this +// struct and override the specific methods. For example, to override only +// the MaxRetries method: +// +// type retryer struct { +// client.DefaultRetryer +// } +// +// // This implementation always has 100 max retries +// func (d retryer) MaxRetries() int { return 100 } +type DefaultRetryer struct { + NumMaxRetries int +} + +// MaxRetries returns the number of maximum returns the service will use to make +// an individual API request. +func (d DefaultRetryer) MaxRetries() int { + return d.NumMaxRetries +} + +// RetryRules returns the delay duration before retrying this request again +func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration { + // Set the upper limit of delay in retrying at ~five minutes + minTime := 30 + isThrottle := r.IsErrorThrottle() + if isThrottle { + if delay, ok := getRetryDelay(r); ok { + return delay + } + + minTime = 500 + } + + retryCount := r.RetryCount + if isThrottle && retryCount > 8 { + retryCount = 8 + } else if retryCount > 13 { + retryCount = 13 + } + + delay := (1 << uint(retryCount)) * (sdkrand.SeededRand.Intn(minTime) + minTime) + return time.Duration(delay) * time.Millisecond +} + +// ShouldRetry returns true if the request should be retried. +func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { + // If one of the other handlers already set the retry state + // we don't want to override it based on the service's state + if r.Retryable != nil { + return *r.Retryable + } + + if r.HTTPResponse.StatusCode >= 500 && r.HTTPResponse.StatusCode != 501 { + return true + } + + return r.IsErrorRetryable() || r.IsErrorThrottle() +} + +// This will look in the Retry-After header, RFC 7231, for how long +// it will wait before attempting another request +func getRetryDelay(r *request.Request) (time.Duration, bool) { + if !canUseRetryAfterHeader(r) { + return 0, false + } + + delayStr := r.HTTPResponse.Header.Get("Retry-After") + if len(delayStr) == 0 { + return 0, false + } + + delay, err := strconv.Atoi(delayStr) + if err != nil { + return 0, false + } + + return time.Duration(delay) * time.Second, true +} + +// Will look at the status code to see if the retry header pertains to +// the status code. +func canUseRetryAfterHeader(r *request.Request) bool { + switch r.HTTPResponse.StatusCode { + case 429: + case 503: + default: + return false + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go b/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go new file mode 100644 index 000000000..8958c32d4 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/logger.go @@ -0,0 +1,194 @@ +package client + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http/httputil" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +const logReqMsg = `DEBUG: Request %s/%s Details: +---[ REQUEST POST-SIGN ]----------------------------- +%s +-----------------------------------------------------` + +const logReqErrMsg = `DEBUG ERROR: Request %s/%s: +---[ REQUEST DUMP ERROR ]----------------------------- +%s +------------------------------------------------------` + +type logWriter struct { + // Logger is what we will use to log the payload of a response. + Logger aws.Logger + // buf stores the contents of what has been read + buf *bytes.Buffer +} + +func (logger *logWriter) Write(b []byte) (int, error) { + return logger.buf.Write(b) +} + +type teeReaderCloser struct { + // io.Reader will be a tee reader that is used during logging. + // This structure will read from a body and write the contents to a logger. + io.Reader + // Source is used just to close when we are done reading. + Source io.ReadCloser +} + +func (reader *teeReaderCloser) Close() error { + return reader.Source.Close() +} + +// LogHTTPRequestHandler is a SDK request handler to log the HTTP request sent +// to a service. Will include the HTTP request body if the LogLevel of the +// request matches LogDebugWithHTTPBody. +var LogHTTPRequestHandler = request.NamedHandler{ + Name: "awssdk.client.LogRequest", + Fn: logRequest, +} + +func logRequest(r *request.Request) { + logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) + bodySeekable := aws.IsReaderSeekable(r.Body) + + b, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + + if logBody { + if !bodySeekable { + r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body)) + } + // Reset the request body because dumpRequest will re-wrap the + // r.HTTPRequest's Body as a NoOpCloser and will not be reset after + // read by the HTTP client reader. + if err := r.Error; err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + } + + r.Config.Logger.Log(fmt.Sprintf(logReqMsg, + r.ClientInfo.ServiceName, r.Operation.Name, string(b))) +} + +// LogHTTPRequestHeaderHandler is a SDK request handler to log the HTTP request sent +// to a service. Will only log the HTTP request's headers. The request payload +// will not be read. +var LogHTTPRequestHeaderHandler = request.NamedHandler{ + Name: "awssdk.client.LogRequestHeader", + Fn: logRequestHeader, +} + +func logRequestHeader(r *request.Request) { + b, err := httputil.DumpRequestOut(r.HTTPRequest, false) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + + r.Config.Logger.Log(fmt.Sprintf(logReqMsg, + r.ClientInfo.ServiceName, r.Operation.Name, string(b))) +} + +const logRespMsg = `DEBUG: Response %s/%s Details: +---[ RESPONSE ]-------------------------------------- +%s +-----------------------------------------------------` + +const logRespErrMsg = `DEBUG ERROR: Response %s/%s: +---[ RESPONSE DUMP ERROR ]----------------------------- +%s +-----------------------------------------------------` + +// LogHTTPResponseHandler is a SDK request handler to log the HTTP response +// received from a service. Will include the HTTP response body if the LogLevel +// of the request matches LogDebugWithHTTPBody. +var LogHTTPResponseHandler = request.NamedHandler{ + Name: "awssdk.client.LogResponse", + Fn: logResponse, +} + +func logResponse(r *request.Request) { + lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)} + + if r.HTTPResponse == nil { + lw.Logger.Log(fmt.Sprintf(logRespErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, "request's HTTPResponse is nil")) + return + } + + logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) + if logBody { + r.HTTPResponse.Body = &teeReaderCloser{ + Reader: io.TeeReader(r.HTTPResponse.Body, lw), + Source: r.HTTPResponse.Body, + } + } + + handlerFn := func(req *request.Request) { + b, err := httputil.DumpResponse(req.HTTPResponse, false) + if err != nil { + lw.Logger.Log(fmt.Sprintf(logRespErrMsg, + req.ClientInfo.ServiceName, req.Operation.Name, err)) + return + } + + lw.Logger.Log(fmt.Sprintf(logRespMsg, + req.ClientInfo.ServiceName, req.Operation.Name, string(b))) + + if logBody { + b, err := ioutil.ReadAll(lw.buf) + if err != nil { + lw.Logger.Log(fmt.Sprintf(logRespErrMsg, + req.ClientInfo.ServiceName, req.Operation.Name, err)) + return + } + + lw.Logger.Log(string(b)) + } + } + + const handlerName = "awsdk.client.LogResponse.ResponseBody" + + r.Handlers.Unmarshal.SetBackNamed(request.NamedHandler{ + Name: handlerName, Fn: handlerFn, + }) + r.Handlers.UnmarshalError.SetBackNamed(request.NamedHandler{ + Name: handlerName, Fn: handlerFn, + }) +} + +// LogHTTPResponseHeaderHandler is a SDK request handler to log the HTTP +// response received from a service. Will only log the HTTP response's headers. +// The response payload will not be read. +var LogHTTPResponseHeaderHandler = request.NamedHandler{ + Name: "awssdk.client.LogResponseHeader", + Fn: logResponseHeader, +} + +func logResponseHeader(r *request.Request) { + if r.Config.Logger == nil { + return + } + + b, err := httputil.DumpResponse(r.HTTPResponse, false) + if err != nil { + r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, + r.ClientInfo.ServiceName, r.Operation.Name, err)) + return + } + + r.Config.Logger.Log(fmt.Sprintf(logRespMsg, + r.ClientInfo.ServiceName, r.Operation.Name, string(b))) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go b/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go new file mode 100644 index 000000000..920e9fddf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go @@ -0,0 +1,13 @@ +package metadata + +// ClientInfo wraps immutable data from the client.Client structure. +type ClientInfo struct { + ServiceName string + ServiceID string + APIVersion string + Endpoint string + SigningName string + SigningRegion string + JSONVersion string + TargetPrefix string +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go new file mode 100644 index 000000000..fd1e240f6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go @@ -0,0 +1,536 @@ +package aws + +import ( + "net/http" + "time" + + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/endpoints" +) + +// UseServiceDefaultRetries instructs the config to use the service's own +// default number of retries. This will be the default action if +// Config.MaxRetries is nil also. +const UseServiceDefaultRetries = -1 + +// RequestRetryer is an alias for a type that implements the request.Retryer +// interface. +type RequestRetryer interface{} + +// A Config provides service configuration for service clients. By default, +// all clients will use the defaults.DefaultConfig structure. +// +// // Create Session with MaxRetries configuration to be shared by multiple +// // service clients. +// sess := session.Must(session.NewSession(&aws.Config{ +// MaxRetries: aws.Int(3), +// })) +// +// // Create S3 service client with a specific Region. +// svc := s3.New(sess, &aws.Config{ +// Region: aws.String("us-west-2"), +// }) +type Config struct { + // Enables verbose error printing of all credential chain errors. + // Should be used when wanting to see all errors while attempting to + // retrieve credentials. + CredentialsChainVerboseErrors *bool + + // The credentials object to use when signing requests. Defaults to a + // chain of credential providers to search for credentials in environment + // variables, shared credential file, and EC2 Instance Roles. + Credentials *credentials.Credentials + + // An optional endpoint URL (hostname only or fully qualified URI) + // that overrides the default generated endpoint for a client. Set this + // to `""` to use the default generated endpoint. + // + // Note: You must still provide a `Region` value when specifying an + // endpoint for a client. + Endpoint *string + + // The resolver to use for looking up endpoints for AWS service clients + // to use based on region. + EndpointResolver endpoints.Resolver + + // EnforceShouldRetryCheck is used in the AfterRetryHandler to always call + // ShouldRetry regardless of whether or not if request.Retryable is set. + // This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck + // is not set, then ShouldRetry will only be called if request.Retryable is nil. + // Proper handling of the request.Retryable field is important when setting this field. + EnforceShouldRetryCheck *bool + + // The region to send requests to. This parameter is required and must + // be configured globally or on a per-client basis unless otherwise + // noted. A full list of regions is found in the "Regions and Endpoints" + // document. + // + // See http://docs.aws.amazon.com/general/latest/gr/rande.html for AWS + // Regions and Endpoints. + Region *string + + // Set this to `true` to disable SSL when sending requests. Defaults + // to `false`. + DisableSSL *bool + + // The HTTP client to use when sending requests. Defaults to + // `http.DefaultClient`. + HTTPClient *http.Client + + // An integer value representing the logging level. The default log level + // is zero (LogOff), which represents no logging. To enable logging set + // to a LogLevel Value. + LogLevel *LogLevelType + + // The logger writer interface to write logging messages to. Defaults to + // standard out. + Logger Logger + + // The maximum number of times that a request will be retried for failures. + // Defaults to -1, which defers the max retry setting to the service + // specific configuration. + MaxRetries *int + + // Retryer guides how HTTP requests should be retried in case of + // recoverable failures. + // + // When nil or the value does not implement the request.Retryer interface, + // the client.DefaultRetryer will be used. + // + // When both Retryer and MaxRetries are non-nil, the former is used and + // the latter ignored. + // + // To set the Retryer field in a type-safe manner and with chaining, use + // the request.WithRetryer helper function: + // + // cfg := request.WithRetryer(aws.NewConfig(), myRetryer) + // + Retryer RequestRetryer + + // Disables semantic parameter validation, which validates input for + // missing required fields and/or other semantic request input errors. + DisableParamValidation *bool + + // Disables the computation of request and response checksums, e.g., + // CRC32 checksums in Amazon DynamoDB. + DisableComputeChecksums *bool + + // Set this to `true` to force the request to use path-style addressing, + // i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client + // will use virtual hosted bucket addressing when possible + // (`http://BUCKET.s3.amazonaws.com/KEY`). + // + // Note: This configuration option is specific to the Amazon S3 service. + // + // See http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html + // for Amazon S3: Virtual Hosting of Buckets + S3ForcePathStyle *bool + + // Set this to `true` to disable the SDK adding the `Expect: 100-Continue` + // header to PUT requests over 2MB of content. 100-Continue instructs the + // HTTP client not to send the body until the service responds with a + // `continue` status. This is useful to prevent sending the request body + // until after the request is authenticated, and validated. + // + // http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html + // + // 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s + // `ExpectContinueTimeout` for information on adjusting the continue wait + // timeout. https://golang.org/pkg/net/http/#Transport + // + // You should use this flag to disble 100-Continue if you experience issues + // with proxies or third party S3 compatible services. + S3Disable100Continue *bool + + // Set this to `true` to enable S3 Accelerate feature. For all operations + // compatible with S3 Accelerate will use the accelerate endpoint for + // requests. Requests not compatible will fall back to normal S3 requests. + // + // The bucket must be enable for accelerate to be used with S3 client with + // accelerate enabled. If the bucket is not enabled for accelerate an error + // will be returned. The bucket name must be DNS compatible to also work + // with accelerate. + S3UseAccelerate *bool + + // S3DisableContentMD5Validation config option is temporarily disabled, + // For S3 GetObject API calls, #1837. + // + // Set this to `true` to disable the S3 service client from automatically + // adding the ContentMD5 to S3 Object Put and Upload API calls. This option + // will also disable the SDK from performing object ContentMD5 validation + // on GetObject API calls. + S3DisableContentMD5Validation *bool + + // Set this to `true` to disable the EC2Metadata client from overriding the + // default http.Client's Timeout. This is helpful if you do not want the + // EC2Metadata client to create a new http.Client. This options is only + // meaningful if you're not already using a custom HTTP client with the + // SDK. Enabled by default. + // + // Must be set and provided to the session.NewSession() in order to disable + // the EC2Metadata overriding the timeout for default credentials chain. + // + // Example: + // sess := session.Must(session.NewSession(aws.NewConfig() + // .WithEC2MetadataDiableTimeoutOverride(true))) + // + // svc := s3.New(sess) + // + EC2MetadataDisableTimeoutOverride *bool + + // Instructs the endpoint to be generated for a service client to + // be the dual stack endpoint. The dual stack endpoint will support + // both IPv4 and IPv6 addressing. + // + // Setting this for a service which does not support dual stack will fail + // to make requets. It is not recommended to set this value on the session + // as it will apply to all service clients created with the session. Even + // services which don't support dual stack endpoints. + // + // If the Endpoint config value is also provided the UseDualStack flag + // will be ignored. + // + // Only supported with. + // + // sess := session.Must(session.NewSession()) + // + // svc := s3.New(sess, &aws.Config{ + // UseDualStack: aws.Bool(true), + // }) + UseDualStack *bool + + // SleepDelay is an override for the func the SDK will call when sleeping + // during the lifecycle of a request. Specifically this will be used for + // request delays. This value should only be used for testing. To adjust + // the delay of a request see the aws/client.DefaultRetryer and + // aws/request.Retryer. + // + // SleepDelay will prevent any Context from being used for canceling retry + // delay of an API operation. It is recommended to not use SleepDelay at all + // and specify a Retryer instead. + SleepDelay func(time.Duration) + + // DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests. + // Will default to false. This would only be used for empty directory names in s3 requests. + // + // Example: + // sess := session.Must(session.NewSession(&aws.Config{ + // DisableRestProtocolURICleaning: aws.Bool(true), + // })) + // + // svc := s3.New(sess) + // out, err := svc.GetObject(&s3.GetObjectInput { + // Bucket: aws.String("bucketname"), + // Key: aws.String("//foo//bar//moo"), + // }) + DisableRestProtocolURICleaning *bool + + // EnableEndpointDiscovery will allow for endpoint discovery on operations that + // have the definition in its model. By default, endpoint discovery is off. + // + // Example: + // sess := session.Must(session.NewSession(&aws.Config{ + // EnableEndpointDiscovery: aws.Bool(true), + // })) + // + // svc := s3.New(sess) + // out, err := svc.GetObject(&s3.GetObjectInput { + // Bucket: aws.String("bucketname"), + // Key: aws.String("/foo/bar/moo"), + // }) + EnableEndpointDiscovery *bool + + // DisableEndpointHostPrefix will disable the SDK's behavior of prefixing + // request endpoint hosts with modeled information. + // + // Disabling this feature is useful when you want to use local endpoints + // for testing that do not support the modeled host prefix pattern. + DisableEndpointHostPrefix *bool +} + +// NewConfig returns a new Config pointer that can be chained with builder +// methods to set multiple configuration values inline without using pointers. +// +// // Create Session with MaxRetries configuration to be shared by multiple +// // service clients. +// sess := session.Must(session.NewSession(aws.NewConfig(). +// WithMaxRetries(3), +// )) +// +// // Create S3 service client with a specific Region. +// svc := s3.New(sess, aws.NewConfig(). +// WithRegion("us-west-2"), +// ) +func NewConfig() *Config { + return &Config{} +} + +// WithCredentialsChainVerboseErrors sets a config verbose errors boolean and returning +// a Config pointer. +func (c *Config) WithCredentialsChainVerboseErrors(verboseErrs bool) *Config { + c.CredentialsChainVerboseErrors = &verboseErrs + return c +} + +// WithCredentials sets a config Credentials value returning a Config pointer +// for chaining. +func (c *Config) WithCredentials(creds *credentials.Credentials) *Config { + c.Credentials = creds + return c +} + +// WithEndpoint sets a config Endpoint value returning a Config pointer for +// chaining. +func (c *Config) WithEndpoint(endpoint string) *Config { + c.Endpoint = &endpoint + return c +} + +// WithEndpointResolver sets a config EndpointResolver value returning a +// Config pointer for chaining. +func (c *Config) WithEndpointResolver(resolver endpoints.Resolver) *Config { + c.EndpointResolver = resolver + return c +} + +// WithRegion sets a config Region value returning a Config pointer for +// chaining. +func (c *Config) WithRegion(region string) *Config { + c.Region = ®ion + return c +} + +// WithDisableSSL sets a config DisableSSL value returning a Config pointer +// for chaining. +func (c *Config) WithDisableSSL(disable bool) *Config { + c.DisableSSL = &disable + return c +} + +// WithHTTPClient sets a config HTTPClient value returning a Config pointer +// for chaining. +func (c *Config) WithHTTPClient(client *http.Client) *Config { + c.HTTPClient = client + return c +} + +// WithMaxRetries sets a config MaxRetries value returning a Config pointer +// for chaining. +func (c *Config) WithMaxRetries(max int) *Config { + c.MaxRetries = &max + return c +} + +// WithDisableParamValidation sets a config DisableParamValidation value +// returning a Config pointer for chaining. +func (c *Config) WithDisableParamValidation(disable bool) *Config { + c.DisableParamValidation = &disable + return c +} + +// WithDisableComputeChecksums sets a config DisableComputeChecksums value +// returning a Config pointer for chaining. +func (c *Config) WithDisableComputeChecksums(disable bool) *Config { + c.DisableComputeChecksums = &disable + return c +} + +// WithLogLevel sets a config LogLevel value returning a Config pointer for +// chaining. +func (c *Config) WithLogLevel(level LogLevelType) *Config { + c.LogLevel = &level + return c +} + +// WithLogger sets a config Logger value returning a Config pointer for +// chaining. +func (c *Config) WithLogger(logger Logger) *Config { + c.Logger = logger + return c +} + +// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config +// pointer for chaining. +func (c *Config) WithS3ForcePathStyle(force bool) *Config { + c.S3ForcePathStyle = &force + return c +} + +// WithS3Disable100Continue sets a config S3Disable100Continue value returning +// a Config pointer for chaining. +func (c *Config) WithS3Disable100Continue(disable bool) *Config { + c.S3Disable100Continue = &disable + return c +} + +// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config +// pointer for chaining. +func (c *Config) WithS3UseAccelerate(enable bool) *Config { + c.S3UseAccelerate = &enable + return c + +} + +// WithS3DisableContentMD5Validation sets a config +// S3DisableContentMD5Validation value returning a Config pointer for chaining. +func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config { + c.S3DisableContentMD5Validation = &enable + return c + +} + +// WithUseDualStack sets a config UseDualStack value returning a Config +// pointer for chaining. +func (c *Config) WithUseDualStack(enable bool) *Config { + c.UseDualStack = &enable + return c +} + +// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value +// returning a Config pointer for chaining. +func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config { + c.EC2MetadataDisableTimeoutOverride = &enable + return c +} + +// WithSleepDelay overrides the function used to sleep while waiting for the +// next retry. Defaults to time.Sleep. +func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config { + c.SleepDelay = fn + return c +} + +// WithEndpointDiscovery will set whether or not to use endpoint discovery. +func (c *Config) WithEndpointDiscovery(t bool) *Config { + c.EnableEndpointDiscovery = &t + return c +} + +// WithDisableEndpointHostPrefix will set whether or not to use modeled host prefix +// when making requests. +func (c *Config) WithDisableEndpointHostPrefix(t bool) *Config { + c.DisableEndpointHostPrefix = &t + return c +} + +// MergeIn merges the passed in configs into the existing config object. +func (c *Config) MergeIn(cfgs ...*Config) { + for _, other := range cfgs { + mergeInConfig(c, other) + } +} + +func mergeInConfig(dst *Config, other *Config) { + if other == nil { + return + } + + if other.CredentialsChainVerboseErrors != nil { + dst.CredentialsChainVerboseErrors = other.CredentialsChainVerboseErrors + } + + if other.Credentials != nil { + dst.Credentials = other.Credentials + } + + if other.Endpoint != nil { + dst.Endpoint = other.Endpoint + } + + if other.EndpointResolver != nil { + dst.EndpointResolver = other.EndpointResolver + } + + if other.Region != nil { + dst.Region = other.Region + } + + if other.DisableSSL != nil { + dst.DisableSSL = other.DisableSSL + } + + if other.HTTPClient != nil { + dst.HTTPClient = other.HTTPClient + } + + if other.LogLevel != nil { + dst.LogLevel = other.LogLevel + } + + if other.Logger != nil { + dst.Logger = other.Logger + } + + if other.MaxRetries != nil { + dst.MaxRetries = other.MaxRetries + } + + if other.Retryer != nil { + dst.Retryer = other.Retryer + } + + if other.DisableParamValidation != nil { + dst.DisableParamValidation = other.DisableParamValidation + } + + if other.DisableComputeChecksums != nil { + dst.DisableComputeChecksums = other.DisableComputeChecksums + } + + if other.S3ForcePathStyle != nil { + dst.S3ForcePathStyle = other.S3ForcePathStyle + } + + if other.S3Disable100Continue != nil { + dst.S3Disable100Continue = other.S3Disable100Continue + } + + if other.S3UseAccelerate != nil { + dst.S3UseAccelerate = other.S3UseAccelerate + } + + if other.S3DisableContentMD5Validation != nil { + dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation + } + + if other.UseDualStack != nil { + dst.UseDualStack = other.UseDualStack + } + + if other.EC2MetadataDisableTimeoutOverride != nil { + dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride + } + + if other.SleepDelay != nil { + dst.SleepDelay = other.SleepDelay + } + + if other.DisableRestProtocolURICleaning != nil { + dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning + } + + if other.EnforceShouldRetryCheck != nil { + dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck + } + + if other.EnableEndpointDiscovery != nil { + dst.EnableEndpointDiscovery = other.EnableEndpointDiscovery + } + + if other.DisableEndpointHostPrefix != nil { + dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix + } +} + +// Copy will return a shallow copy of the Config object. If any additional +// configurations are provided they will be merged into the new config returned. +func (c *Config) Copy(cfgs ...*Config) *Config { + dst := &Config{} + dst.MergeIn(c) + + for _, cfg := range cfgs { + dst.MergeIn(cfg) + } + + return dst +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go b/vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go new file mode 100644 index 000000000..2866f9a7f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go @@ -0,0 +1,37 @@ +// +build !go1.9 + +package aws + +import "time" + +// Context is an copy of the Go v1.7 stdlib's context.Context interface. +// It is represented as a SDK interface to enable you to use the "WithContext" +// API methods with Go v1.6 and a Context type such as golang.org/x/net/context. +// +// See https://golang.org/pkg/context on how to use contexts. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + Value(key interface{}) interface{} +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go b/vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go new file mode 100644 index 000000000..3718b26e1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go @@ -0,0 +1,11 @@ +// +build go1.9 + +package aws + +import "context" + +// Context is an alias of the Go stdlib's context.Context interface. +// It can be used within the SDK's API operation "WithContext" methods. +// +// See https://golang.org/pkg/context on how to use contexts. +type Context = context.Context diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go b/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go new file mode 100644 index 000000000..66c5945db --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go @@ -0,0 +1,56 @@ +// +build !go1.7 + +package aws + +import "time" + +// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to +// provide a 1.6 and 1.5 safe version of context that is compatible with Go +// 1.7's Context. +// +// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// struct{}, since vars of this type must have distinct addresses. +type emptyCtx int + +func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { + return +} + +func (*emptyCtx) Done() <-chan struct{} { + return nil +} + +func (*emptyCtx) Err() error { + return nil +} + +func (*emptyCtx) Value(key interface{}) interface{} { + return nil +} + +func (e *emptyCtx) String() string { + switch e { + case backgroundCtx: + return "aws.BackgroundContext" + } + return "unknown empty Context" +} + +var ( + backgroundCtx = new(emptyCtx) +) + +// BackgroundContext returns a context that will never be canceled, has no +// values, and no deadline. This context is used by the SDK to provide +// backwards compatibility with non-context API operations and functionality. +// +// Go 1.6 and before: +// This context function is equivalent to context.Background in the Go stdlib. +// +// Go 1.7 and later: +// The context returned will be the value returned by context.Background() +// +// See https://golang.org/pkg/context for more information on Contexts. +func BackgroundContext() Context { + return backgroundCtx +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go new file mode 100644 index 000000000..9c29f29af --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go @@ -0,0 +1,20 @@ +// +build go1.7 + +package aws + +import "context" + +// BackgroundContext returns a context that will never be canceled, has no +// values, and no deadline. This context is used by the SDK to provide +// backwards compatibility with non-context API operations and functionality. +// +// Go 1.6 and before: +// This context function is equivalent to context.Background in the Go stdlib. +// +// Go 1.7 and later: +// The context returned will be the value returned by context.Background() +// +// See https://golang.org/pkg/context for more information on Contexts. +func BackgroundContext() Context { + return context.Background() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go b/vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go new file mode 100644 index 000000000..304fd1561 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go @@ -0,0 +1,24 @@ +package aws + +import ( + "time" +) + +// SleepWithContext will wait for the timer duration to expire, or the context +// is canceled. Which ever happens first. If the context is canceled the Context's +// error will be returned. +// +// Expects Context to always return a non-nil error if the Done channel is closed. +func SleepWithContext(ctx Context, dur time.Duration) error { + t := time.NewTimer(dur) + defer t.Stop() + + select { + case <-t.C: + break + case <-ctx.Done(): + return ctx.Err() + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go b/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go new file mode 100644 index 000000000..ff5d58e06 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/convert_types.go @@ -0,0 +1,387 @@ +package aws + +import "time" + +// String returns a pointer to the string value passed in. +func String(v string) *string { + return &v +} + +// StringValue returns the value of the string pointer passed in or +// "" if the pointer is nil. +func StringValue(v *string) string { + if v != nil { + return *v + } + return "" +} + +// StringSlice converts a slice of string values into a slice of +// string pointers +func StringSlice(src []string) []*string { + dst := make([]*string, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// StringValueSlice converts a slice of string pointers into a slice of +// string values +func StringValueSlice(src []*string) []string { + dst := make([]string, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// StringMap converts a string map of string values into a string +// map of string pointers +func StringMap(src map[string]string) map[string]*string { + dst := make(map[string]*string) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// StringValueMap converts a string map of string pointers into a string +// map of string values +func StringValueMap(src map[string]*string) map[string]string { + dst := make(map[string]string) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Bool returns a pointer to the bool value passed in. +func Bool(v bool) *bool { + return &v +} + +// BoolValue returns the value of the bool pointer passed in or +// false if the pointer is nil. +func BoolValue(v *bool) bool { + if v != nil { + return *v + } + return false +} + +// BoolSlice converts a slice of bool values into a slice of +// bool pointers +func BoolSlice(src []bool) []*bool { + dst := make([]*bool, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// BoolValueSlice converts a slice of bool pointers into a slice of +// bool values +func BoolValueSlice(src []*bool) []bool { + dst := make([]bool, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// BoolMap converts a string map of bool values into a string +// map of bool pointers +func BoolMap(src map[string]bool) map[string]*bool { + dst := make(map[string]*bool) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// BoolValueMap converts a string map of bool pointers into a string +// map of bool values +func BoolValueMap(src map[string]*bool) map[string]bool { + dst := make(map[string]bool) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int returns a pointer to the int value passed in. +func Int(v int) *int { + return &v +} + +// IntValue returns the value of the int pointer passed in or +// 0 if the pointer is nil. +func IntValue(v *int) int { + if v != nil { + return *v + } + return 0 +} + +// IntSlice converts a slice of int values into a slice of +// int pointers +func IntSlice(src []int) []*int { + dst := make([]*int, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// IntValueSlice converts a slice of int pointers into a slice of +// int values +func IntValueSlice(src []*int) []int { + dst := make([]int, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// IntMap converts a string map of int values into a string +// map of int pointers +func IntMap(src map[string]int) map[string]*int { + dst := make(map[string]*int) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// IntValueMap converts a string map of int pointers into a string +// map of int values +func IntValueMap(src map[string]*int) map[string]int { + dst := make(map[string]int) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Int64 returns a pointer to the int64 value passed in. +func Int64(v int64) *int64 { + return &v +} + +// Int64Value returns the value of the int64 pointer passed in or +// 0 if the pointer is nil. +func Int64Value(v *int64) int64 { + if v != nil { + return *v + } + return 0 +} + +// Int64Slice converts a slice of int64 values into a slice of +// int64 pointers +func Int64Slice(src []int64) []*int64 { + dst := make([]*int64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Int64ValueSlice converts a slice of int64 pointers into a slice of +// int64 values +func Int64ValueSlice(src []*int64) []int64 { + dst := make([]int64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Int64Map converts a string map of int64 values into a string +// map of int64 pointers +func Int64Map(src map[string]int64) map[string]*int64 { + dst := make(map[string]*int64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Int64ValueMap converts a string map of int64 pointers into a string +// map of int64 values +func Int64ValueMap(src map[string]*int64) map[string]int64 { + dst := make(map[string]int64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Float64 returns a pointer to the float64 value passed in. +func Float64(v float64) *float64 { + return &v +} + +// Float64Value returns the value of the float64 pointer passed in or +// 0 if the pointer is nil. +func Float64Value(v *float64) float64 { + if v != nil { + return *v + } + return 0 +} + +// Float64Slice converts a slice of float64 values into a slice of +// float64 pointers +func Float64Slice(src []float64) []*float64 { + dst := make([]*float64, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// Float64ValueSlice converts a slice of float64 pointers into a slice of +// float64 values +func Float64ValueSlice(src []*float64) []float64 { + dst := make([]float64, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// Float64Map converts a string map of float64 values into a string +// map of float64 pointers +func Float64Map(src map[string]float64) map[string]*float64 { + dst := make(map[string]*float64) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// Float64ValueMap converts a string map of float64 pointers into a string +// map of float64 values +func Float64ValueMap(src map[string]*float64) map[string]float64 { + dst := make(map[string]float64) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} + +// Time returns a pointer to the time.Time value passed in. +func Time(v time.Time) *time.Time { + return &v +} + +// TimeValue returns the value of the time.Time pointer passed in or +// time.Time{} if the pointer is nil. +func TimeValue(v *time.Time) time.Time { + if v != nil { + return *v + } + return time.Time{} +} + +// SecondsTimeValue converts an int64 pointer to a time.Time value +// representing seconds since Epoch or time.Time{} if the pointer is nil. +func SecondsTimeValue(v *int64) time.Time { + if v != nil { + return time.Unix((*v / 1000), 0) + } + return time.Time{} +} + +// MillisecondsTimeValue converts an int64 pointer to a time.Time value +// representing milliseconds sinch Epoch or time.Time{} if the pointer is nil. +func MillisecondsTimeValue(v *int64) time.Time { + if v != nil { + return time.Unix(0, (*v * 1000000)) + } + return time.Time{} +} + +// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC". +// The result is undefined if the Unix time cannot be represented by an int64. +// Which includes calling TimeUnixMilli on a zero Time is undefined. +// +// This utility is useful for service API's such as CloudWatch Logs which require +// their unix time values to be in milliseconds. +// +// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information. +func TimeUnixMilli(t time.Time) int64 { + return t.UnixNano() / int64(time.Millisecond/time.Nanosecond) +} + +// TimeSlice converts a slice of time.Time values into a slice of +// time.Time pointers +func TimeSlice(src []time.Time) []*time.Time { + dst := make([]*time.Time, len(src)) + for i := 0; i < len(src); i++ { + dst[i] = &(src[i]) + } + return dst +} + +// TimeValueSlice converts a slice of time.Time pointers into a slice of +// time.Time values +func TimeValueSlice(src []*time.Time) []time.Time { + dst := make([]time.Time, len(src)) + for i := 0; i < len(src); i++ { + if src[i] != nil { + dst[i] = *(src[i]) + } + } + return dst +} + +// TimeMap converts a string map of time.Time values into a string +// map of time.Time pointers +func TimeMap(src map[string]time.Time) map[string]*time.Time { + dst := make(map[string]*time.Time) + for k, val := range src { + v := val + dst[k] = &v + } + return dst +} + +// TimeValueMap converts a string map of time.Time pointers into a string +// map of time.Time values +func TimeValueMap(src map[string]*time.Time) map[string]time.Time { + dst := make(map[string]time.Time) + for k, val := range src { + if val != nil { + dst[k] = *val + } + } + return dst +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go new file mode 100644 index 000000000..0c60e612e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go @@ -0,0 +1,230 @@ +package corehandlers + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "regexp" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" +) + +// Interface for matching types which also have a Len method. +type lener interface { + Len() int +} + +// BuildContentLengthHandler builds the content length of a request based on the body, +// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable +// to determine request body length and no "Content-Length" was specified it will panic. +// +// The Content-Length will only be added to the request if the length of the body +// is greater than 0. If the body is empty or the current `Content-Length` +// header is <= 0, the header will also be stripped. +var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) { + var length int64 + + if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" { + length, _ = strconv.ParseInt(slength, 10, 64) + } else { + if r.Body != nil { + var err error + length, err = aws.SeekerLen(r.Body) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to get request body's length", err) + return + } + } + } + + if length > 0 { + r.HTTPRequest.ContentLength = length + r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length)) + } else { + r.HTTPRequest.ContentLength = 0 + r.HTTPRequest.Header.Del("Content-Length") + } +}} + +var reStatusCode = regexp.MustCompile(`^(\d{3})`) + +// ValidateReqSigHandler is a request handler to ensure that the request's +// signature doesn't expire before it is sent. This can happen when a request +// is built and signed significantly before it is sent. Or significant delays +// occur when retrying requests that would cause the signature to expire. +var ValidateReqSigHandler = request.NamedHandler{ + Name: "core.ValidateReqSigHandler", + Fn: func(r *request.Request) { + // Unsigned requests are not signed + if r.Config.Credentials == credentials.AnonymousCredentials { + return + } + + signedTime := r.Time + if !r.LastSignedAt.IsZero() { + signedTime = r.LastSignedAt + } + + // 5 minutes to allow for some clock skew/delays in transmission. + // Would be improved with aws/aws-sdk-go#423 + if signedTime.Add(5 * time.Minute).After(time.Now()) { + return + } + + fmt.Println("request expired, resigning") + r.Sign() + }, +} + +// SendHandler is a request handler to send service request using HTTP client. +var SendHandler = request.NamedHandler{ + Name: "core.SendHandler", + Fn: func(r *request.Request) { + sender := sendFollowRedirects + if r.DisableFollowRedirects { + sender = sendWithoutFollowRedirects + } + + if request.NoBody == r.HTTPRequest.Body { + // Strip off the request body if the NoBody reader was used as a + // place holder for a request body. This prevents the SDK from + // making requests with a request body when it would be invalid + // to do so. + // + // Use a shallow copy of the http.Request to ensure the race condition + // of transport on Body will not trigger + reqOrig, reqCopy := r.HTTPRequest, *r.HTTPRequest + reqCopy.Body = nil + r.HTTPRequest = &reqCopy + defer func() { + r.HTTPRequest = reqOrig + }() + } + + var err error + r.HTTPResponse, err = sender(r) + if err != nil { + handleSendError(r, err) + } + }, +} + +func sendFollowRedirects(r *request.Request) (*http.Response, error) { + return r.Config.HTTPClient.Do(r.HTTPRequest) +} + +func sendWithoutFollowRedirects(r *request.Request) (*http.Response, error) { + transport := r.Config.HTTPClient.Transport + if transport == nil { + transport = http.DefaultTransport + } + + return transport.RoundTrip(r.HTTPRequest) +} + +func handleSendError(r *request.Request, err error) { + // Prevent leaking if an HTTPResponse was returned. Clean up + // the body. + if r.HTTPResponse != nil { + r.HTTPResponse.Body.Close() + } + // Capture the case where url.Error is returned for error processing + // response. e.g. 301 without location header comes back as string + // error and r.HTTPResponse is nil. Other URL redirect errors will + // comeback in a similar method. + if e, ok := err.(*url.Error); ok && e.Err != nil { + if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil { + code, _ := strconv.ParseInt(s[1], 10, 64) + r.HTTPResponse = &http.Response{ + StatusCode: int(code), + Status: http.StatusText(int(code)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + return + } + } + if r.HTTPResponse == nil { + // Add a dummy request response object to ensure the HTTPResponse + // value is consistent. + r.HTTPResponse = &http.Response{ + StatusCode: int(0), + Status: http.StatusText(int(0)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + } + // Catch all request errors, and let the default retrier determine + // if the error is retryable. + r.Error = awserr.New("RequestError", "send request failed", err) + + // Override the error with a context canceled error, if that was canceled. + ctx := r.Context() + select { + case <-ctx.Done(): + r.Error = awserr.New(request.CanceledErrorCode, + "request context canceled", ctx.Err()) + r.Retryable = aws.Bool(false) + default: + } +} + +// ValidateResponseHandler is a request handler to validate service response. +var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) { + if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 { + // this may be replaced by an UnmarshalError handler + r.Error = awserr.New("UnknownError", "unknown error", nil) + } +}} + +// AfterRetryHandler performs final checks to determine if the request should +// be retried and how long to delay. +var AfterRetryHandler = request.NamedHandler{ + Name: "core.AfterRetryHandler", + Fn: func(r *request.Request) { + // If one of the other handlers already set the retry state + // we don't want to override it based on the service's state + if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) { + r.Retryable = aws.Bool(r.ShouldRetry(r)) + } + + if r.WillRetry() { + r.RetryDelay = r.RetryRules(r) + + if sleepFn := r.Config.SleepDelay; sleepFn != nil { + // Support SleepDelay for backwards compatibility and testing + sleepFn(r.RetryDelay) + } else if err := aws.SleepWithContext(r.Context(), r.RetryDelay); err != nil { + r.Error = awserr.New(request.CanceledErrorCode, + "request context canceled", err) + r.Retryable = aws.Bool(false) + return + } + + // when the expired token exception occurs the credentials + // need to be expired locally so that the next request to + // get credentials will trigger a credentials refresh. + if r.IsErrorExpired() { + r.Config.Credentials.Expire() + } + + r.RetryCount++ + r.Error = nil + } + }} + +// ValidateEndpointHandler is a request handler to validate a request had the +// appropriate Region and Endpoint set. Will set r.Error if the endpoint or +// region is not valid. +var ValidateEndpointHandler = request.NamedHandler{Name: "core.ValidateEndpointHandler", Fn: func(r *request.Request) { + if r.ClientInfo.SigningRegion == "" && aws.StringValue(r.Config.Region) == "" { + r.Error = aws.ErrMissingRegion + } else if r.ClientInfo.Endpoint == "" { + r.Error = aws.ErrMissingEndpoint + } +}} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go new file mode 100644 index 000000000..7d50b1557 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go @@ -0,0 +1,17 @@ +package corehandlers + +import "github.com/aws/aws-sdk-go/aws/request" + +// ValidateParametersHandler is a request handler to validate the input parameters. +// Validating parameters only has meaning if done prior to the request being sent. +var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) { + if !r.ParamsFilled() { + return + } + + if v, ok := r.Params.(request.Validator); ok { + if err := v.Validate(); err != nil { + r.Error = err + } + } +}} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go new file mode 100644 index 000000000..ab69c7a6f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go @@ -0,0 +1,37 @@ +package corehandlers + +import ( + "os" + "runtime" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +// SDKVersionUserAgentHandler is a request handler for adding the SDK Version +// to the user agent. +var SDKVersionUserAgentHandler = request.NamedHandler{ + Name: "core.SDKVersionUserAgentHandler", + Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion, + runtime.Version(), runtime.GOOS, runtime.GOARCH), +} + +const execEnvVar = `AWS_EXECUTION_ENV` +const execEnvUAKey = `exec-env` + +// AddHostExecEnvUserAgentHander is a request handler appending the SDK's +// execution environment to the user agent. +// +// If the environment variable AWS_EXECUTION_ENV is set, its value will be +// appended to the user agent string. +var AddHostExecEnvUserAgentHander = request.NamedHandler{ + Name: "core.AddHostExecEnvUserAgentHander", + Fn: func(r *request.Request) { + v := os.Getenv(execEnvVar) + if len(v) == 0 { + return + } + + request.AddToUserAgent(r, execEnvUAKey+"/"+v) + }, +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go new file mode 100644 index 000000000..3ad1e798d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go @@ -0,0 +1,100 @@ +package credentials + +import ( + "github.com/aws/aws-sdk-go/aws/awserr" +) + +var ( + // ErrNoValidProvidersFoundInChain Is returned when there are no valid + // providers in the ChainProvider. + // + // This has been deprecated. For verbose error messaging set + // aws.Config.CredentialsChainVerboseErrors to true. + ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders", + `no valid providers in chain. Deprecated. + For verbose messaging see aws.Config.CredentialsChainVerboseErrors`, + nil) +) + +// A ChainProvider will search for a provider which returns credentials +// and cache that provider until Retrieve is called again. +// +// The ChainProvider provides a way of chaining multiple providers together +// which will pick the first available using priority order of the Providers +// in the list. +// +// If none of the Providers retrieve valid credentials Value, ChainProvider's +// Retrieve() will return the error ErrNoValidProvidersFoundInChain. +// +// If a Provider is found which returns valid credentials Value ChainProvider +// will cache that Provider for all calls to IsExpired(), until Retrieve is +// called again. +// +// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider. +// In this example EnvProvider will first check if any credentials are available +// via the environment variables. If there are none ChainProvider will check +// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider +// does not return any credentials ChainProvider will return the error +// ErrNoValidProvidersFoundInChain +// +// creds := credentials.NewChainCredentials( +// []credentials.Provider{ +// &credentials.EnvProvider{}, +// &ec2rolecreds.EC2RoleProvider{ +// Client: ec2metadata.New(sess), +// }, +// }) +// +// // Usage of ChainCredentials with aws.Config +// svc := ec2.New(session.Must(session.NewSession(&aws.Config{ +// Credentials: creds, +// }))) +// +type ChainProvider struct { + Providers []Provider + curr Provider + VerboseErrors bool +} + +// NewChainCredentials returns a pointer to a new Credentials object +// wrapping a chain of providers. +func NewChainCredentials(providers []Provider) *Credentials { + return NewCredentials(&ChainProvider{ + Providers: append([]Provider{}, providers...), + }) +} + +// Retrieve returns the credentials value or error if no provider returned +// without error. +// +// If a provider is found it will be cached and any calls to IsExpired() +// will return the expired state of the cached provider. +func (c *ChainProvider) Retrieve() (Value, error) { + var errs []error + for _, p := range c.Providers { + creds, err := p.Retrieve() + if err == nil { + c.curr = p + return creds, nil + } + errs = append(errs, err) + } + c.curr = nil + + var err error + err = ErrNoValidProvidersFoundInChain + if c.VerboseErrors { + err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs) + } + return Value{}, err +} + +// IsExpired will returned the expired state of the currently cached provider +// if there is one. If there is no current provider, true will be returned. +func (c *ChainProvider) IsExpired() bool { + if c.curr != nil { + return c.curr.IsExpired() + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go new file mode 100644 index 000000000..4af592158 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go @@ -0,0 +1,299 @@ +// Package credentials provides credential retrieval and management +// +// The Credentials is the primary method of getting access to and managing +// credentials Values. Using dependency injection retrieval of the credential +// values is handled by a object which satisfies the Provider interface. +// +// By default the Credentials.Get() will cache the successful result of a +// Provider's Retrieve() until Provider.IsExpired() returns true. At which +// point Credentials will call Provider's Retrieve() to get new credential Value. +// +// The Provider is responsible for determining when credentials Value have expired. +// It is also important to note that Credentials will always call Retrieve the +// first time Credentials.Get() is called. +// +// Example of using the environment variable credentials. +// +// creds := credentials.NewEnvCredentials() +// +// // Retrieve the credentials value +// credValue, err := creds.Get() +// if err != nil { +// // handle error +// } +// +// Example of forcing credentials to expire and be refreshed on the next Get(). +// This may be helpful to proactively expire credentials and refresh them sooner +// than they would naturally expire on their own. +// +// creds := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{}) +// creds.Expire() +// credsValue, err := creds.Get() +// // New credentials will be retrieved instead of from cache. +// +// +// Custom Provider +// +// Each Provider built into this package also provides a helper method to generate +// a Credentials pointer setup with the provider. To use a custom Provider just +// create a type which satisfies the Provider interface and pass it to the +// NewCredentials method. +// +// type MyProvider struct{} +// func (m *MyProvider) Retrieve() (Value, error) {...} +// func (m *MyProvider) IsExpired() bool {...} +// +// creds := credentials.NewCredentials(&MyProvider{}) +// credValue, err := creds.Get() +// +package credentials + +import ( + "fmt" + "sync" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// AnonymousCredentials is an empty Credential object that can be used as +// dummy placeholder credentials for requests that do not need signed. +// +// This Credentials can be used to configure a service to not sign requests +// when making service API calls. For example, when accessing public +// s3 buckets. +// +// svc := s3.New(session.Must(session.NewSession(&aws.Config{ +// Credentials: credentials.AnonymousCredentials, +// }))) +// // Access public S3 buckets. +var AnonymousCredentials = NewStaticCredentials("", "", "") + +// A Value is the AWS credentials value for individual credential fields. +type Value struct { + // AWS Access key ID + AccessKeyID string + + // AWS Secret Access Key + SecretAccessKey string + + // AWS Session Token + SessionToken string + + // Provider used to get credentials + ProviderName string +} + +// HasKeys returns if the credentials Value has both AccessKeyID and +// SecretAccessKey value set. +func (v Value) HasKeys() bool { + return len(v.AccessKeyID) != 0 && len(v.SecretAccessKey) != 0 +} + +// A Provider is the interface for any component which will provide credentials +// Value. A provider is required to manage its own Expired state, and what to +// be expired means. +// +// The Provider should not need to implement its own mutexes, because +// that will be managed by Credentials. +type Provider interface { + // Retrieve returns nil if it successfully retrieved the value. + // Error is returned if the value were not obtainable, or empty. + Retrieve() (Value, error) + + // IsExpired returns if the credentials are no longer valid, and need + // to be retrieved. + IsExpired() bool +} + +// An Expirer is an interface that Providers can implement to expose the expiration +// time, if known. If the Provider cannot accurately provide this info, +// it should not implement this interface. +type Expirer interface { + // The time at which the credentials are no longer valid + ExpiresAt() time.Time +} + +// An ErrorProvider is a stub credentials provider that always returns an error +// this is used by the SDK when construction a known provider is not possible +// due to an error. +type ErrorProvider struct { + // The error to be returned from Retrieve + Err error + + // The provider name to set on the Retrieved returned Value + ProviderName string +} + +// Retrieve will always return the error that the ErrorProvider was created with. +func (p ErrorProvider) Retrieve() (Value, error) { + return Value{ProviderName: p.ProviderName}, p.Err +} + +// IsExpired will always return not expired. +func (p ErrorProvider) IsExpired() bool { + return false +} + +// A Expiry provides shared expiration logic to be used by credentials +// providers to implement expiry functionality. +// +// The best method to use this struct is as an anonymous field within the +// provider's struct. +// +// Example: +// type EC2RoleProvider struct { +// Expiry +// ... +// } +type Expiry struct { + // The date/time when to expire on + expiration time.Time + + // If set will be used by IsExpired to determine the current time. + // Defaults to time.Now if CurrentTime is not set. Available for testing + // to be able to mock out the current time. + CurrentTime func() time.Time +} + +// SetExpiration sets the expiration IsExpired will check when called. +// +// If window is greater than 0 the expiration time will be reduced by the +// window value. +// +// Using a window is helpful to trigger credentials to expire sooner than +// the expiration time given to ensure no requests are made with expired +// tokens. +func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) { + e.expiration = expiration + if window > 0 { + e.expiration = e.expiration.Add(-window) + } +} + +// IsExpired returns if the credentials are expired. +func (e *Expiry) IsExpired() bool { + curTime := e.CurrentTime + if curTime == nil { + curTime = time.Now + } + return e.expiration.Before(curTime()) +} + +// ExpiresAt returns the expiration time of the credential +func (e *Expiry) ExpiresAt() time.Time { + return e.expiration +} + +// A Credentials provides concurrency safe retrieval of AWS credentials Value. +// Credentials will cache the credentials value until they expire. Once the value +// expires the next Get will attempt to retrieve valid credentials. +// +// Credentials is safe to use across multiple goroutines and will manage the +// synchronous state so the Providers do not need to implement their own +// synchronization. +// +// The first Credentials.Get() will always call Provider.Retrieve() to get the +// first instance of the credentials Value. All calls to Get() after that +// will return the cached credentials Value until IsExpired() returns true. +type Credentials struct { + creds Value + forceRefresh bool + + m sync.RWMutex + + provider Provider +} + +// NewCredentials returns a pointer to a new Credentials with the provider set. +func NewCredentials(provider Provider) *Credentials { + return &Credentials{ + provider: provider, + forceRefresh: true, + } +} + +// Get returns the credentials value, or error if the credentials Value failed +// to be retrieved. +// +// Will return the cached credentials Value if it has not expired. If the +// credentials Value has expired the Provider's Retrieve() will be called +// to refresh the credentials. +// +// If Credentials.Expire() was called the credentials Value will be force +// expired, and the next call to Get() will cause them to be refreshed. +func (c *Credentials) Get() (Value, error) { + // Check the cached credentials first with just the read lock. + c.m.RLock() + if !c.isExpired() { + creds := c.creds + c.m.RUnlock() + return creds, nil + } + c.m.RUnlock() + + // Credentials are expired need to retrieve the credentials taking the full + // lock. + c.m.Lock() + defer c.m.Unlock() + + if c.isExpired() { + creds, err := c.provider.Retrieve() + if err != nil { + return Value{}, err + } + c.creds = creds + c.forceRefresh = false + } + + return c.creds, nil +} + +// Expire expires the credentials and forces them to be retrieved on the +// next call to Get(). +// +// This will override the Provider's expired state, and force Credentials +// to call the Provider's Retrieve(). +func (c *Credentials) Expire() { + c.m.Lock() + defer c.m.Unlock() + + c.forceRefresh = true +} + +// IsExpired returns if the credentials are no longer valid, and need +// to be retrieved. +// +// If the Credentials were forced to be expired with Expire() this will +// reflect that override. +func (c *Credentials) IsExpired() bool { + c.m.RLock() + defer c.m.RUnlock() + + return c.isExpired() +} + +// isExpired helper method wrapping the definition of expired credentials. +func (c *Credentials) isExpired() bool { + return c.forceRefresh || c.provider.IsExpired() +} + +// ExpiresAt provides access to the functionality of the Expirer interface of +// the underlying Provider, if it supports that interface. Otherwise, it returns +// an error. +func (c *Credentials) ExpiresAt() (time.Time, error) { + c.m.RLock() + defer c.m.RUnlock() + + expirer, ok := c.provider.(Expirer) + if !ok { + return time.Time{}, awserr.New("ProviderNotExpirer", + fmt.Sprintf("provider %s does not support ExpiresAt()", c.creds.ProviderName), + nil) + } + if c.forceRefresh { + // set expiration time to the distant past + return time.Time{}, nil + } + return expirer.ExpiresAt(), nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go new file mode 100644 index 000000000..43d4ed386 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go @@ -0,0 +1,180 @@ +package ec2rolecreds + +import ( + "bufio" + "encoding/json" + "fmt" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/ec2metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/sdkuri" +) + +// ProviderName provides a name of EC2Role provider +const ProviderName = "EC2RoleProvider" + +// A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if +// those credentials are expired. +// +// Example how to configure the EC2RoleProvider with custom http Client, Endpoint +// or ExpiryWindow +// +// p := &ec2rolecreds.EC2RoleProvider{ +// // Pass in a custom timeout to be used when requesting +// // IAM EC2 Role credentials. +// Client: ec2metadata.New(sess, aws.Config{ +// HTTPClient: &http.Client{Timeout: 10 * time.Second}, +// }), +// +// // Do not use early expiry of credentials. If a non zero value is +// // specified the credentials will be expired early +// ExpiryWindow: 0, +// } +type EC2RoleProvider struct { + credentials.Expiry + + // Required EC2Metadata client to use when connecting to EC2 metadata service. + Client *ec2metadata.EC2Metadata + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration +} + +// NewCredentials returns a pointer to a new Credentials object wrapping +// the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client. +// The ConfigProvider is satisfied by the session.Session type. +func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials { + p := &EC2RoleProvider{ + Client: ec2metadata.New(c), + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping +// the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2 +// metadata service. +func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials { + p := &EC2RoleProvider{ + Client: client, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// Retrieve retrieves credentials from the EC2 service. +// Error will be returned if the request fails, or unable to extract +// the desired credentials. +func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) { + credsList, err := requestCredList(m.Client) + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + if len(credsList) == 0 { + return credentials.Value{ProviderName: ProviderName}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil) + } + credsName := credsList[0] + + roleCreds, err := requestCred(m.Client, credsName) + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow) + + return credentials.Value{ + AccessKeyID: roleCreds.AccessKeyID, + SecretAccessKey: roleCreds.SecretAccessKey, + SessionToken: roleCreds.Token, + ProviderName: ProviderName, + }, nil +} + +// A ec2RoleCredRespBody provides the shape for unmarshaling credential +// request responses. +type ec2RoleCredRespBody struct { + // Success State + Expiration time.Time + AccessKeyID string + SecretAccessKey string + Token string + + // Error state + Code string + Message string +} + +const iamSecurityCredsPath = "iam/security-credentials/" + +// requestCredList requests a list of credentials from the EC2 service. +// If there are no credentials, or there is an error making or receiving the request +func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) { + resp, err := client.GetMetadata(iamSecurityCredsPath) + if err != nil { + return nil, awserr.New("EC2RoleRequestError", "no EC2 instance role found", err) + } + + credsList := []string{} + s := bufio.NewScanner(strings.NewReader(resp)) + for s.Scan() { + credsList = append(credsList, s.Text()) + } + + if err := s.Err(); err != nil { + return nil, awserr.New(request.ErrCodeSerialization, + "failed to read EC2 instance role from metadata service", err) + } + + return credsList, nil +} + +// requestCred requests the credentials for a specific credentials from the EC2 service. +// +// If the credentials cannot be found, or there is an error reading the response +// and error will be returned. +func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) { + resp, err := client.GetMetadata(sdkuri.PathJoin(iamSecurityCredsPath, credsName)) + if err != nil { + return ec2RoleCredRespBody{}, + awserr.New("EC2RoleRequestError", + fmt.Sprintf("failed to get %s EC2 instance role credentials", credsName), + err) + } + + respCreds := ec2RoleCredRespBody{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil { + return ec2RoleCredRespBody{}, + awserr.New(request.ErrCodeSerialization, + fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName), + err) + } + + if respCreds.Code != "Success" { + // If an error code was returned something failed requesting the role. + return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil) + } + + return respCreds, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go new file mode 100644 index 000000000..c2b2c5d65 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go @@ -0,0 +1,203 @@ +// Package endpointcreds provides support for retrieving credentials from an +// arbitrary HTTP endpoint. +// +// The credentials endpoint Provider can receive both static and refreshable +// credentials that will expire. Credentials are static when an "Expiration" +// value is not provided in the endpoint's response. +// +// Static credentials will never expire once they have been retrieved. The format +// of the static credentials response: +// { +// "AccessKeyId" : "MUA...", +// "SecretAccessKey" : "/7PC5om....", +// } +// +// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration +// value in the response. The format of the refreshable credentials response: +// { +// "AccessKeyId" : "MUA...", +// "SecretAccessKey" : "/7PC5om....", +// "Token" : "AQoDY....=", +// "Expiration" : "2016-02-25T06:03:31Z" +// } +// +// Errors should be returned in the following format and only returned with 400 +// or 500 HTTP status codes. +// { +// "code": "ErrorCode", +// "message": "Helpful error message." +// } +package endpointcreds + +import ( + "encoding/json" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" +) + +// ProviderName is the name of the credentials provider. +const ProviderName = `CredentialsEndpointProvider` + +// Provider satisfies the credentials.Provider interface, and is a client to +// retrieve credentials from an arbitrary endpoint. +type Provider struct { + staticCreds bool + credentials.Expiry + + // Requires a AWS Client to make HTTP requests to the endpoint with. + // the Endpoint the request will be made to is provided by the aws.Config's + // Endpoint value. + Client *client.Client + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration + + // Optional authorization token value if set will be used as the value of + // the Authorization header of the endpoint credential request. + AuthorizationToken string +} + +// NewProviderClient returns a credentials Provider for retrieving AWS credentials +// from arbitrary endpoint. +func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider { + p := &Provider{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: "CredentialsEndpoint", + Endpoint: endpoint, + }, + handlers, + ), + } + + p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler) + p.Client.Handlers.UnmarshalError.PushBack(unmarshalError) + p.Client.Handlers.Validate.Clear() + p.Client.Handlers.Validate.PushBack(validateEndpointHandler) + + for _, option := range options { + option(p) + } + + return p +} + +// NewCredentialsClient returns a Credentials wrapper for retrieving credentials +// from an arbitrary endpoint concurrently. The client will request the +func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials { + return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...)) +} + +// IsExpired returns true if the credentials retrieved are expired, or not yet +// retrieved. +func (p *Provider) IsExpired() bool { + if p.staticCreds { + return false + } + return p.Expiry.IsExpired() +} + +// Retrieve will attempt to request the credentials from the endpoint the Provider +// was configured for. And error will be returned if the retrieval fails. +func (p *Provider) Retrieve() (credentials.Value, error) { + resp, err := p.getCredentials() + if err != nil { + return credentials.Value{ProviderName: ProviderName}, + awserr.New("CredentialsEndpointError", "failed to load credentials", err) + } + + if resp.Expiration != nil { + p.SetExpiration(*resp.Expiration, p.ExpiryWindow) + } else { + p.staticCreds = true + } + + return credentials.Value{ + AccessKeyID: resp.AccessKeyID, + SecretAccessKey: resp.SecretAccessKey, + SessionToken: resp.Token, + ProviderName: ProviderName, + }, nil +} + +type getCredentialsOutput struct { + Expiration *time.Time + AccessKeyID string + SecretAccessKey string + Token string +} + +type errorOutput struct { + Code string `json:"code"` + Message string `json:"message"` +} + +func (p *Provider) getCredentials() (*getCredentialsOutput, error) { + op := &request.Operation{ + Name: "GetCredentials", + HTTPMethod: "GET", + } + + out := &getCredentialsOutput{} + req := p.Client.NewRequest(op, nil, out) + req.HTTPRequest.Header.Set("Accept", "application/json") + if authToken := p.AuthorizationToken; len(authToken) != 0 { + req.HTTPRequest.Header.Set("Authorization", authToken) + } + + return out, req.Send() +} + +func validateEndpointHandler(r *request.Request) { + if len(r.ClientInfo.Endpoint) == 0 { + r.Error = aws.ErrMissingEndpoint + } +} + +func unmarshalHandler(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + out := r.Data.(*getCredentialsOutput) + if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to decode endpoint credentials", + err, + ) + } +} + +func unmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + var errOut errorOutput + err := jsonutil.UnmarshalJSONError(&errOut, r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to decode error message", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + + // Response body format is not consistent between metadata endpoints. + // Grab the error message as a string and include that as the source error + r.Error = awserr.New(errOut.Code, errOut.Message, nil) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go new file mode 100644 index 000000000..54c5cf733 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go @@ -0,0 +1,74 @@ +package credentials + +import ( + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// EnvProviderName provides a name of Env provider +const EnvProviderName = "EnvProvider" + +var ( + // ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be + // found in the process's environment. + ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil) + + // ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key + // can't be found in the process's environment. + ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil) +) + +// A EnvProvider retrieves credentials from the environment variables of the +// running process. Environment credentials never expire. +// +// Environment variables used: +// +// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY +// +// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY +type EnvProvider struct { + retrieved bool +} + +// NewEnvCredentials returns a pointer to a new Credentials object +// wrapping the environment variable provider. +func NewEnvCredentials() *Credentials { + return NewCredentials(&EnvProvider{}) +} + +// Retrieve retrieves the keys from the environment. +func (e *EnvProvider) Retrieve() (Value, error) { + e.retrieved = false + + id := os.Getenv("AWS_ACCESS_KEY_ID") + if id == "" { + id = os.Getenv("AWS_ACCESS_KEY") + } + + secret := os.Getenv("AWS_SECRET_ACCESS_KEY") + if secret == "" { + secret = os.Getenv("AWS_SECRET_KEY") + } + + if id == "" { + return Value{ProviderName: EnvProviderName}, ErrAccessKeyIDNotFound + } + + if secret == "" { + return Value{ProviderName: EnvProviderName}, ErrSecretAccessKeyNotFound + } + + e.retrieved = true + return Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: os.Getenv("AWS_SESSION_TOKEN"), + ProviderName: EnvProviderName, + }, nil +} + +// IsExpired returns if the credentials have been retrieved. +func (e *EnvProvider) IsExpired() bool { + return !e.retrieved +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini b/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini new file mode 100644 index 000000000..7fc91d9d2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini @@ -0,0 +1,12 @@ +[default] +aws_access_key_id = accessKey +aws_secret_access_key = secret +aws_session_token = token + +[no_token] +aws_access_key_id = accessKey +aws_secret_access_key = secret + +[with_colon] +aws_access_key_id: accessKey +aws_secret_access_key: secret diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go new file mode 100644 index 000000000..1980c8c14 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go @@ -0,0 +1,425 @@ +/* +Package processcreds is a credential Provider to retrieve `credential_process` +credentials. + +WARNING: The following describes a method of sourcing credentials from an external +process. This can potentially be dangerous, so proceed with caution. Other +credential providers should be preferred if at all possible. If using this +option, you should make sure that the config file is as locked down as possible +using security best practices for your operating system. + +You can use credentials from a `credential_process` in a variety of ways. + +One way is to setup your shared config file, located in the default +location, with the `credential_process` key and the command you want to be +called. You also need to set the AWS_SDK_LOAD_CONFIG environment variable +(e.g., `export AWS_SDK_LOAD_CONFIG=1`) to use the shared config file. + + [default] + credential_process = /command/to/call + +Creating a new session will use the credential process to retrieve credentials. +NOTE: If there are credentials in the profile you are using, the credential +process will not be used. + + // Initialize a session to load credentials. + sess, _ := session.NewSession(&aws.Config{ + Region: aws.String("us-east-1")}, + ) + + // Create S3 service client to use the credentials. + svc := s3.New(sess) + +Another way to use the `credential_process` method is by using +`credentials.NewCredentials()` and providing a command to be executed to +retrieve credentials: + + // Create credentials using the ProcessProvider. + creds := processcreds.NewCredentials("/path/to/command") + + // Create service client value configured for credentials. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +You can set a non-default timeout for the `credential_process` with another +constructor, `credentials.NewCredentialsTimeout()`, providing the timeout. To +set a one minute timeout: + + // Create credentials using the ProcessProvider. + creds := processcreds.NewCredentialsTimeout( + "/path/to/command", + time.Duration(500) * time.Millisecond) + +If you need more control, you can set any configurable options in the +credentials using one or more option functions. For example, you can set a two +minute timeout, a credential duration of 60 minutes, and a maximum stdout +buffer size of 2k. + + creds := processcreds.NewCredentials( + "/path/to/command", + func(opt *ProcessProvider) { + opt.Timeout = time.Duration(2) * time.Minute + opt.Duration = time.Duration(60) * time.Minute + opt.MaxBufSize = 2048 + }) + +You can also use your own `exec.Cmd`: + + // Create an exec.Cmd + myCommand := exec.Command("/path/to/command") + + // Create credentials using your exec.Cmd and custom timeout + creds := processcreds.NewCredentialsCommand( + myCommand, + func(opt *processcreds.ProcessProvider) { + opt.Timeout = time.Duration(1) * time.Second + }) +*/ +package processcreds + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "runtime" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" +) + +const ( + // ProviderName is the name this credentials provider will label any + // returned credentials Value with. + ProviderName = `ProcessProvider` + + // ErrCodeProcessProviderParse error parsing process output + ErrCodeProcessProviderParse = "ProcessProviderParseError" + + // ErrCodeProcessProviderVersion version error in output + ErrCodeProcessProviderVersion = "ProcessProviderVersionError" + + // ErrCodeProcessProviderRequired required attribute missing in output + ErrCodeProcessProviderRequired = "ProcessProviderRequiredError" + + // ErrCodeProcessProviderExecution execution of command failed + ErrCodeProcessProviderExecution = "ProcessProviderExecutionError" + + // errMsgProcessProviderTimeout process took longer than allowed + errMsgProcessProviderTimeout = "credential process timed out" + + // errMsgProcessProviderProcess process error + errMsgProcessProviderProcess = "error in credential_process" + + // errMsgProcessProviderParse problem parsing output + errMsgProcessProviderParse = "parse failed of credential_process output" + + // errMsgProcessProviderVersion version error in output + errMsgProcessProviderVersion = "wrong version in process output (not 1)" + + // errMsgProcessProviderMissKey missing access key id in output + errMsgProcessProviderMissKey = "missing AccessKeyId in process output" + + // errMsgProcessProviderMissSecret missing secret acess key in output + errMsgProcessProviderMissSecret = "missing SecretAccessKey in process output" + + // errMsgProcessProviderPrepareCmd prepare of command failed + errMsgProcessProviderPrepareCmd = "failed to prepare command" + + // errMsgProcessProviderEmptyCmd command must not be empty + errMsgProcessProviderEmptyCmd = "command must not be empty" + + // errMsgProcessProviderPipe failed to initialize pipe + errMsgProcessProviderPipe = "failed to initialize pipe" + + // DefaultDuration is the default amount of time in minutes that the + // credentials will be valid for. + DefaultDuration = time.Duration(15) * time.Minute + + // DefaultBufSize limits buffer size from growing to an enormous + // amount due to a faulty process. + DefaultBufSize = 1024 + + // DefaultTimeout default limit on time a process can run. + DefaultTimeout = time.Duration(1) * time.Minute +) + +// ProcessProvider satisfies the credentials.Provider interface, and is a +// client to retrieve credentials from a process. +type ProcessProvider struct { + staticCreds bool + credentials.Expiry + originalCommand []string + + // Expiry duration of the credentials. Defaults to 15 minutes if not set. + Duration time.Duration + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration + + // A string representing an os command that should return a JSON with + // credential information. + command *exec.Cmd + + // MaxBufSize limits memory usage from growing to an enormous + // amount due to a faulty process. + MaxBufSize int + + // Timeout limits the time a process can run. + Timeout time.Duration +} + +// NewCredentials returns a pointer to a new Credentials object wrapping the +// ProcessProvider. The credentials will expire every 15 minutes by default. +func NewCredentials(command string, options ...func(*ProcessProvider)) *credentials.Credentials { + p := &ProcessProvider{ + command: exec.Command(command), + Duration: DefaultDuration, + Timeout: DefaultTimeout, + MaxBufSize: DefaultBufSize, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsTimeout returns a pointer to a new Credentials object with +// the specified command and timeout, and default duration and max buffer size. +func NewCredentialsTimeout(command string, timeout time.Duration) *credentials.Credentials { + p := NewCredentials(command, func(opt *ProcessProvider) { + opt.Timeout = timeout + }) + + return p +} + +// NewCredentialsCommand returns a pointer to a new Credentials object with +// the specified command, and default timeout, duration and max buffer size. +func NewCredentialsCommand(command *exec.Cmd, options ...func(*ProcessProvider)) *credentials.Credentials { + p := &ProcessProvider{ + command: command, + Duration: DefaultDuration, + Timeout: DefaultTimeout, + MaxBufSize: DefaultBufSize, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +type credentialProcessResponse struct { + Version int + AccessKeyID string `json:"AccessKeyId"` + SecretAccessKey string + SessionToken string + Expiration *time.Time +} + +// Retrieve executes the 'credential_process' and returns the credentials. +func (p *ProcessProvider) Retrieve() (credentials.Value, error) { + out, err := p.executeCredentialProcess() + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + // Serialize and validate response + resp := &credentialProcessResponse{} + if err = json.Unmarshal(out, resp); err != nil { + return credentials.Value{ProviderName: ProviderName}, awserr.New( + ErrCodeProcessProviderParse, + fmt.Sprintf("%s: %s", errMsgProcessProviderParse, string(out)), + err) + } + + if resp.Version != 1 { + return credentials.Value{ProviderName: ProviderName}, awserr.New( + ErrCodeProcessProviderVersion, + errMsgProcessProviderVersion, + nil) + } + + if len(resp.AccessKeyID) == 0 { + return credentials.Value{ProviderName: ProviderName}, awserr.New( + ErrCodeProcessProviderRequired, + errMsgProcessProviderMissKey, + nil) + } + + if len(resp.SecretAccessKey) == 0 { + return credentials.Value{ProviderName: ProviderName}, awserr.New( + ErrCodeProcessProviderRequired, + errMsgProcessProviderMissSecret, + nil) + } + + // Handle expiration + p.staticCreds = resp.Expiration == nil + if resp.Expiration != nil { + p.SetExpiration(*resp.Expiration, p.ExpiryWindow) + } + + return credentials.Value{ + ProviderName: ProviderName, + AccessKeyID: resp.AccessKeyID, + SecretAccessKey: resp.SecretAccessKey, + SessionToken: resp.SessionToken, + }, nil +} + +// IsExpired returns true if the credentials retrieved are expired, or not yet +// retrieved. +func (p *ProcessProvider) IsExpired() bool { + if p.staticCreds { + return false + } + return p.Expiry.IsExpired() +} + +// prepareCommand prepares the command to be executed. +func (p *ProcessProvider) prepareCommand() error { + + var cmdArgs []string + if runtime.GOOS == "windows" { + cmdArgs = []string{"cmd.exe", "/C"} + } else { + cmdArgs = []string{"sh", "-c"} + } + + if len(p.originalCommand) == 0 { + p.originalCommand = make([]string, len(p.command.Args)) + copy(p.originalCommand, p.command.Args) + + // check for empty command because it succeeds + if len(strings.TrimSpace(p.originalCommand[0])) < 1 { + return awserr.New( + ErrCodeProcessProviderExecution, + fmt.Sprintf( + "%s: %s", + errMsgProcessProviderPrepareCmd, + errMsgProcessProviderEmptyCmd), + nil) + } + } + + cmdArgs = append(cmdArgs, p.originalCommand...) + p.command = exec.Command(cmdArgs[0], cmdArgs[1:]...) + p.command.Env = os.Environ() + + return nil +} + +// executeCredentialProcess starts the credential process on the OS and +// returns the results or an error. +func (p *ProcessProvider) executeCredentialProcess() ([]byte, error) { + + if err := p.prepareCommand(); err != nil { + return nil, err + } + + // Setup the pipes + outReadPipe, outWritePipe, err := os.Pipe() + if err != nil { + return nil, awserr.New( + ErrCodeProcessProviderExecution, + errMsgProcessProviderPipe, + err) + } + + p.command.Stderr = os.Stderr // display stderr on console for MFA + p.command.Stdout = outWritePipe // get creds json on process's stdout + p.command.Stdin = os.Stdin // enable stdin for MFA + + output := bytes.NewBuffer(make([]byte, 0, p.MaxBufSize)) + + stdoutCh := make(chan error, 1) + go readInput( + io.LimitReader(outReadPipe, int64(p.MaxBufSize)), + output, + stdoutCh) + + execCh := make(chan error, 1) + go executeCommand(*p.command, execCh) + + finished := false + var errors []error + for !finished { + select { + case readError := <-stdoutCh: + errors = appendError(errors, readError) + finished = true + case execError := <-execCh: + err := outWritePipe.Close() + errors = appendError(errors, err) + errors = appendError(errors, execError) + if errors != nil { + return output.Bytes(), awserr.NewBatchError( + ErrCodeProcessProviderExecution, + errMsgProcessProviderProcess, + errors) + } + case <-time.After(p.Timeout): + finished = true + return output.Bytes(), awserr.NewBatchError( + ErrCodeProcessProviderExecution, + errMsgProcessProviderTimeout, + errors) // errors can be nil + } + } + + out := output.Bytes() + + if runtime.GOOS == "windows" { + // windows adds slashes to quotes + out = []byte(strings.Replace(string(out), `\"`, `"`, -1)) + } + + return out, nil +} + +// appendError conveniently checks for nil before appending slice +func appendError(errors []error, err error) []error { + if err != nil { + return append(errors, err) + } + return errors +} + +func executeCommand(cmd exec.Cmd, exec chan error) { + // Start the command + err := cmd.Start() + if err == nil { + err = cmd.Wait() + } + + exec <- err +} + +func readInput(r io.Reader, w io.Writer, read chan error) { + tee := io.TeeReader(r, w) + + _, err := ioutil.ReadAll(tee) + + if err == io.EOF { + err = nil + } + + read <- err // will only arrive here when write end of pipe is closed +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go new file mode 100644 index 000000000..e15514958 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go @@ -0,0 +1,150 @@ +package credentials + +import ( + "fmt" + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/internal/ini" + "github.com/aws/aws-sdk-go/internal/shareddefaults" +) + +// SharedCredsProviderName provides a name of SharedCreds provider +const SharedCredsProviderName = "SharedCredentialsProvider" + +var ( + // ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found. + ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil) +) + +// A SharedCredentialsProvider retrieves credentials from the current user's home +// directory, and keeps track if those credentials are expired. +// +// Profile ini file example: $HOME/.aws/credentials +type SharedCredentialsProvider struct { + // Path to the shared credentials file. + // + // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the + // env value is empty will default to current user's home directory. + // Linux/OSX: "$HOME/.aws/credentials" + // Windows: "%USERPROFILE%\.aws\credentials" + Filename string + + // AWS Profile to extract credentials from the shared credentials file. If empty + // will default to environment variable "AWS_PROFILE" or "default" if + // environment variable is also not set. + Profile string + + // retrieved states if the credentials have been successfully retrieved. + retrieved bool +} + +// NewSharedCredentials returns a pointer to a new Credentials object +// wrapping the Profile file provider. +func NewSharedCredentials(filename, profile string) *Credentials { + return NewCredentials(&SharedCredentialsProvider{ + Filename: filename, + Profile: profile, + }) +} + +// Retrieve reads and extracts the shared credentials from the current +// users home directory. +func (p *SharedCredentialsProvider) Retrieve() (Value, error) { + p.retrieved = false + + filename, err := p.filename() + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, err + } + + creds, err := loadProfile(filename, p.profile()) + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, err + } + + p.retrieved = true + return creds, nil +} + +// IsExpired returns if the shared credentials have expired. +func (p *SharedCredentialsProvider) IsExpired() bool { + return !p.retrieved +} + +// loadProfiles loads from the file pointed to by shared credentials filename for profile. +// The credentials retrieved from the profile will be returned or error. Error will be +// returned if it fails to read from the file, or the data is invalid. +func loadProfile(filename, profile string) (Value, error) { + config, err := ini.OpenFile(filename) + if err != nil { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err) + } + + iniProfile, ok := config.GetSection(profile) + if !ok { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", nil) + } + + id := iniProfile.String("aws_access_key_id") + if len(id) == 0 { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey", + fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename), + nil) + } + + secret := iniProfile.String("aws_secret_access_key") + if len(secret) == 0 { + return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret", + fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename), + nil) + } + + // Default to empty string if not found + token := iniProfile.String("aws_session_token") + + return Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: token, + ProviderName: SharedCredsProviderName, + }, nil +} + +// filename returns the filename to use to read AWS shared credentials. +// +// Will return an error if the user's home directory path cannot be found. +func (p *SharedCredentialsProvider) filename() (string, error) { + if len(p.Filename) != 0 { + return p.Filename, nil + } + + if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 { + return p.Filename, nil + } + + if home := shareddefaults.UserHomeDir(); len(home) == 0 { + // Backwards compatibility of home directly not found error being returned. + // This error is too verbose, failure when opening the file would of been + // a better error to return. + return "", ErrSharedCredentialsHomeNotFound + } + + p.Filename = shareddefaults.SharedCredentialsFilename() + + return p.Filename, nil +} + +// profile returns the AWS shared credentials profile. If empty will read +// environment variable "AWS_PROFILE". If that is not set profile will +// return "default". +func (p *SharedCredentialsProvider) profile() string { + if p.Profile == "" { + p.Profile = os.Getenv("AWS_PROFILE") + } + if p.Profile == "" { + p.Profile = "default" + } + + return p.Profile +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go new file mode 100644 index 000000000..531139e39 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go @@ -0,0 +1,55 @@ +package credentials + +import ( + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// StaticProviderName provides a name of Static provider +const StaticProviderName = "StaticProvider" + +var ( + // ErrStaticCredentialsEmpty is emitted when static credentials are empty. + ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil) +) + +// A StaticProvider is a set of credentials which are set programmatically, +// and will never expire. +type StaticProvider struct { + Value +} + +// NewStaticCredentials returns a pointer to a new Credentials object +// wrapping a static credentials value provider. +func NewStaticCredentials(id, secret, token string) *Credentials { + return NewCredentials(&StaticProvider{Value: Value{ + AccessKeyID: id, + SecretAccessKey: secret, + SessionToken: token, + }}) +} + +// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object +// wrapping the static credentials value provide. Same as NewStaticCredentials +// but takes the creds Value instead of individual fields +func NewStaticCredentialsFromCreds(creds Value) *Credentials { + return NewCredentials(&StaticProvider{Value: creds}) +} + +// Retrieve returns the credentials or error if the credentials are invalid. +func (s *StaticProvider) Retrieve() (Value, error) { + if s.AccessKeyID == "" || s.SecretAccessKey == "" { + return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty + } + + if len(s.Value.ProviderName) == 0 { + s.Value.ProviderName = StaticProviderName + } + return s.Value, nil +} + +// IsExpired returns if the credentials are expired. +// +// For StaticProvider, the credentials never expired. +func (s *StaticProvider) IsExpired() bool { + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go new file mode 100644 index 000000000..2e528d130 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go @@ -0,0 +1,312 @@ +/* +Package stscreds are credential Providers to retrieve STS AWS credentials. + +STS provides multiple ways to retrieve credentials which can be used when making +future AWS service API operation calls. + +The SDK will ensure that per instance of credentials.Credentials all requests +to refresh the credentials will be synchronized. But, the SDK is unable to +ensure synchronous usage of the AssumeRoleProvider if the value is shared +between multiple Credentials, Sessions or service clients. + +Assume Role + +To assume an IAM role using STS with the SDK you can create a new Credentials +with the SDKs's stscreds package. + + // Initial credentials loaded from SDK's default credential chain. Such as + // the environment, shared credentials (~/.aws/credentials), or EC2 Instance + // Role. These credentials will be used to to make the STS Assume Role API. + sess := session.Must(session.NewSession()) + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN. + creds := stscreds.NewCredentials(sess, "myRoleArn") + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +Assume Role with static MFA Token + +To assume an IAM role with a MFA token you can either specify a MFA token code +directly or provide a function to prompt the user each time the credentials +need to refresh the role's credentials. Specifying the TokenCode should be used +for short lived operations that will not need to be refreshed, and when you do +not want to have direct control over the user provides their MFA token. + +With TokenCode the AssumeRoleProvider will be not be able to refresh the role's +credentials. + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN using the MFA token code provided. + creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) { + p.SerialNumber = aws.String("myTokenSerialNumber") + p.TokenCode = aws.String("00000000") + }) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +Assume Role with MFA Token Provider + +To assume an IAM role with MFA for longer running tasks where the credentials +may need to be refreshed setting the TokenProvider field of AssumeRoleProvider +will allow the credential provider to prompt for new MFA token code when the +role's credentials need to be refreshed. + +The StdinTokenProvider function is available to prompt on stdin to retrieve +the MFA token code from the user. You can also implement custom prompts by +satisfing the TokenProvider function signature. + +Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will +have undesirable results as the StdinTokenProvider will not be synchronized. A +single Credentials with an AssumeRoleProvider can be shared safely. + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin. + creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) { + p.SerialNumber = aws.String("myTokenSerialNumber") + p.TokenProvider = stscreds.StdinTokenProvider + }) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +*/ +package stscreds + +import ( + "fmt" + "os" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/internal/sdkrand" + "github.com/aws/aws-sdk-go/service/sts" +) + +// StdinTokenProvider will prompt on stderr and read from stdin for a string value. +// An error is returned if reading from stdin fails. +// +// Use this function go read MFA tokens from stdin. The function makes no attempt +// to make atomic prompts from stdin across multiple gorouties. +// +// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will +// have undesirable results as the StdinTokenProvider will not be synchronized. A +// single Credentials with an AssumeRoleProvider can be shared safely +// +// Will wait forever until something is provided on the stdin. +func StdinTokenProvider() (string, error) { + var v string + fmt.Fprintf(os.Stderr, "Assume Role MFA token code: ") + _, err := fmt.Scanln(&v) + + return v, err +} + +// ProviderName provides a name of AssumeRole provider +const ProviderName = "AssumeRoleProvider" + +// AssumeRoler represents the minimal subset of the STS client API used by this provider. +type AssumeRoler interface { + AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) +} + +// DefaultDuration is the default amount of time in minutes that the credentials +// will be valid for. +var DefaultDuration = time.Duration(15) * time.Minute + +// AssumeRoleProvider retrieves temporary credentials from the STS service, and +// keeps track of their expiration time. +// +// This credential provider will be used by the SDKs default credential change +// when shared configuration is enabled, and the shared config or shared credentials +// file configure assume role. See Session docs for how to do this. +// +// AssumeRoleProvider does not provide any synchronization and it is not safe +// to share this value across multiple Credentials, Sessions, or service clients +// without also sharing the same Credentials instance. +type AssumeRoleProvider struct { + credentials.Expiry + + // STS client to make assume role request with. + Client AssumeRoler + + // Role to be assumed. + RoleARN string + + // Session name, if you wish to reuse the credentials elsewhere. + RoleSessionName string + + // Expiry duration of the STS credentials. Defaults to 15 minutes if not set. + Duration time.Duration + + // Optional ExternalID to pass along, defaults to nil if not set. + ExternalID *string + + // The policy plain text must be 2048 bytes or shorter. However, an internal + // conversion compresses it into a packed binary format with a separate limit. + // The PackedPolicySize response element indicates by percentage how close to + // the upper size limit the policy is, with 100% equaling the maximum allowed + // size. + Policy *string + + // The identification number of the MFA device that is associated with the user + // who is making the AssumeRole call. Specify this value if the trust policy + // of the role being assumed includes a condition that requires MFA authentication. + // The value is either the serial number for a hardware device (such as GAHT12345678) + // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + SerialNumber *string + + // The value provided by the MFA device, if the trust policy of the role being + // assumed requires MFA (that is, if the policy includes a condition that tests + // for MFA). If the role being assumed requires MFA and if the TokenCode value + // is missing or expired, the AssumeRole call returns an "access denied" error. + // + // If SerialNumber is set and neither TokenCode nor TokenProvider are also + // set an error will be returned. + TokenCode *string + + // Async method of providing MFA token code for assuming an IAM role with MFA. + // The value returned by the function will be used as the TokenCode in the Retrieve + // call. See StdinTokenProvider for a provider that prompts and reads from stdin. + // + // This token provider will be called when ever the assumed role's + // credentials need to be refreshed when SerialNumber is also set and + // TokenCode is not set. + // + // If both TokenCode and TokenProvider is set, TokenProvider will be used and + // TokenCode is ignored. + TokenProvider func() (string, error) + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration + + // MaxJitterFrac reduces the effective Duration of each credential requested + // by a random percentage between 0 and MaxJitterFraction. MaxJitterFrac must + // have a value between 0 and 1. Any other value may lead to expected behavior. + // With a MaxJitterFrac value of 0, default) will no jitter will be used. + // + // For example, with a Duration of 30m and a MaxJitterFrac of 0.1, the + // AssumeRole call will be made with an arbitrary Duration between 27m and + // 30m. + // + // MaxJitterFrac should not be negative. + MaxJitterFrac float64 +} + +// NewCredentials returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// Takes a Config provider to create the STS client. The ConfigProvider is +// satisfied by the session.Session type. +// +// It is safe to share the returned Credentials with multiple Sessions and +// service clients. All access to the credentials and refreshing them +// will be synchronized. +func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { + p := &AssumeRoleProvider{ + Client: sts.New(c), + RoleARN: roleARN, + Duration: DefaultDuration, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// Takes an AssumeRoler which can be satisfied by the STS client. +// +// It is safe to share the returned Credentials with multiple Sessions and +// service clients. All access to the credentials and refreshing them +// will be synchronized. +func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { + p := &AssumeRoleProvider{ + Client: svc, + RoleARN: roleARN, + Duration: DefaultDuration, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// Retrieve generates a new set of temporary credentials using STS. +func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) { + // Apply defaults where parameters are not set. + if p.RoleSessionName == "" { + // Try to work out a role name that will hopefully end up unique. + p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano()) + } + if p.Duration == 0 { + // Expire as often as AWS permits. + p.Duration = DefaultDuration + } + jitter := time.Duration(sdkrand.SeededRand.Float64() * p.MaxJitterFrac * float64(p.Duration)) + input := &sts.AssumeRoleInput{ + DurationSeconds: aws.Int64(int64((p.Duration - jitter) / time.Second)), + RoleArn: aws.String(p.RoleARN), + RoleSessionName: aws.String(p.RoleSessionName), + ExternalId: p.ExternalID, + } + if p.Policy != nil { + input.Policy = p.Policy + } + if p.SerialNumber != nil { + if p.TokenCode != nil { + input.SerialNumber = p.SerialNumber + input.TokenCode = p.TokenCode + } else if p.TokenProvider != nil { + input.SerialNumber = p.SerialNumber + code, err := p.TokenProvider() + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + input.TokenCode = aws.String(code) + } else { + return credentials.Value{ProviderName: ProviderName}, + awserr.New("AssumeRoleTokenNotAvailable", + "assume role with MFA enabled, but neither TokenCode nor TokenProvider are set", nil) + } + } + + roleOutput, err := p.Client.AssumeRole(input) + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + // We will proactively generate new credentials before they expire. + p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow) + + return credentials.Value{ + AccessKeyID: *roleOutput.Credentials.AccessKeyId, + SecretAccessKey: *roleOutput.Credentials.SecretAccessKey, + SessionToken: *roleOutput.Credentials.SessionToken, + ProviderName: ProviderName, + }, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go new file mode 100644 index 000000000..20510d9ae --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go @@ -0,0 +1,97 @@ +package stscreds + +import ( + "fmt" + "io/ioutil" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/service/sts" + "github.com/aws/aws-sdk-go/service/sts/stsiface" +) + +const ( + // ErrCodeWebIdentity will be used as an error code when constructing + // a new error to be returned during session creation or retrieval. + ErrCodeWebIdentity = "WebIdentityErr" + + // WebIdentityProviderName is the web identity provider name + WebIdentityProviderName = "WebIdentityCredentials" +) + +// now is used to return a time.Time object representing +// the current time. This can be used to easily test and +// compare test values. +var now = time.Now + +// WebIdentityRoleProvider is used to retrieve credentials using +// an OIDC token. +type WebIdentityRoleProvider struct { + credentials.Expiry + + client stsiface.STSAPI + ExpiryWindow time.Duration + + tokenFilePath string + roleARN string + roleSessionName string +} + +// NewWebIdentityCredentials will return a new set of credentials with a given +// configuration, role arn, and token file path. +func NewWebIdentityCredentials(c client.ConfigProvider, roleARN, roleSessionName, path string) *credentials.Credentials { + svc := sts.New(c) + p := NewWebIdentityRoleProvider(svc, roleARN, roleSessionName, path) + return credentials.NewCredentials(p) +} + +// NewWebIdentityRoleProvider will return a new WebIdentityRoleProvider with the +// provided stsiface.STSAPI +func NewWebIdentityRoleProvider(svc stsiface.STSAPI, roleARN, roleSessionName, path string) *WebIdentityRoleProvider { + return &WebIdentityRoleProvider{ + client: svc, + tokenFilePath: path, + roleARN: roleARN, + roleSessionName: roleSessionName, + } +} + +// Retrieve will attempt to assume a role from a token which is located at +// 'WebIdentityTokenFilePath' specified destination and if that is empty an +// error will be returned. +func (p *WebIdentityRoleProvider) Retrieve() (credentials.Value, error) { + b, err := ioutil.ReadFile(p.tokenFilePath) + if err != nil { + errMsg := fmt.Sprintf("unable to read file at %s", p.tokenFilePath) + return credentials.Value{}, awserr.New(ErrCodeWebIdentity, errMsg, err) + } + + sessionName := p.roleSessionName + if len(sessionName) == 0 { + // session name is used to uniquely identify a session. This simply + // uses unix time in nanoseconds to uniquely identify sessions. + sessionName = strconv.FormatInt(now().UnixNano(), 10) + } + resp, err := p.client.AssumeRoleWithWebIdentity(&sts.AssumeRoleWithWebIdentityInput{ + RoleArn: &p.roleARN, + RoleSessionName: &sessionName, + WebIdentityToken: aws.String(string(b)), + }) + if err != nil { + return credentials.Value{}, awserr.New(ErrCodeWebIdentity, "failed to retrieve credentials", err) + } + + p.SetExpiration(aws.TimeValue(resp.Credentials.Expiration), p.ExpiryWindow) + + value := credentials.Value{ + AccessKeyID: aws.StringValue(resp.Credentials.AccessKeyId), + SecretAccessKey: aws.StringValue(resp.Credentials.SecretAccessKey), + SessionToken: aws.StringValue(resp.Credentials.SessionToken), + ProviderName: WebIdentityProviderName, + } + return value, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go new file mode 100644 index 000000000..25a66d1dd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go @@ -0,0 +1,69 @@ +// Package csm provides the Client Side Monitoring (CSM) client which enables +// sending metrics via UDP connection to the CSM agent. This package provides +// control options, and configuration for the CSM client. The client can be +// controlled manually, or automatically via the SDK's Session configuration. +// +// Enabling CSM client via SDK's Session configuration +// +// The CSM client can be enabled automatically via SDK's Session configuration. +// The SDK's session configuration enables the CSM client if the AWS_CSM_PORT +// environment variable is set to a non-empty value. +// +// The configuration options for the CSM client via the SDK's session +// configuration are: +// +// * AWS_CSM_PORT= +// The port number the CSM agent will receive metrics on. +// +// * AWS_CSM_HOST= +// The hostname, or IP address the CSM agent will receive metrics on. +// Without port number. +// +// Manually enabling the CSM client +// +// The CSM client can be started, paused, and resumed manually. The Start +// function will enable the CSM client to publish metrics to the CSM agent. It +// is safe to call Start concurrently, but if Start is called additional times +// with different ClientID or address it will panic. +// +// r, err := csm.Start("clientID", ":31000") +// if err != nil { +// panic(fmt.Errorf("failed starting CSM: %v", err)) +// } +// +// When controlling the CSM client manually, you must also inject its request +// handlers into the SDK's Session configuration for the SDK's API clients to +// publish metrics. +// +// sess, err := session.NewSession(&aws.Config{}) +// if err != nil { +// panic(fmt.Errorf("failed loading session: %v", err)) +// } +// +// // Add CSM client's metric publishing request handlers to the SDK's +// // Session Configuration. +// r.InjectHandlers(&sess.Handlers) +// +// Controlling CSM client +// +// Once the CSM client has been enabled the Get function will return a Reporter +// value that you can use to pause and resume the metrics published to the CSM +// agent. If Get function is called before the reporter is enabled with the +// Start function or via SDK's Session configuration nil will be returned. +// +// The Pause method can be called to stop the CSM client publishing metrics to +// the CSM agent. The Continue method will resume metric publishing. +// +// // Get the CSM client Reporter. +// r := csm.Get() +// +// // Will pause monitoring +// r.Pause() +// resp, err = client.GetObject(&s3.GetObjectInput{ +// Bucket: aws.String("bucket"), +// Key: aws.String("key"), +// }) +// +// // Resume monitoring +// r.Continue() +package csm diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go new file mode 100644 index 000000000..4b19e2800 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go @@ -0,0 +1,89 @@ +package csm + +import ( + "fmt" + "strings" + "sync" +) + +var ( + lock sync.Mutex +) + +const ( + // DefaultPort is used when no port is specified. + DefaultPort = "31000" + + // DefaultHost is the host that will be used when none is specified. + DefaultHost = "127.0.0.1" +) + +// AddressWithDefaults returns a CSM address built from the host and port +// values. If the host or port is not set, default values will be used +// instead. If host is "localhost" it will be replaced with "127.0.0.1". +func AddressWithDefaults(host, port string) string { + if len(host) == 0 || strings.EqualFold(host, "localhost") { + host = DefaultHost + } + + if len(port) == 0 { + port = DefaultPort + } + + // Only IP6 host can contain a colon + if strings.Contains(host, ":") { + return "[" + host + "]:" + port + } + + return host + ":" + port +} + +// Start will start a long running go routine to capture +// client side metrics. Calling start multiple time will only +// start the metric listener once and will panic if a different +// client ID or port is passed in. +// +// r, err := csm.Start("clientID", "127.0.0.1:31000") +// if err != nil { +// panic(fmt.Errorf("expected no error, but received %v", err)) +// } +// sess := session.NewSession() +// r.InjectHandlers(sess.Handlers) +// +// svc := s3.New(sess) +// out, err := svc.GetObject(&s3.GetObjectInput{ +// Bucket: aws.String("bucket"), +// Key: aws.String("key"), +// }) +func Start(clientID string, url string) (*Reporter, error) { + lock.Lock() + defer lock.Unlock() + + if sender == nil { + sender = newReporter(clientID, url) + } else { + if sender.clientID != clientID { + panic(fmt.Errorf("inconsistent client IDs. %q was expected, but received %q", sender.clientID, clientID)) + } + + if sender.url != url { + panic(fmt.Errorf("inconsistent URLs. %q was expected, but received %q", sender.url, url)) + } + } + + if err := connect(url); err != nil { + sender = nil + return nil, err + } + + return sender, nil +} + +// Get will return a reporter if one exists, if one does not exist, nil will +// be returned. +func Get() *Reporter { + lock.Lock() + defer lock.Unlock() + + return sender +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go new file mode 100644 index 000000000..5bacc791a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go @@ -0,0 +1,109 @@ +package csm + +import ( + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" +) + +type metricTime time.Time + +func (t metricTime) MarshalJSON() ([]byte, error) { + ns := time.Duration(time.Time(t).UnixNano()) + return []byte(strconv.FormatInt(int64(ns/time.Millisecond), 10)), nil +} + +type metric struct { + ClientID *string `json:"ClientId,omitempty"` + API *string `json:"Api,omitempty"` + Service *string `json:"Service,omitempty"` + Timestamp *metricTime `json:"Timestamp,omitempty"` + Type *string `json:"Type,omitempty"` + Version *int `json:"Version,omitempty"` + + AttemptCount *int `json:"AttemptCount,omitempty"` + Latency *int `json:"Latency,omitempty"` + + Fqdn *string `json:"Fqdn,omitempty"` + UserAgent *string `json:"UserAgent,omitempty"` + AttemptLatency *int `json:"AttemptLatency,omitempty"` + + SessionToken *string `json:"SessionToken,omitempty"` + Region *string `json:"Region,omitempty"` + AccessKey *string `json:"AccessKey,omitempty"` + HTTPStatusCode *int `json:"HttpStatusCode,omitempty"` + XAmzID2 *string `json:"XAmzId2,omitempty"` + XAmzRequestID *string `json:"XAmznRequestId,omitempty"` + + AWSException *string `json:"AwsException,omitempty"` + AWSExceptionMessage *string `json:"AwsExceptionMessage,omitempty"` + SDKException *string `json:"SdkException,omitempty"` + SDKExceptionMessage *string `json:"SdkExceptionMessage,omitempty"` + + FinalHTTPStatusCode *int `json:"FinalHttpStatusCode,omitempty"` + FinalAWSException *string `json:"FinalAwsException,omitempty"` + FinalAWSExceptionMessage *string `json:"FinalAwsExceptionMessage,omitempty"` + FinalSDKException *string `json:"FinalSdkException,omitempty"` + FinalSDKExceptionMessage *string `json:"FinalSdkExceptionMessage,omitempty"` + + DestinationIP *string `json:"DestinationIp,omitempty"` + ConnectionReused *int `json:"ConnectionReused,omitempty"` + + AcquireConnectionLatency *int `json:"AcquireConnectionLatency,omitempty"` + ConnectLatency *int `json:"ConnectLatency,omitempty"` + RequestLatency *int `json:"RequestLatency,omitempty"` + DNSLatency *int `json:"DnsLatency,omitempty"` + TCPLatency *int `json:"TcpLatency,omitempty"` + SSLLatency *int `json:"SslLatency,omitempty"` + + MaxRetriesExceeded *int `json:"MaxRetriesExceeded,omitempty"` +} + +func (m *metric) TruncateFields() { + m.ClientID = truncateString(m.ClientID, 255) + m.UserAgent = truncateString(m.UserAgent, 256) + + m.AWSException = truncateString(m.AWSException, 128) + m.AWSExceptionMessage = truncateString(m.AWSExceptionMessage, 512) + + m.SDKException = truncateString(m.SDKException, 128) + m.SDKExceptionMessage = truncateString(m.SDKExceptionMessage, 512) + + m.FinalAWSException = truncateString(m.FinalAWSException, 128) + m.FinalAWSExceptionMessage = truncateString(m.FinalAWSExceptionMessage, 512) + + m.FinalSDKException = truncateString(m.FinalSDKException, 128) + m.FinalSDKExceptionMessage = truncateString(m.FinalSDKExceptionMessage, 512) +} + +func truncateString(v *string, l int) *string { + if v != nil && len(*v) > l { + nv := (*v)[:l] + return &nv + } + + return v +} + +func (m *metric) SetException(e metricException) { + switch te := e.(type) { + case awsException: + m.AWSException = aws.String(te.exception) + m.AWSExceptionMessage = aws.String(te.message) + case sdkException: + m.SDKException = aws.String(te.exception) + m.SDKExceptionMessage = aws.String(te.message) + } +} + +func (m *metric) SetFinalException(e metricException) { + switch te := e.(type) { + case awsException: + m.FinalAWSException = aws.String(te.exception) + m.FinalAWSExceptionMessage = aws.String(te.message) + case sdkException: + m.FinalSDKException = aws.String(te.exception) + m.FinalSDKExceptionMessage = aws.String(te.message) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go new file mode 100644 index 000000000..514fc3739 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go @@ -0,0 +1,54 @@ +package csm + +import ( + "sync/atomic" +) + +const ( + runningEnum = iota + pausedEnum +) + +var ( + // MetricsChannelSize of metrics to hold in the channel + MetricsChannelSize = 100 +) + +type metricChan struct { + ch chan metric + paused int64 +} + +func newMetricChan(size int) metricChan { + return metricChan{ + ch: make(chan metric, size), + } +} + +func (ch *metricChan) Pause() { + atomic.StoreInt64(&ch.paused, pausedEnum) +} + +func (ch *metricChan) Continue() { + atomic.StoreInt64(&ch.paused, runningEnum) +} + +func (ch *metricChan) IsPaused() bool { + v := atomic.LoadInt64(&ch.paused) + return v == pausedEnum +} + +// Push will push metrics to the metric channel if the channel +// is not paused +func (ch *metricChan) Push(m metric) bool { + if ch.IsPaused() { + return false + } + + select { + case ch.ch <- m: + return true + default: + return false + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go new file mode 100644 index 000000000..54a99280c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go @@ -0,0 +1,26 @@ +package csm + +type metricException interface { + Exception() string + Message() string +} + +type requestException struct { + exception string + message string +} + +func (e requestException) Exception() string { + return e.exception +} +func (e requestException) Message() string { + return e.message +} + +type awsException struct { + requestException +} + +type sdkException struct { + requestException +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go new file mode 100644 index 000000000..c7008d8c3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go @@ -0,0 +1,265 @@ +package csm + +import ( + "encoding/json" + "net" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +// Reporter will gather metrics of API requests made and +// send those metrics to the CSM endpoint. +type Reporter struct { + clientID string + url string + conn net.Conn + metricsCh metricChan + done chan struct{} +} + +var ( + sender *Reporter +) + +func connect(url string) error { + const network = "udp" + if err := sender.connect(network, url); err != nil { + return err + } + + if sender.done == nil { + sender.done = make(chan struct{}) + go sender.start() + } + + return nil +} + +func newReporter(clientID, url string) *Reporter { + return &Reporter{ + clientID: clientID, + url: url, + metricsCh: newMetricChan(MetricsChannelSize), + } +} + +func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) { + if rep == nil { + return + } + + now := time.Now() + creds, _ := r.Config.Credentials.Get() + + m := metric{ + ClientID: aws.String(rep.clientID), + API: aws.String(r.Operation.Name), + Service: aws.String(r.ClientInfo.ServiceID), + Timestamp: (*metricTime)(&now), + UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")), + Region: r.Config.Region, + Type: aws.String("ApiCallAttempt"), + Version: aws.Int(1), + + XAmzRequestID: aws.String(r.RequestID), + + AttemptCount: aws.Int(r.RetryCount + 1), + AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))), + AccessKey: aws.String(creds.AccessKeyID), + } + + if r.HTTPResponse != nil { + m.HTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode) + } + + if r.Error != nil { + if awserr, ok := r.Error.(awserr.Error); ok { + m.SetException(getMetricException(awserr)) + } + } + + m.TruncateFields() + rep.metricsCh.Push(m) +} + +func getMetricException(err awserr.Error) metricException { + msg := err.Error() + code := err.Code() + + switch code { + case "RequestError", + request.ErrCodeSerialization, + request.CanceledErrorCode: + return sdkException{ + requestException{exception: code, message: msg}, + } + default: + return awsException{ + requestException{exception: code, message: msg}, + } + } +} + +func (rep *Reporter) sendAPICallMetric(r *request.Request) { + if rep == nil { + return + } + + now := time.Now() + m := metric{ + ClientID: aws.String(rep.clientID), + API: aws.String(r.Operation.Name), + Service: aws.String(r.ClientInfo.ServiceID), + Timestamp: (*metricTime)(&now), + UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")), + Type: aws.String("ApiCall"), + AttemptCount: aws.Int(r.RetryCount + 1), + Region: r.Config.Region, + Latency: aws.Int(int(time.Since(r.Time) / time.Millisecond)), + XAmzRequestID: aws.String(r.RequestID), + MaxRetriesExceeded: aws.Int(boolIntValue(r.RetryCount >= r.MaxRetries())), + } + + if r.HTTPResponse != nil { + m.FinalHTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode) + } + + if r.Error != nil { + if awserr, ok := r.Error.(awserr.Error); ok { + m.SetFinalException(getMetricException(awserr)) + } + } + + m.TruncateFields() + + // TODO: Probably want to figure something out for logging dropped + // metrics + rep.metricsCh.Push(m) +} + +func (rep *Reporter) connect(network, url string) error { + if rep.conn != nil { + rep.conn.Close() + } + + conn, err := net.Dial(network, url) + if err != nil { + return awserr.New("UDPError", "Could not connect", err) + } + + rep.conn = conn + + return nil +} + +func (rep *Reporter) close() { + if rep.done != nil { + close(rep.done) + } + + rep.metricsCh.Pause() +} + +func (rep *Reporter) start() { + defer func() { + rep.metricsCh.Pause() + }() + + for { + select { + case <-rep.done: + rep.done = nil + return + case m := <-rep.metricsCh.ch: + // TODO: What to do with this error? Probably should just log + b, err := json.Marshal(m) + if err != nil { + continue + } + + rep.conn.Write(b) + } + } +} + +// Pause will pause the metric channel preventing any new metrics from being +// added. It is safe to call concurrently with other calls to Pause, but if +// called concurently with Continue can lead to unexpected state. +func (rep *Reporter) Pause() { + lock.Lock() + defer lock.Unlock() + + if rep == nil { + return + } + + rep.close() +} + +// Continue will reopen the metric channel and allow for monitoring to be +// resumed. It is safe to call concurrently with other calls to Continue, but +// if called concurently with Pause can lead to unexpected state. +func (rep *Reporter) Continue() { + lock.Lock() + defer lock.Unlock() + if rep == nil { + return + } + + if !rep.metricsCh.IsPaused() { + return + } + + rep.metricsCh.Continue() +} + +// Client side metric handler names +const ( + APICallMetricHandlerName = "awscsm.SendAPICallMetric" + APICallAttemptMetricHandlerName = "awscsm.SendAPICallAttemptMetric" +) + +// InjectHandlers will will enable client side metrics and inject the proper +// handlers to handle how metrics are sent. +// +// InjectHandlers is NOT safe to call concurrently. Calling InjectHandlers +// multiple times may lead to unexpected behavior, (e.g. duplicate metrics). +// +// // Start must be called in order to inject the correct handlers +// r, err := csm.Start("clientID", "127.0.0.1:8094") +// if err != nil { +// panic(fmt.Errorf("expected no error, but received %v", err)) +// } +// +// sess := session.NewSession() +// r.InjectHandlers(&sess.Handlers) +// +// // create a new service client with our client side metric session +// svc := s3.New(sess) +func (rep *Reporter) InjectHandlers(handlers *request.Handlers) { + if rep == nil { + return + } + + handlers.Complete.PushFrontNamed(request.NamedHandler{ + Name: APICallMetricHandlerName, + Fn: rep.sendAPICallMetric, + }) + + handlers.CompleteAttempt.PushFrontNamed(request.NamedHandler{ + Name: APICallAttemptMetricHandlerName, + Fn: rep.sendAPICallAttemptMetric, + }) +} + +// boolIntValue return 1 for true and 0 for false. +func boolIntValue(b bool) int { + if b { + return 1 + } + + return 0 +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go new file mode 100644 index 000000000..23bb639e0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go @@ -0,0 +1,207 @@ +// Package defaults is a collection of helpers to retrieve the SDK's default +// configuration and handlers. +// +// Generally this package shouldn't be used directly, but session.Session +// instead. This package is useful when you need to reset the defaults +// of a session or service client to the SDK defaults before setting +// additional parameters. +package defaults + +import ( + "fmt" + "net" + "net/http" + "net/url" + "os" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" + "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds" + "github.com/aws/aws-sdk-go/aws/ec2metadata" + "github.com/aws/aws-sdk-go/aws/endpoints" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/shareddefaults" +) + +// A Defaults provides a collection of default values for SDK clients. +type Defaults struct { + Config *aws.Config + Handlers request.Handlers +} + +// Get returns the SDK's default values with Config and handlers pre-configured. +func Get() Defaults { + cfg := Config() + handlers := Handlers() + cfg.Credentials = CredChain(cfg, handlers) + + return Defaults{ + Config: cfg, + Handlers: handlers, + } +} + +// Config returns the default configuration without credentials. +// To retrieve a config with credentials also included use +// `defaults.Get().Config` instead. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the configuration of an +// existing service client or session. +func Config() *aws.Config { + return aws.NewConfig(). + WithCredentials(credentials.AnonymousCredentials). + WithRegion(os.Getenv("AWS_REGION")). + WithHTTPClient(http.DefaultClient). + WithMaxRetries(aws.UseServiceDefaultRetries). + WithLogger(aws.NewDefaultLogger()). + WithLogLevel(aws.LogOff). + WithEndpointResolver(endpoints.DefaultResolver()) +} + +// Handlers returns the default request handlers. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the request handlers of an +// existing service client or session. +func Handlers() request.Handlers { + var handlers request.Handlers + + handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) + handlers.Validate.AfterEachFn = request.HandlerListStopOnError + handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) + handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander) + handlers.Build.AfterEachFn = request.HandlerListStopOnError + handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) + handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler) + handlers.Send.PushBackNamed(corehandlers.SendHandler) + handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) + handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) + + return handlers +} + +// CredChain returns the default credential chain. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the credentials of an +// existing service client or session's Config. +func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { + return credentials.NewCredentials(&credentials.ChainProvider{ + VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), + Providers: CredProviders(cfg, handlers), + }) +} + +// CredProviders returns the slice of providers used in +// the default credential chain. +// +// For applications that need to use some other provider (for example use +// different environment variables for legacy reasons) but still fall back +// on the default chain of providers. This allows that default chaint to be +// automatically updated +func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Provider { + return []credentials.Provider{ + &credentials.EnvProvider{}, + &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, + RemoteCredProvider(*cfg, handlers), + } +} + +const ( + httpProviderAuthorizationEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN" + httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI" +) + +// RemoteCredProvider returns a credentials provider for the default remote +// endpoints such as EC2 or ECS Roles. +func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { + if u := os.Getenv(httpProviderEnvVar); len(u) > 0 { + return localHTTPCredProvider(cfg, handlers, u) + } + + if uri := os.Getenv(shareddefaults.ECSCredsProviderEnvVar); len(uri) > 0 { + u := fmt.Sprintf("%s%s", shareddefaults.ECSContainerCredentialsURI, uri) + return httpCredProvider(cfg, handlers, u) + } + + return ec2RoleProvider(cfg, handlers) +} + +var lookupHostFn = net.LookupHost + +func isLoopbackHost(host string) (bool, error) { + ip := net.ParseIP(host) + if ip != nil { + return ip.IsLoopback(), nil + } + + // Host is not an ip, perform lookup + addrs, err := lookupHostFn(host) + if err != nil { + return false, err + } + for _, addr := range addrs { + if !net.ParseIP(addr).IsLoopback() { + return false, nil + } + } + + return true, nil +} + +func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { + var errMsg string + + parsed, err := url.Parse(u) + if err != nil { + errMsg = fmt.Sprintf("invalid URL, %v", err) + } else { + host := aws.URLHostname(parsed) + if len(host) == 0 { + errMsg = "unable to parse host from local HTTP cred provider URL" + } else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil { + errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr) + } else if !isLoopback { + errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host) + } + } + + if len(errMsg) > 0 { + if cfg.Logger != nil { + cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err) + } + return credentials.ErrorProvider{ + Err: awserr.New("CredentialsEndpointError", errMsg, err), + ProviderName: endpointcreds.ProviderName, + } + } + + return httpCredProvider(cfg, handlers, u) +} + +func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { + return endpointcreds.NewProviderClient(cfg, handlers, u, + func(p *endpointcreds.Provider) { + p.ExpiryWindow = 5 * time.Minute + p.AuthorizationToken = os.Getenv(httpProviderAuthorizationEnvVar) + }, + ) +} + +func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { + resolver := cfg.EndpointResolver + if resolver == nil { + resolver = endpoints.DefaultResolver() + } + + e, _ := resolver.EndpointFor(endpoints.Ec2metadataServiceID, "") + return &ec2rolecreds.EC2RoleProvider{ + Client: ec2metadata.NewClient(cfg, handlers, e.URL, e.SigningRegion), + ExpiryWindow: 5 * time.Minute, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go new file mode 100644 index 000000000..ca0ee1dcc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go @@ -0,0 +1,27 @@ +package defaults + +import ( + "github.com/aws/aws-sdk-go/internal/shareddefaults" +) + +// SharedCredentialsFilename returns the SDK's default file path +// for the shared credentials file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/credentials +// - Windows: %USERPROFILE%\.aws\credentials +func SharedCredentialsFilename() string { + return shareddefaults.SharedCredentialsFilename() +} + +// SharedConfigFilename returns the SDK's default file path for +// the shared config file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/config +// - Windows: %USERPROFILE%\.aws\config +func SharedConfigFilename() string { + return shareddefaults.SharedConfigFilename() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/doc.go new file mode 100644 index 000000000..4fcb61618 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/doc.go @@ -0,0 +1,56 @@ +// Package aws provides the core SDK's utilities and shared types. Use this package's +// utilities to simplify setting and reading API operations parameters. +// +// Value and Pointer Conversion Utilities +// +// This package includes a helper conversion utility for each scalar type the SDK's +// API use. These utilities make getting a pointer of the scalar, and dereferencing +// a pointer easier. +// +// Each conversion utility comes in two forms. Value to Pointer and Pointer to Value. +// The Pointer to value will safely dereference the pointer and return its value. +// If the pointer was nil, the scalar's zero value will be returned. +// +// The value to pointer functions will be named after the scalar type. So get a +// *string from a string value use the "String" function. This makes it easy to +// to get pointer of a literal string value, because getting the address of a +// literal requires assigning the value to a variable first. +// +// var strPtr *string +// +// // Without the SDK's conversion functions +// str := "my string" +// strPtr = &str +// +// // With the SDK's conversion functions +// strPtr = aws.String("my string") +// +// // Convert *string to string value +// str = aws.StringValue(strPtr) +// +// In addition to scalars the aws package also includes conversion utilities for +// map and slice for commonly types used in API parameters. The map and slice +// conversion functions use similar naming pattern as the scalar conversion +// functions. +// +// var strPtrs []*string +// var strs []string = []string{"Go", "Gophers", "Go"} +// +// // Convert []string to []*string +// strPtrs = aws.StringSlice(strs) +// +// // Convert []*string to []string +// strs = aws.StringValueSlice(strPtrs) +// +// SDK Default HTTP Client +// +// The SDK will use the http.DefaultClient if a HTTP client is not provided to +// the SDK's Session, or service client constructor. This means that if the +// http.DefaultClient is modified by other components of your application the +// modifications will be picked up by the SDK as well. +// +// In some cases this might be intended, but it is a better practice to create +// a custom HTTP Client to share explicitly through your application. You can +// configure the SDK to use the custom HTTP Client by setting the HTTPClient +// value of the SDK's Config type when creating a Session or service client. +package aws diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go new file mode 100644 index 000000000..2c8d5f56d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go @@ -0,0 +1,169 @@ +package ec2metadata + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/sdkuri" +) + +// GetMetadata uses the path provided to request information from the EC2 +// instance metdata service. The content will be returned as a string, or +// error if the request failed. +func (c *EC2Metadata) GetMetadata(p string) (string, error) { + op := &request.Operation{ + Name: "GetMetadata", + HTTPMethod: "GET", + HTTPPath: sdkuri.PathJoin("/meta-data", p), + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + err := req.Send() + + return output.Content, err +} + +// GetUserData returns the userdata that was configured for the service. If +// there is no user-data setup for the EC2 instance a "NotFoundError" error +// code will be returned. +func (c *EC2Metadata) GetUserData() (string, error) { + op := &request.Operation{ + Name: "GetUserData", + HTTPMethod: "GET", + HTTPPath: "/user-data", + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + req.Handlers.UnmarshalError.PushBack(func(r *request.Request) { + if r.HTTPResponse.StatusCode == http.StatusNotFound { + r.Error = awserr.New("NotFoundError", "user-data not found", r.Error) + } + }) + err := req.Send() + + return output.Content, err +} + +// GetDynamicData uses the path provided to request information from the EC2 +// instance metadata service for dynamic data. The content will be returned +// as a string, or error if the request failed. +func (c *EC2Metadata) GetDynamicData(p string) (string, error) { + op := &request.Operation{ + Name: "GetDynamicData", + HTTPMethod: "GET", + HTTPPath: sdkuri.PathJoin("/dynamic", p), + } + + output := &metadataOutput{} + req := c.NewRequest(op, nil, output) + err := req.Send() + + return output.Content, err +} + +// GetInstanceIdentityDocument retrieves an identity document describing an +// instance. Error is returned if the request fails or is unable to parse +// the response. +func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument, error) { + resp, err := c.GetDynamicData("instance-identity/document") + if err != nil { + return EC2InstanceIdentityDocument{}, + awserr.New("EC2MetadataRequestError", + "failed to get EC2 instance identity document", err) + } + + doc := EC2InstanceIdentityDocument{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil { + return EC2InstanceIdentityDocument{}, + awserr.New(request.ErrCodeSerialization, + "failed to decode EC2 instance identity document", err) + } + + return doc, nil +} + +// IAMInfo retrieves IAM info from the metadata API +func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) { + resp, err := c.GetMetadata("iam/info") + if err != nil { + return EC2IAMInfo{}, + awserr.New("EC2MetadataRequestError", + "failed to get EC2 IAM info", err) + } + + info := EC2IAMInfo{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil { + return EC2IAMInfo{}, + awserr.New(request.ErrCodeSerialization, + "failed to decode EC2 IAM info", err) + } + + if info.Code != "Success" { + errMsg := fmt.Sprintf("failed to get EC2 IAM Info (%s)", info.Code) + return EC2IAMInfo{}, + awserr.New("EC2MetadataError", errMsg, nil) + } + + return info, nil +} + +// Region returns the region the instance is running in. +func (c *EC2Metadata) Region() (string, error) { + resp, err := c.GetMetadata("placement/availability-zone") + if err != nil { + return "", err + } + + if len(resp) == 0 { + return "", awserr.New("EC2MetadataError", "invalid Region response", nil) + } + + // returns region without the suffix. Eg: us-west-2a becomes us-west-2 + return resp[:len(resp)-1], nil +} + +// Available returns if the application has access to the EC2 Metadata service. +// Can be used to determine if application is running within an EC2 Instance and +// the metadata service is available. +func (c *EC2Metadata) Available() bool { + if _, err := c.GetMetadata("instance-id"); err != nil { + return false + } + + return true +} + +// An EC2IAMInfo provides the shape for unmarshaling +// an IAM info from the metadata API +type EC2IAMInfo struct { + Code string + LastUpdated time.Time + InstanceProfileArn string + InstanceProfileID string +} + +// An EC2InstanceIdentityDocument provides the shape for unmarshaling +// an instance identity document +type EC2InstanceIdentityDocument struct { + DevpayProductCodes []string `json:"devpayProductCodes"` + AvailabilityZone string `json:"availabilityZone"` + PrivateIP string `json:"privateIp"` + Version string `json:"version"` + Region string `json:"region"` + InstanceID string `json:"instanceId"` + BillingProducts []string `json:"billingProducts"` + InstanceType string `json:"instanceType"` + AccountID string `json:"accountId"` + PendingTime time.Time `json:"pendingTime"` + ImageID string `json:"imageId"` + KernelID string `json:"kernelId"` + RamdiskID string `json:"ramdiskId"` + Architecture string `json:"architecture"` +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go new file mode 100644 index 000000000..4c5636e35 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go @@ -0,0 +1,152 @@ +// Package ec2metadata provides the client for making API calls to the +// EC2 Metadata service. +// +// This package's client can be disabled completely by setting the environment +// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to +// true instructs the SDK to disable the EC2 Metadata client. The client cannot +// be used while the environment variable is set to true, (case insensitive). +package ec2metadata + +import ( + "bytes" + "errors" + "io" + "net/http" + "os" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/request" +) + +// ServiceName is the name of the service. +const ServiceName = "ec2metadata" +const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED" + +// A EC2Metadata is an EC2 Metadata service Client. +type EC2Metadata struct { + *client.Client +} + +// New creates a new instance of the EC2Metadata client with a session. +// This client is safe to use across multiple goroutines. +// +// +// Example: +// // Create a EC2Metadata client from just a session. +// svc := ec2metadata.New(mySession) +// +// // Create a EC2Metadata client with additional configuration +// svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody)) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata { + c := p.ClientConfig(ServiceName, cfgs...) + return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion) +} + +// NewClient returns a new EC2Metadata client. Should be used to create +// a client when not using a session. Generally using just New with a session +// is preferred. +// +// If an unmodified HTTP client is provided from the stdlib default, or no client +// the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened. +// To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default. +func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata { + if !aws.BoolValue(cfg.EC2MetadataDisableTimeoutOverride) && httpClientZero(cfg.HTTPClient) { + // If the http client is unmodified and this feature is not disabled + // set custom timeouts for EC2Metadata requests. + cfg.HTTPClient = &http.Client{ + // use a shorter timeout than default because the metadata + // service is local if it is running, and to fail faster + // if not running on an ec2 instance. + Timeout: 5 * time.Second, + } + } + + svc := &EC2Metadata{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceName, + Endpoint: endpoint, + APIVersion: "latest", + }, + handlers, + ), + } + + svc.Handlers.Unmarshal.PushBack(unmarshalHandler) + svc.Handlers.UnmarshalError.PushBack(unmarshalError) + svc.Handlers.Validate.Clear() + svc.Handlers.Validate.PushBack(validateEndpointHandler) + + // Disable the EC2 Metadata service if the environment variable is set. + // This shortcirctes the service's functionality to always fail to send + // requests. + if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" { + svc.Handlers.Send.SwapNamed(request.NamedHandler{ + Name: corehandlers.SendHandler.Name, + Fn: func(r *request.Request) { + r.HTTPResponse = &http.Response{ + Header: http.Header{}, + } + r.Error = awserr.New( + request.CanceledErrorCode, + "EC2 IMDS access disabled via "+disableServiceEnvVar+" env var", + nil) + }, + }) + } + + // Add additional options to the service config + for _, option := range opts { + option(svc.Client) + } + + return svc +} + +func httpClientZero(c *http.Client) bool { + return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0) +} + +type metadataOutput struct { + Content string +} + +func unmarshalHandler(r *request.Request) { + defer r.HTTPResponse.Body.Close() + b := &bytes.Buffer{} + if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata response", err) + return + } + + if data, ok := r.Data.(*metadataOutput); ok { + data.Content = b.String() + } +} + +func unmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + b := &bytes.Buffer{} + if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata error response", err) + return + } + + // Response body format is not consistent between metadata endpoints. + // Grab the error message as a string and include that as the source error + r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String())) +} + +func validateEndpointHandler(r *request.Request) { + if r.ClientInfo.Endpoint == "" { + r.Error = aws.ErrMissingEndpoint + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go new file mode 100644 index 000000000..87b9ff3ff --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go @@ -0,0 +1,188 @@ +package endpoints + +import ( + "encoding/json" + "fmt" + "io" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +type modelDefinition map[string]json.RawMessage + +// A DecodeModelOptions are the options for how the endpoints model definition +// are decoded. +type DecodeModelOptions struct { + SkipCustomizations bool +} + +// Set combines all of the option functions together. +func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) { + for _, fn := range optFns { + fn(d) + } +} + +// DecodeModel unmarshals a Regions and Endpoint model definition file into +// a endpoint Resolver. If the file format is not supported, or an error occurs +// when unmarshaling the model an error will be returned. +// +// Casting the return value of this func to a EnumPartitions will +// allow you to get a list of the partitions in the order the endpoints +// will be resolved in. +// +// resolver, err := endpoints.DecodeModel(reader) +// +// partitions := resolver.(endpoints.EnumPartitions).Partitions() +// for _, p := range partitions { +// // ... inspect partitions +// } +func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (Resolver, error) { + var opts DecodeModelOptions + opts.Set(optFns...) + + // Get the version of the partition file to determine what + // unmarshaling model to use. + modelDef := modelDefinition{} + if err := json.NewDecoder(r).Decode(&modelDef); err != nil { + return nil, newDecodeModelError("failed to decode endpoints model", err) + } + + var version string + if b, ok := modelDef["version"]; ok { + version = string(b) + } else { + return nil, newDecodeModelError("endpoints version not found in model", nil) + } + + if version == "3" { + return decodeV3Endpoints(modelDef, opts) + } + + return nil, newDecodeModelError( + fmt.Sprintf("endpoints version %s, not supported", version), nil) +} + +func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resolver, error) { + b, ok := modelDef["partitions"] + if !ok { + return nil, newDecodeModelError("endpoints model missing partitions", nil) + } + + ps := partitions{} + if err := json.Unmarshal(b, &ps); err != nil { + return nil, newDecodeModelError("failed to decode endpoints model", err) + } + + if opts.SkipCustomizations { + return ps, nil + } + + // Customization + for i := 0; i < len(ps); i++ { + p := &ps[i] + custAddEC2Metadata(p) + custAddS3DualStack(p) + custRmIotDataService(p) + custFixAppAutoscalingChina(p) + custFixAppAutoscalingUsGov(p) + } + + return ps, nil +} + +func custAddS3DualStack(p *partition) { + if p.ID != "aws" { + return + } + + custAddDualstack(p, "s3") + custAddDualstack(p, "s3-control") +} + +func custAddDualstack(p *partition, svcName string) { + s, ok := p.Services[svcName] + if !ok { + return + } + + s.Defaults.HasDualStack = boxedTrue + s.Defaults.DualStackHostname = "{service}.dualstack.{region}.{dnsSuffix}" + + p.Services[svcName] = s +} + +func custAddEC2Metadata(p *partition) { + p.Services["ec2metadata"] = service{ + IsRegionalized: boxedFalse, + PartitionEndpoint: "aws-global", + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "169.254.169.254/latest", + Protocols: []string{"http"}, + }, + }, + } +} + +func custRmIotDataService(p *partition) { + delete(p.Services, "data.iot") +} + +func custFixAppAutoscalingChina(p *partition) { + if p.ID != "aws-cn" { + return + } + + const serviceName = "application-autoscaling" + s, ok := p.Services[serviceName] + if !ok { + return + } + + const expectHostname = `autoscaling.{region}.amazonaws.com` + if e, a := s.Defaults.Hostname, expectHostname; e != a { + fmt.Printf("custFixAppAutoscalingChina: ignoring customization, expected %s, got %s\n", e, a) + return + } + + s.Defaults.Hostname = expectHostname + ".cn" + p.Services[serviceName] = s +} + +func custFixAppAutoscalingUsGov(p *partition) { + if p.ID != "aws-us-gov" { + return + } + + const serviceName = "application-autoscaling" + s, ok := p.Services[serviceName] + if !ok { + return + } + + if a := s.Defaults.CredentialScope.Service; a != "" { + fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty credential scope service, got %s\n", a) + return + } + + if a := s.Defaults.Hostname; a != "" { + fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty hostname, got %s\n", a) + return + } + + s.Defaults.CredentialScope.Service = "application-autoscaling" + s.Defaults.Hostname = "autoscaling.{region}.amazonaws.com" + + p.Services[serviceName] = s +} + +type decodeModelError struct { + awsError +} + +func newDecodeModelError(msg string, err error) decodeModelError { + return decodeModelError{ + awsError: awserr.New("DecodeEndpointsModelError", msg, err), + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go new file mode 100644 index 000000000..62a5be953 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -0,0 +1,4888 @@ +// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT. + +package endpoints + +import ( + "regexp" +) + +// Partition identifiers +const ( + AwsPartitionID = "aws" // AWS Standard partition. + AwsCnPartitionID = "aws-cn" // AWS China partition. + AwsUsGovPartitionID = "aws-us-gov" // AWS GovCloud (US) partition. +) + +// AWS Standard partition's regions. +const ( + ApEast1RegionID = "ap-east-1" // Asia Pacific (Hong Kong). + ApNortheast1RegionID = "ap-northeast-1" // Asia Pacific (Tokyo). + ApNortheast2RegionID = "ap-northeast-2" // Asia Pacific (Seoul). + ApSouth1RegionID = "ap-south-1" // Asia Pacific (Mumbai). + ApSoutheast1RegionID = "ap-southeast-1" // Asia Pacific (Singapore). + ApSoutheast2RegionID = "ap-southeast-2" // Asia Pacific (Sydney). + CaCentral1RegionID = "ca-central-1" // Canada (Central). + EuCentral1RegionID = "eu-central-1" // EU (Frankfurt). + EuNorth1RegionID = "eu-north-1" // EU (Stockholm). + EuWest1RegionID = "eu-west-1" // EU (Ireland). + EuWest2RegionID = "eu-west-2" // EU (London). + EuWest3RegionID = "eu-west-3" // EU (Paris). + MeSouth1RegionID = "me-south-1" // Middle East (Bahrain). + SaEast1RegionID = "sa-east-1" // South America (Sao Paulo). + UsEast1RegionID = "us-east-1" // US East (N. Virginia). + UsEast2RegionID = "us-east-2" // US East (Ohio). + UsWest1RegionID = "us-west-1" // US West (N. California). + UsWest2RegionID = "us-west-2" // US West (Oregon). +) + +// AWS China partition's regions. +const ( + CnNorth1RegionID = "cn-north-1" // China (Beijing). + CnNorthwest1RegionID = "cn-northwest-1" // China (Ningxia). +) + +// AWS GovCloud (US) partition's regions. +const ( + UsGovEast1RegionID = "us-gov-east-1" // AWS GovCloud (US-East). + UsGovWest1RegionID = "us-gov-west-1" // AWS GovCloud (US). +) + +// DefaultResolver returns an Endpoint resolver that will be able +// to resolve endpoints for: AWS Standard, AWS China, and AWS GovCloud (US). +// +// Use DefaultPartitions() to get the list of the default partitions. +func DefaultResolver() Resolver { + return defaultPartitions +} + +// DefaultPartitions returns a list of the partitions the SDK is bundled +// with. The available partitions are: AWS Standard, AWS China, and AWS GovCloud (US). +// +// partitions := endpoints.DefaultPartitions +// for _, p := range partitions { +// // ... inspect partitions +// } +func DefaultPartitions() []Partition { + return defaultPartitions.Partitions() +} + +var defaultPartitions = partitions{ + awsPartition, + awscnPartition, + awsusgovPartition, +} + +// AwsPartition returns the Resolver for AWS Standard. +func AwsPartition() Partition { + return awsPartition.Partition() +} + +var awsPartition = partition{ + ID: "aws", + Name: "AWS Standard", + DNSSuffix: "amazonaws.com", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^(us|eu|ap|sa|ca|me)\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "ap-east-1": region{ + Description: "Asia Pacific (Hong Kong)", + }, + "ap-northeast-1": region{ + Description: "Asia Pacific (Tokyo)", + }, + "ap-northeast-2": region{ + Description: "Asia Pacific (Seoul)", + }, + "ap-south-1": region{ + Description: "Asia Pacific (Mumbai)", + }, + "ap-southeast-1": region{ + Description: "Asia Pacific (Singapore)", + }, + "ap-southeast-2": region{ + Description: "Asia Pacific (Sydney)", + }, + "ca-central-1": region{ + Description: "Canada (Central)", + }, + "eu-central-1": region{ + Description: "EU (Frankfurt)", + }, + "eu-north-1": region{ + Description: "EU (Stockholm)", + }, + "eu-west-1": region{ + Description: "EU (Ireland)", + }, + "eu-west-2": region{ + Description: "EU (London)", + }, + "eu-west-3": region{ + Description: "EU (Paris)", + }, + "me-south-1": region{ + Description: "Middle East (Bahrain)", + }, + "sa-east-1": region{ + Description: "South America (Sao Paulo)", + }, + "us-east-1": region{ + Description: "US East (N. Virginia)", + }, + "us-east-2": region{ + Description: "US East (Ohio)", + }, + "us-west-1": region{ + Description: "US West (N. California)", + }, + "us-west-2": region{ + Description: "US West (Oregon)", + }, + }, + Services: services{ + "a4b": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "acm": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "acm-pca": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "api.ecr": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{ + Hostname: "api.ecr.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + }, + "ap-northeast-1": endpoint{ + Hostname: "api.ecr.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + "ap-northeast-2": endpoint{ + Hostname: "api.ecr.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + "ap-south-1": endpoint{ + Hostname: "api.ecr.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + "ap-southeast-1": endpoint{ + Hostname: "api.ecr.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + "ap-southeast-2": endpoint{ + Hostname: "api.ecr.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + "ca-central-1": endpoint{ + Hostname: "api.ecr.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + "eu-central-1": endpoint{ + Hostname: "api.ecr.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + "eu-north-1": endpoint{ + Hostname: "api.ecr.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + "eu-west-1": endpoint{ + Hostname: "api.ecr.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + "eu-west-2": endpoint{ + Hostname: "api.ecr.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + "eu-west-3": endpoint{ + Hostname: "api.ecr.eu-west-3.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + "me-south-1": endpoint{ + Hostname: "api.ecr.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + }, + "sa-east-1": endpoint{ + Hostname: "api.ecr.sa-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + "us-east-1": endpoint{ + Hostname: "api.ecr.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{ + Hostname: "api.ecr.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{ + Hostname: "api.ecr.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{ + Hostname: "api.ecr.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "api.mediatailor": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "api.pricing": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "pricing", + }, + }, + Endpoints: endpoints{ + "ap-south-1": endpoint{}, + "us-east-1": endpoint{}, + }, + }, + "api.sagemaker": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "api-fips.sagemaker.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "api-fips.sagemaker.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "api-fips.sagemaker.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "api-fips.sagemaker.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "apigateway": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "application-autoscaling", + }, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "appmesh": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "appstream2": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + CredentialScope: credentialScope{ + Service: "appstream", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "appsync": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "athena": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "autoscaling": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "autoscaling-plans": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "autoscaling-plans", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "backup": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "batch": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "budgets": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "budgets.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "ce": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "ce.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "chime": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + Defaults: endpoint{ + SSLCommonName: "service.chime.aws.amazon.com", + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "service.chime.aws.amazon.com", + Protocols: []string{"https"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "cloud9": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "clouddirectory": service{ + + Endpoints: endpoints{ + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudformation": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudfront": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "cloudfront.amazonaws.com", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "cloudhsm": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudhsmv2": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "cloudhsm", + }, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudsearch": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cloudtrail": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "codebuild": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "codebuild-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "codebuild-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "codebuild-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "codebuild-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "codecommit": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "fips": endpoint{ + Hostname: "codecommit-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "codedeploy": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "codedeploy-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "codedeploy-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "codedeploy-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "codedeploy-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "codepipeline": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "codestar": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cognito-identity": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cognito-idp": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cognito-sync": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "comprehend": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "comprehendmedical": service{ + + Endpoints: endpoints{ + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "config": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "cur": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "data.mediastore": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "datapipeline": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "datasync": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "fips-us-east-1": endpoint{ + Hostname: "datasync-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "fips-us-east-2": endpoint{ + Hostname: "datasync-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "fips-us-west-1": endpoint{ + Hostname: "datasync-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "fips-us-west-2": endpoint{ + Hostname: "datasync-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "dax": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "devicefarm": service{ + + Endpoints: endpoints{ + "us-west-2": endpoint{}, + }, + }, + "directconnect": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "discovery": service{ + + Endpoints: endpoints{ + "us-west-2": endpoint{}, + }, + }, + "dms": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "docdb": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{ + Hostname: "rds.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + "ap-northeast-2": endpoint{ + Hostname: "rds.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + "ap-southeast-2": endpoint{ + Hostname: "rds.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + "eu-central-1": endpoint{ + Hostname: "rds.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + "eu-west-1": endpoint{ + Hostname: "rds.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + "eu-west-2": endpoint{ + Hostname: "rds.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + "us-east-1": endpoint{ + Hostname: "rds.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{ + Hostname: "rds.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-2": endpoint{ + Hostname: "rds.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "ds": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "dynamodb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "ca-central-1-fips": endpoint{ + Hostname: "dynamodb-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "local": endpoint{ + Hostname: "localhost:8000", + Protocols: []string{"http"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "dynamodb-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "dynamodb-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "dynamodb-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "dynamodb-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "ec2": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ec2metadata": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "169.254.169.254/latest", + Protocols: []string{"http"}, + }, + }, + }, + "ecs": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticache": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "fips": endpoint{ + Hostname: "elasticache-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticbeanstalk": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticfilesystem": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticloadbalancing": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elasticmapreduce": service{ + Defaults: endpoint{ + SSLCommonName: "{region}.{service}.{dnsSuffix}", + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{ + SSLCommonName: "{service}.{region}.{dnsSuffix}", + }, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{ + SSLCommonName: "{service}.{region}.{dnsSuffix}", + }, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "elastictranscoder": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "email": service{ + + Endpoints: endpoints{ + "ap-south-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "entitlement.marketplace": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "es": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "fips": endpoint{ + Hostname: "es-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "events": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "firehose": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "fms": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "fsx": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "gamelift": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "glacier": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "glue": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "greengrass": service{ + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "groundstation": service{ + + Endpoints: endpoints{ + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "guardduty": service{ + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "health": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "iam.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "importexport": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "importexport.amazonaws.com", + SignatureVersions: []string{"v2", "v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + Service: "IngestionService", + }, + }, + }, + }, + "inspector": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "iot": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "iotanalytics": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "iotevents": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ioteventsdata": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{ + Hostname: "data.iotevents.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + "ap-southeast-2": endpoint{ + Hostname: "data.iotevents.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + "eu-central-1": endpoint{ + Hostname: "data.iotevents.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + "eu-west-1": endpoint{ + Hostname: "data.iotevents.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + "us-east-1": endpoint{ + Hostname: "data.iotevents.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{ + Hostname: "data.iotevents.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-2": endpoint{ + Hostname: "data.iotevents.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "iotthingsgraph": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "iotthingsgraph", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kafka": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kinesis": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kinesisanalytics": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kinesisvideo": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "kms": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "lakeformation": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "lambda": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "license-manager": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "lightsail": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "logs": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "machinelearning": service{ + + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + }, + }, + "marketplacecommerceanalytics": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "mediaconnect": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mediaconvert": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "medialive": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mediapackage": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mediastore": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "metering.marketplace": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mgh": service{ + + Endpoints: endpoints{ + "us-west-2": endpoint{}, + }, + }, + "mobileanalytics": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "models.lex": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "monitoring": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mq": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "mturk-requester": service{ + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "sandbox": endpoint{ + Hostname: "mturk-requester-sandbox.us-east-1.amazonaws.com", + }, + "us-east-1": endpoint{}, + }, + }, + "neptune": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{ + Hostname: "rds.ap-northeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + "ap-northeast-2": endpoint{ + Hostname: "rds.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + "ap-south-1": endpoint{ + Hostname: "rds.ap-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + "ap-southeast-1": endpoint{ + Hostname: "rds.ap-southeast-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + "ap-southeast-2": endpoint{ + Hostname: "rds.ap-southeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + "eu-central-1": endpoint{ + Hostname: "rds.eu-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + "eu-north-1": endpoint{ + Hostname: "rds.eu-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + "eu-west-1": endpoint{ + Hostname: "rds.eu-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + "eu-west-2": endpoint{ + Hostname: "rds.eu-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + "us-east-1": endpoint{ + Hostname: "rds.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{ + Hostname: "rds.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-2": endpoint{ + Hostname: "rds.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "opsworks": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "opsworks-cm": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "organizations": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "organizations.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "pinpoint": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "mobiletargeting", + }, + }, + Endpoints: endpoints{ + "ap-south-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "polly": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "projects.iot1click": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ram": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "rds": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{ + SSLCommonName: "{service}.{dnsSuffix}", + }, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "redshift": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "rekognition": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "resource-groups": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "robomaker": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "route53": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "route53.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "route53domains": service{ + + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "route53resolver": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "runtime.lex": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "lex", + }, + }, + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "runtime.sagemaker": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "runtime-fips.sagemaker.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "runtime-fips.sagemaker.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "runtime-fips.sagemaker.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "runtime-fips.sagemaker.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "s3": service{ + PartitionEndpoint: "us-east-1", + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + + HasDualStack: boxedTrue, + DualStackHostname: "{service}.dualstack.{region}.{dnsSuffix}", + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{ + Hostname: "s3.ap-northeast-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{ + Hostname: "s3.ap-southeast-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "ap-southeast-2": endpoint{ + Hostname: "s3.ap-southeast-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{ + Hostname: "s3.eu-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "s3-external-1": endpoint{ + Hostname: "s3-external-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "sa-east-1": endpoint{ + Hostname: "s3.sa-east-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "us-east-1": endpoint{ + Hostname: "s3.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "us-east-2": endpoint{}, + "us-west-1": endpoint{ + Hostname: "s3.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + "us-west-2": endpoint{ + Hostname: "s3.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3", "s3v4"}, + }, + }, + }, + "s3-control": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + + HasDualStack: boxedTrue, + DualStackHostname: "{service}.dualstack.{region}.{dnsSuffix}", + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{ + Hostname: "s3-control.ap-northeast-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-northeast-1", + }, + }, + "ap-northeast-2": endpoint{ + Hostname: "s3-control.ap-northeast-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + "ap-south-1": endpoint{ + Hostname: "s3-control.ap-south-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-south-1", + }, + }, + "ap-southeast-1": endpoint{ + Hostname: "s3-control.ap-southeast-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-southeast-1", + }, + }, + "ap-southeast-2": endpoint{ + Hostname: "s3-control.ap-southeast-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ap-southeast-2", + }, + }, + "ca-central-1": endpoint{ + Hostname: "s3-control.ca-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + "eu-central-1": endpoint{ + Hostname: "s3-control.eu-central-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-central-1", + }, + }, + "eu-north-1": endpoint{ + Hostname: "s3-control.eu-north-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-north-1", + }, + }, + "eu-west-1": endpoint{ + Hostname: "s3-control.eu-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-1", + }, + }, + "eu-west-2": endpoint{ + Hostname: "s3-control.eu-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-2", + }, + }, + "eu-west-3": endpoint{ + Hostname: "s3-control.eu-west-3.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "eu-west-3", + }, + }, + "sa-east-1": endpoint{ + Hostname: "s3-control.sa-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "sa-east-1", + }, + }, + "us-east-1": endpoint{ + Hostname: "s3-control.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-1-fips": endpoint{ + Hostname: "s3-control-fips.us-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{ + Hostname: "s3-control.us-east-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-east-2-fips": endpoint{ + Hostname: "s3-control-fips.us-east-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{ + Hostname: "s3-control.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-1-fips": endpoint{ + Hostname: "s3-control-fips.us-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{ + Hostname: "s3-control.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + "us-west-2-fips": endpoint{ + Hostname: "s3-control-fips.us-west-2.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "sdb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"v2"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{ + Hostname: "sdb.amazonaws.com", + }, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "secretsmanager": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "secretsmanager-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "secretsmanager-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "secretsmanager-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "secretsmanager-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "securityhub": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "serverlessrepo": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{ + Protocols: []string{"https"}, + }, + "ap-northeast-2": endpoint{ + Protocols: []string{"https"}, + }, + "ap-south-1": endpoint{ + Protocols: []string{"https"}, + }, + "ap-southeast-1": endpoint{ + Protocols: []string{"https"}, + }, + "ap-southeast-2": endpoint{ + Protocols: []string{"https"}, + }, + "ca-central-1": endpoint{ + Protocols: []string{"https"}, + }, + "eu-central-1": endpoint{ + Protocols: []string{"https"}, + }, + "eu-north-1": endpoint{ + Protocols: []string{"https"}, + }, + "eu-west-1": endpoint{ + Protocols: []string{"https"}, + }, + "eu-west-2": endpoint{ + Protocols: []string{"https"}, + }, + "eu-west-3": endpoint{ + Protocols: []string{"https"}, + }, + "sa-east-1": endpoint{ + Protocols: []string{"https"}, + }, + "us-east-1": endpoint{ + Protocols: []string{"https"}, + }, + "us-east-2": endpoint{ + Protocols: []string{"https"}, + }, + "us-west-1": endpoint{ + Protocols: []string{"https"}, + }, + "us-west-2": endpoint{ + Protocols: []string{"https"}, + }, + }, + }, + "servicecatalog": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "servicecatalog-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "servicecatalog-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "servicecatalog-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "servicecatalog-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "servicediscovery": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "shield": service{ + IsRegionalized: boxedFalse, + Defaults: endpoint{ + SSLCommonName: "shield.us-east-1.amazonaws.com", + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-east-1": endpoint{}, + }, + }, + "sms": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "snowball": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "sns": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "sqs": service{ + Defaults: endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "fips-us-east-1": endpoint{ + Hostname: "sqs-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "fips-us-east-2": endpoint{ + Hostname: "sqs-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "fips-us-west-1": endpoint{ + Hostname: "sqs-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "fips-us-west-2": endpoint{ + Hostname: "sqs-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{ + SSLCommonName: "queue.{dnsSuffix}", + }, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "ssm": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "states": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "storagegateway": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "ca-central-1-fips": endpoint{ + Hostname: "dynamodb-fips.ca-central-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ca-central-1", + }, + }, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "local": endpoint{ + Hostname: "localhost:8000", + Protocols: []string{"http"}, + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "dynamodb-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "dynamodb-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "dynamodb-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "dynamodb-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "sts": service{ + PartitionEndpoint: "aws-global", + Defaults: endpoint{ + Hostname: "sts.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + Endpoints: endpoints{ + "ap-east-1": endpoint{ + Hostname: "sts.ap-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-east-1", + }, + }, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{ + Hostname: "sts.ap-northeast-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "ap-northeast-2", + }, + }, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "aws-global": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{ + Hostname: "sts.me-south-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "me-south-1", + }, + }, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "sts-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "sts-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-1": endpoint{}, + "us-west-1-fips": endpoint{ + Hostname: "sts-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "sts-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "support": service{ + PartitionEndpoint: "aws-global", + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "support.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "swf": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "tagging": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "transfer": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "translate": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-1-fips": endpoint{ + Hostname: "translate-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "us-east-2": endpoint{}, + "us-east-2-fips": endpoint{ + Hostname: "translate-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "us-west-2": endpoint{}, + "us-west-2-fips": endpoint{ + Hostname: "translate-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + }, + }, + "waf": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "waf.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, + "waf-regional": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "workdocs": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "workmail": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "workspaces": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + "xray": service{ + + Endpoints: endpoints{ + "ap-east-1": endpoint{}, + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, + "ap-southeast-1": endpoint{}, + "ap-southeast-2": endpoint{}, + "ca-central-1": endpoint{}, + "eu-central-1": endpoint{}, + "eu-north-1": endpoint{}, + "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, + "eu-west-3": endpoint{}, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, + }, +} + +// AwsCnPartition returns the Resolver for AWS China. +func AwsCnPartition() Partition { + return awscnPartition.Partition() +} + +var awscnPartition = partition{ + ID: "aws-cn", + Name: "AWS China", + DNSSuffix: "amazonaws.com.cn", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^cn\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "cn-north-1": region{ + Description: "China (Beijing)", + }, + "cn-northwest-1": region{ + Description: "China (Ningxia)", + }, + }, + Services: services{ + "api.ecr": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{ + Hostname: "api.ecr.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + "cn-northwest-1": endpoint{ + Hostname: "api.ecr.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "apigateway": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com.cn", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "application-autoscaling", + }, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "autoscaling": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "cloudformation": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "cloudfront": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-cn-global": endpoint{ + Hostname: "cloudfront.cn-northwest-1.amazonaws.com.cn", + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "cloudtrail": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "codebuild": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "codedeploy": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "cognito-identity": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "config": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "directconnect": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "dms": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "ds": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "dynamodb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "ec2": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "ec2metadata": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "169.254.169.254/latest", + Protocols: []string{"http"}, + }, + }, + }, + "ecs": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "elasticache": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "elasticbeanstalk": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "elasticloadbalancing": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "elasticmapreduce": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "es": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "events": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "firehose": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "gamelift": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "glacier": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "greengrass": service{ + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-cn-global": endpoint{ + Hostname: "iam.cn-north-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + }, + }, + "iot": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "kinesis": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "kms": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "lambda": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "license-manager": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "logs": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "mediaconvert": service{ + + Endpoints: endpoints{ + "cn-northwest-1": endpoint{ + Hostname: "subscribe.mediaconvert.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "monitoring": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "polly": service{ + + Endpoints: endpoints{ + "cn-northwest-1": endpoint{}, + }, + }, + "rds": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "redshift": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "s3": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + SignatureVersions: []string{"s3v4"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "s3-control": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{ + Hostname: "s3-control.cn-north-1.amazonaws.com.cn", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + "cn-northwest-1": endpoint{ + Hostname: "s3-control.cn-northwest-1.amazonaws.com.cn", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, + "sms": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "snowball": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "sns": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "sqs": service{ + Defaults: endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "ssm": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "states": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "storagegateway": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpoint{ + Protocols: []string{"http", "https"}, + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "sts": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "support": service{ + PartitionEndpoint: "aws-cn-global", + + Endpoints: endpoints{ + "aws-cn-global": endpoint{ + Hostname: "support.cn-north-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "cn-north-1", + }, + }, + }, + }, + "swf": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + "tagging": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + "cn-northwest-1": endpoint{}, + }, + }, + }, +} + +// AwsUsGovPartition returns the Resolver for AWS GovCloud (US). +func AwsUsGovPartition() Partition { + return awsusgovPartition.Partition() +} + +var awsusgovPartition = partition{ + ID: "aws-us-gov", + Name: "AWS GovCloud (US)", + DNSSuffix: "amazonaws.com", + RegionRegex: regionRegex{ + Regexp: func() *regexp.Regexp { + reg, _ := regexp.Compile("^us\\-gov\\-\\w+\\-\\d+$") + return reg + }(), + }, + Defaults: endpoint{ + Hostname: "{service}.{region}.{dnsSuffix}", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + Regions: regions{ + "us-gov-east-1": region{ + Description: "AWS GovCloud (US-East)", + }, + "us-gov-west-1": region{ + Description: "AWS GovCloud (US)", + }, + }, + Services: services{ + "acm": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "acm-pca": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "api.ecr": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{ + Hostname: "api.ecr.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{ + Hostname: "api.ecr.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "api.sagemaker": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "apigateway": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "application-autoscaling": service{ + Defaults: endpoint{ + Hostname: "autoscaling.{region}.amazonaws.com", + CredentialScope: credentialScope{ + Service: "application-autoscaling", + }, + }, + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "athena": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "autoscaling": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "clouddirectory": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "cloudformation": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "cloudhsm": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "cloudhsmv2": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "cloudhsm", + }, + }, + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "cloudtrail": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "codebuild": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "codecommit": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "codedeploy": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-east-1-fips": endpoint{ + Hostname: "codedeploy-fips.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "codedeploy-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "comprehend": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "config": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "datasync": service{ + + Endpoints: endpoints{ + "fips-us-gov-west-1": endpoint{ + Hostname: "datasync-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "us-gov-west-1": endpoint{}, + }, + }, + "directconnect": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "dms": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "ds": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "dynamodb": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-east-1-fips": endpoint{ + Hostname: "dynamodb.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "dynamodb.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "ec2": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "ec2metadata": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "169.254.169.254/latest", + Protocols: []string{"http"}, + }, + }, + }, + "ecs": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "elasticache": service{ + + Endpoints: endpoints{ + "fips": endpoint{ + Hostname: "elasticache-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "elasticbeanstalk": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "elasticfilesystem": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "elasticloadbalancing": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "elasticmapreduce": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{ + Protocols: []string{"https"}, + }, + }, + }, + "es": service{ + + Endpoints: endpoints{ + "fips": endpoint{ + Hostname: "es-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "events": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "firehose": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "glacier": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "glue": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "greengrass": service{ + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "guardduty": service{ + IsRegionalized: boxedTrue, + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "health": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "iam": service{ + PartitionEndpoint: "aws-us-gov-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-us-gov-global": endpoint{ + Hostname: "iam.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "inspector": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "iot": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "execute-api", + }, + }, + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "kinesis": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "kms": service{ + + Endpoints: endpoints{ + "ProdFips": endpoint{ + Hostname: "kms-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "lambda": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "license-manager": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "logs": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "mediaconvert": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "metering.marketplace": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "aws-marketplace", + }, + }, + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "monitoring": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "organizations": service{ + PartitionEndpoint: "aws-us-gov-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-us-gov-global": endpoint{ + Hostname: "organizations.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "polly": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "ram": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "rds": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "redshift": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "rekognition": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "route53": service{ + PartitionEndpoint: "aws-us-gov-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-us-gov-global": endpoint{ + Hostname: "route53.us-gov.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "runtime.sagemaker": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "s3": service{ + Defaults: endpoint{ + SignatureVersions: []string{"s3", "s3v4"}, + }, + Endpoints: endpoints{ + "fips-us-gov-west-1": endpoint{ + Hostname: "s3-fips-us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "us-gov-east-1": endpoint{ + Hostname: "s3.us-gov-east-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + "us-gov-west-1": endpoint{ + Hostname: "s3.us-gov-west-1.amazonaws.com", + Protocols: []string{"http", "https"}, + }, + }, + }, + "s3-control": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + SignatureVersions: []string{"s3v4"}, + }, + Endpoints: endpoints{ + "us-gov-east-1": endpoint{ + Hostname: "s3-control.us-gov-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-east-1-fips": endpoint{ + Hostname: "s3-control-fips.us-gov-east-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{ + Hostname: "s3-control.us-gov-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + "us-gov-west-1-fips": endpoint{ + Hostname: "s3-control-fips.us-gov-west-1.amazonaws.com", + SignatureVersions: []string{"s3v4"}, + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "secretsmanager": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "secretsmanager-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "serverlessrepo": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-gov-east-1": endpoint{ + Protocols: []string{"https"}, + }, + "us-gov-west-1": endpoint{ + Protocols: []string{"https"}, + }, + }, + }, + "sms": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "snowball": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "sns": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{ + Protocols: []string{"http", "https"}, + }, + }, + }, + "sqs": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{ + SSLCommonName: "{region}.queue.{dnsSuffix}", + Protocols: []string{"http", "https"}, + }, + }, + }, + "ssm": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "states": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "storagegateway": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "streams.dynamodb": service{ + Defaults: endpoint{ + CredentialScope: credentialScope{ + Service: "dynamodb", + }, + }, + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-east-1-fips": endpoint{ + Hostname: "dynamodb.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "dynamodb.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "sts": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "swf": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "tagging": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, + "translate": service{ + Defaults: endpoint{ + Protocols: []string{"https"}, + }, + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + "us-gov-west-1-fips": endpoint{ + Hostname: "translate-fips.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, + }, + }, + "waf-regional": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + "workspaces": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, + }, +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go new file mode 100644 index 000000000..ca8fc828e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go @@ -0,0 +1,141 @@ +package endpoints + +// Service identifiers +// +// Deprecated: Use client package's EndpointsID value instead of these +// ServiceIDs. These IDs are not maintained, and are out of date. +const ( + A4bServiceID = "a4b" // A4b. + AcmServiceID = "acm" // Acm. + AcmPcaServiceID = "acm-pca" // AcmPca. + ApiMediatailorServiceID = "api.mediatailor" // ApiMediatailor. + ApiPricingServiceID = "api.pricing" // ApiPricing. + ApiSagemakerServiceID = "api.sagemaker" // ApiSagemaker. + ApigatewayServiceID = "apigateway" // Apigateway. + ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling. + Appstream2ServiceID = "appstream2" // Appstream2. + AppsyncServiceID = "appsync" // Appsync. + AthenaServiceID = "athena" // Athena. + AutoscalingServiceID = "autoscaling" // Autoscaling. + AutoscalingPlansServiceID = "autoscaling-plans" // AutoscalingPlans. + BatchServiceID = "batch" // Batch. + BudgetsServiceID = "budgets" // Budgets. + CeServiceID = "ce" // Ce. + ChimeServiceID = "chime" // Chime. + Cloud9ServiceID = "cloud9" // Cloud9. + ClouddirectoryServiceID = "clouddirectory" // Clouddirectory. + CloudformationServiceID = "cloudformation" // Cloudformation. + CloudfrontServiceID = "cloudfront" // Cloudfront. + CloudhsmServiceID = "cloudhsm" // Cloudhsm. + Cloudhsmv2ServiceID = "cloudhsmv2" // Cloudhsmv2. + CloudsearchServiceID = "cloudsearch" // Cloudsearch. + CloudtrailServiceID = "cloudtrail" // Cloudtrail. + CodebuildServiceID = "codebuild" // Codebuild. + CodecommitServiceID = "codecommit" // Codecommit. + CodedeployServiceID = "codedeploy" // Codedeploy. + CodepipelineServiceID = "codepipeline" // Codepipeline. + CodestarServiceID = "codestar" // Codestar. + CognitoIdentityServiceID = "cognito-identity" // CognitoIdentity. + CognitoIdpServiceID = "cognito-idp" // CognitoIdp. + CognitoSyncServiceID = "cognito-sync" // CognitoSync. + ComprehendServiceID = "comprehend" // Comprehend. + ConfigServiceID = "config" // Config. + CurServiceID = "cur" // Cur. + DatapipelineServiceID = "datapipeline" // Datapipeline. + DaxServiceID = "dax" // Dax. + DevicefarmServiceID = "devicefarm" // Devicefarm. + DirectconnectServiceID = "directconnect" // Directconnect. + DiscoveryServiceID = "discovery" // Discovery. + DmsServiceID = "dms" // Dms. + DsServiceID = "ds" // Ds. + DynamodbServiceID = "dynamodb" // Dynamodb. + Ec2ServiceID = "ec2" // Ec2. + Ec2metadataServiceID = "ec2metadata" // Ec2metadata. + EcrServiceID = "ecr" // Ecr. + EcsServiceID = "ecs" // Ecs. + ElasticacheServiceID = "elasticache" // Elasticache. + ElasticbeanstalkServiceID = "elasticbeanstalk" // Elasticbeanstalk. + ElasticfilesystemServiceID = "elasticfilesystem" // Elasticfilesystem. + ElasticloadbalancingServiceID = "elasticloadbalancing" // Elasticloadbalancing. + ElasticmapreduceServiceID = "elasticmapreduce" // Elasticmapreduce. + ElastictranscoderServiceID = "elastictranscoder" // Elastictranscoder. + EmailServiceID = "email" // Email. + EntitlementMarketplaceServiceID = "entitlement.marketplace" // EntitlementMarketplace. + EsServiceID = "es" // Es. + EventsServiceID = "events" // Events. + FirehoseServiceID = "firehose" // Firehose. + FmsServiceID = "fms" // Fms. + GameliftServiceID = "gamelift" // Gamelift. + GlacierServiceID = "glacier" // Glacier. + GlueServiceID = "glue" // Glue. + GreengrassServiceID = "greengrass" // Greengrass. + GuarddutyServiceID = "guardduty" // Guardduty. + HealthServiceID = "health" // Health. + IamServiceID = "iam" // Iam. + ImportexportServiceID = "importexport" // Importexport. + InspectorServiceID = "inspector" // Inspector. + IotServiceID = "iot" // Iot. + IotanalyticsServiceID = "iotanalytics" // Iotanalytics. + KinesisServiceID = "kinesis" // Kinesis. + KinesisanalyticsServiceID = "kinesisanalytics" // Kinesisanalytics. + KinesisvideoServiceID = "kinesisvideo" // Kinesisvideo. + KmsServiceID = "kms" // Kms. + LambdaServiceID = "lambda" // Lambda. + LightsailServiceID = "lightsail" // Lightsail. + LogsServiceID = "logs" // Logs. + MachinelearningServiceID = "machinelearning" // Machinelearning. + MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics. + MediaconvertServiceID = "mediaconvert" // Mediaconvert. + MedialiveServiceID = "medialive" // Medialive. + MediapackageServiceID = "mediapackage" // Mediapackage. + MediastoreServiceID = "mediastore" // Mediastore. + MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace. + MghServiceID = "mgh" // Mgh. + MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics. + ModelsLexServiceID = "models.lex" // ModelsLex. + MonitoringServiceID = "monitoring" // Monitoring. + MturkRequesterServiceID = "mturk-requester" // MturkRequester. + NeptuneServiceID = "neptune" // Neptune. + OpsworksServiceID = "opsworks" // Opsworks. + OpsworksCmServiceID = "opsworks-cm" // OpsworksCm. + OrganizationsServiceID = "organizations" // Organizations. + PinpointServiceID = "pinpoint" // Pinpoint. + PollyServiceID = "polly" // Polly. + RdsServiceID = "rds" // Rds. + RedshiftServiceID = "redshift" // Redshift. + RekognitionServiceID = "rekognition" // Rekognition. + ResourceGroupsServiceID = "resource-groups" // ResourceGroups. + Route53ServiceID = "route53" // Route53. + Route53domainsServiceID = "route53domains" // Route53domains. + RuntimeLexServiceID = "runtime.lex" // RuntimeLex. + RuntimeSagemakerServiceID = "runtime.sagemaker" // RuntimeSagemaker. + S3ServiceID = "s3" // S3. + S3ControlServiceID = "s3-control" // S3Control. + SagemakerServiceID = "api.sagemaker" // Sagemaker. + SdbServiceID = "sdb" // Sdb. + SecretsmanagerServiceID = "secretsmanager" // Secretsmanager. + ServerlessrepoServiceID = "serverlessrepo" // Serverlessrepo. + ServicecatalogServiceID = "servicecatalog" // Servicecatalog. + ServicediscoveryServiceID = "servicediscovery" // Servicediscovery. + ShieldServiceID = "shield" // Shield. + SmsServiceID = "sms" // Sms. + SnowballServiceID = "snowball" // Snowball. + SnsServiceID = "sns" // Sns. + SqsServiceID = "sqs" // Sqs. + SsmServiceID = "ssm" // Ssm. + StatesServiceID = "states" // States. + StoragegatewayServiceID = "storagegateway" // Storagegateway. + StreamsDynamodbServiceID = "streams.dynamodb" // StreamsDynamodb. + StsServiceID = "sts" // Sts. + SupportServiceID = "support" // Support. + SwfServiceID = "swf" // Swf. + TaggingServiceID = "tagging" // Tagging. + TransferServiceID = "transfer" // Transfer. + TranslateServiceID = "translate" // Translate. + WafServiceID = "waf" // Waf. + WafRegionalServiceID = "waf-regional" // WafRegional. + WorkdocsServiceID = "workdocs" // Workdocs. + WorkmailServiceID = "workmail" // Workmail. + WorkspacesServiceID = "workspaces" // Workspaces. + XrayServiceID = "xray" // Xray. +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go new file mode 100644 index 000000000..84316b92c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go @@ -0,0 +1,66 @@ +// Package endpoints provides the types and functionality for defining regions +// and endpoints, as well as querying those definitions. +// +// The SDK's Regions and Endpoints metadata is code generated into the endpoints +// package, and is accessible via the DefaultResolver function. This function +// returns a endpoint Resolver will search the metadata and build an associated +// endpoint if one is found. The default resolver will search all partitions +// known by the SDK. e.g AWS Standard (aws), AWS China (aws-cn), and +// AWS GovCloud (US) (aws-us-gov). +// . +// +// Enumerating Regions and Endpoint Metadata +// +// Casting the Resolver returned by DefaultResolver to a EnumPartitions interface +// will allow you to get access to the list of underlying Partitions with the +// Partitions method. This is helpful if you want to limit the SDK's endpoint +// resolving to a single partition, or enumerate regions, services, and endpoints +// in the partition. +// +// resolver := endpoints.DefaultResolver() +// partitions := resolver.(endpoints.EnumPartitions).Partitions() +// +// for _, p := range partitions { +// fmt.Println("Regions for", p.ID()) +// for id, _ := range p.Regions() { +// fmt.Println("*", id) +// } +// +// fmt.Println("Services for", p.ID()) +// for id, _ := range p.Services() { +// fmt.Println("*", id) +// } +// } +// +// Using Custom Endpoints +// +// The endpoints package also gives you the ability to use your own logic how +// endpoints are resolved. This is a great way to define a custom endpoint +// for select services, without passing that logic down through your code. +// +// If a type implements the Resolver interface it can be used to resolve +// endpoints. To use this with the SDK's Session and Config set the value +// of the type to the EndpointsResolver field of aws.Config when initializing +// the session, or service client. +// +// In addition the ResolverFunc is a wrapper for a func matching the signature +// of Resolver.EndpointFor, converting it to a type that satisfies the +// Resolver interface. +// +// +// myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) { +// if service == endpoints.S3ServiceID { +// return endpoints.ResolvedEndpoint{ +// URL: "s3.custom.endpoint.com", +// SigningRegion: "custom-signing-region", +// }, nil +// } +// +// return endpoints.DefaultResolver().EndpointFor(service, region, optFns...) +// } +// +// sess := session.Must(session.NewSession(&aws.Config{ +// Region: aws.String("us-west-2"), +// EndpointResolver: endpoints.ResolverFunc(myCustomResolver), +// })) +package endpoints diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go new file mode 100644 index 000000000..9c936be6c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go @@ -0,0 +1,452 @@ +package endpoints + +import ( + "fmt" + "regexp" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// Options provide the configuration needed to direct how the +// endpoints will be resolved. +type Options struct { + // DisableSSL forces the endpoint to be resolved as HTTP. + // instead of HTTPS if the service supports it. + DisableSSL bool + + // Sets the resolver to resolve the endpoint as a dualstack endpoint + // for the service. If dualstack support for a service is not known and + // StrictMatching is not enabled a dualstack endpoint for the service will + // be returned. This endpoint may not be valid. If StrictMatching is + // enabled only services that are known to support dualstack will return + // dualstack endpoints. + UseDualStack bool + + // Enables strict matching of services and regions resolved endpoints. + // If the partition doesn't enumerate the exact service and region an + // error will be returned. This option will prevent returning endpoints + // that look valid, but may not resolve to any real endpoint. + StrictMatching bool + + // Enables resolving a service endpoint based on the region provided if the + // service does not exist. The service endpoint ID will be used as the service + // domain name prefix. By default the endpoint resolver requires the service + // to be known when resolving endpoints. + // + // If resolving an endpoint on the partition list the provided region will + // be used to determine which partition's domain name pattern to the service + // endpoint ID with. If both the service and region are unknown and resolving + // the endpoint on partition list an UnknownEndpointError error will be returned. + // + // If resolving and endpoint on a partition specific resolver that partition's + // domain name pattern will be used with the service endpoint ID. If both + // region and service do not exist when resolving an endpoint on a specific + // partition the partition's domain pattern will be used to combine the + // endpoint and region together. + // + // This option is ignored if StrictMatching is enabled. + ResolveUnknownService bool +} + +// Set combines all of the option functions together. +func (o *Options) Set(optFns ...func(*Options)) { + for _, fn := range optFns { + fn(o) + } +} + +// DisableSSLOption sets the DisableSSL options. Can be used as a functional +// option when resolving endpoints. +func DisableSSLOption(o *Options) { + o.DisableSSL = true +} + +// UseDualStackOption sets the UseDualStack option. Can be used as a functional +// option when resolving endpoints. +func UseDualStackOption(o *Options) { + o.UseDualStack = true +} + +// StrictMatchingOption sets the StrictMatching option. Can be used as a functional +// option when resolving endpoints. +func StrictMatchingOption(o *Options) { + o.StrictMatching = true +} + +// ResolveUnknownServiceOption sets the ResolveUnknownService option. Can be used +// as a functional option when resolving endpoints. +func ResolveUnknownServiceOption(o *Options) { + o.ResolveUnknownService = true +} + +// A Resolver provides the interface for functionality to resolve endpoints. +// The build in Partition and DefaultResolver return value satisfy this interface. +type Resolver interface { + EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) +} + +// ResolverFunc is a helper utility that wraps a function so it satisfies the +// Resolver interface. This is useful when you want to add additional endpoint +// resolving logic, or stub out specific endpoints with custom values. +type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) + +// EndpointFor wraps the ResolverFunc function to satisfy the Resolver interface. +func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { + return fn(service, region, opts...) +} + +var schemeRE = regexp.MustCompile("^([^:]+)://") + +// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no +// scheme. If disableSSL is true HTTP will set HTTP instead of the default HTTPS. +// +// If disableSSL is set, it will only set the URL's scheme if the URL does not +// contain a scheme. +func AddScheme(endpoint string, disableSSL bool) string { + if !schemeRE.MatchString(endpoint) { + scheme := "https" + if disableSSL { + scheme = "http" + } + endpoint = fmt.Sprintf("%s://%s", scheme, endpoint) + } + + return endpoint +} + +// EnumPartitions a provides a way to retrieve the underlying partitions that +// make up the SDK's default Resolver, or any resolver decoded from a model +// file. +// +// Use this interface with DefaultResolver and DecodeModels to get the list of +// Partitions. +type EnumPartitions interface { + Partitions() []Partition +} + +// RegionsForService returns a map of regions for the partition and service. +// If either the partition or service does not exist false will be returned +// as the second parameter. +// +// This example shows how to get the regions for DynamoDB in the AWS partition. +// rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID) +// +// This is equivalent to using the partition directly. +// rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions() +func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) { + for _, p := range ps { + if p.ID() != partitionID { + continue + } + if _, ok := p.p.Services[serviceID]; !ok { + break + } + + s := Service{ + id: serviceID, + p: p.p, + } + return s.Regions(), true + } + + return map[string]Region{}, false +} + +// PartitionForRegion returns the first partition which includes the region +// passed in. This includes both known regions and regions which match +// a pattern supported by the partition which may include regions that are +// not explicitly known by the partition. Use the Regions method of the +// returned Partition if explicit support is needed. +func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) { + for _, p := range ps { + if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) { + return p, true + } + } + + return Partition{}, false +} + +// A Partition provides the ability to enumerate the partition's regions +// and services. +type Partition struct { + id, dnsSuffix string + p *partition +} + +// DNSSuffix returns the base domain name of the partition. +func (p Partition) DNSSuffix() string { return p.dnsSuffix } + +// ID returns the identifier of the partition. +func (p Partition) ID() string { return p.id } + +// EndpointFor attempts to resolve the endpoint based on service and region. +// See Options for information on configuring how the endpoint is resolved. +// +// If the service cannot be found in the metadata the UnknownServiceError +// error will be returned. This validation will occur regardless if +// StrictMatching is enabled. To enable resolving unknown services set the +// "ResolveUnknownService" option to true. When StrictMatching is disabled +// this option allows the partition resolver to resolve a endpoint based on +// the service endpoint ID provided. +// +// When resolving endpoints you can choose to enable StrictMatching. This will +// require the provided service and region to be known by the partition. +// If the endpoint cannot be strictly resolved an error will be returned. This +// mode is useful to ensure the endpoint resolved is valid. Without +// StrictMatching enabled the endpoint returned my look valid but may not work. +// StrictMatching requires the SDK to be updated if you want to take advantage +// of new regions and services expansions. +// +// Errors that can be returned. +// * UnknownServiceError +// * UnknownEndpointError +func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { + return p.p.EndpointFor(service, region, opts...) +} + +// Regions returns a map of Regions indexed by their ID. This is useful for +// enumerating over the regions in a partition. +func (p Partition) Regions() map[string]Region { + rs := map[string]Region{} + for id, r := range p.p.Regions { + rs[id] = Region{ + id: id, + desc: r.Description, + p: p.p, + } + } + + return rs +} + +// Services returns a map of Service indexed by their ID. This is useful for +// enumerating over the services in a partition. +func (p Partition) Services() map[string]Service { + ss := map[string]Service{} + for id := range p.p.Services { + ss[id] = Service{ + id: id, + p: p.p, + } + } + + return ss +} + +// A Region provides information about a region, and ability to resolve an +// endpoint from the context of a region, given a service. +type Region struct { + id, desc string + p *partition +} + +// ID returns the region's identifier. +func (r Region) ID() string { return r.id } + +// Description returns the region's description. The region description +// is free text, it can be empty, and it may change between SDK releases. +func (r Region) Description() string { return r.desc } + +// ResolveEndpoint resolves an endpoint from the context of the region given +// a service. See Partition.EndpointFor for usage and errors that can be returned. +func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) { + return r.p.EndpointFor(service, r.id, opts...) +} + +// Services returns a list of all services that are known to be in this region. +func (r Region) Services() map[string]Service { + ss := map[string]Service{} + for id, s := range r.p.Services { + if _, ok := s.Endpoints[r.id]; ok { + ss[id] = Service{ + id: id, + p: r.p, + } + } + } + + return ss +} + +// A Service provides information about a service, and ability to resolve an +// endpoint from the context of a service, given a region. +type Service struct { + id string + p *partition +} + +// ID returns the identifier for the service. +func (s Service) ID() string { return s.id } + +// ResolveEndpoint resolves an endpoint from the context of a service given +// a region. See Partition.EndpointFor for usage and errors that can be returned. +func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) { + return s.p.EndpointFor(s.id, region, opts...) +} + +// Regions returns a map of Regions that the service is present in. +// +// A region is the AWS region the service exists in. Whereas a Endpoint is +// an URL that can be resolved to a instance of a service. +func (s Service) Regions() map[string]Region { + rs := map[string]Region{} + for id := range s.p.Services[s.id].Endpoints { + if r, ok := s.p.Regions[id]; ok { + rs[id] = Region{ + id: id, + desc: r.Description, + p: s.p, + } + } + } + + return rs +} + +// Endpoints returns a map of Endpoints indexed by their ID for all known +// endpoints for a service. +// +// A region is the AWS region the service exists in. Whereas a Endpoint is +// an URL that can be resolved to a instance of a service. +func (s Service) Endpoints() map[string]Endpoint { + es := map[string]Endpoint{} + for id := range s.p.Services[s.id].Endpoints { + es[id] = Endpoint{ + id: id, + serviceID: s.id, + p: s.p, + } + } + + return es +} + +// A Endpoint provides information about endpoints, and provides the ability +// to resolve that endpoint for the service, and the region the endpoint +// represents. +type Endpoint struct { + id string + serviceID string + p *partition +} + +// ID returns the identifier for an endpoint. +func (e Endpoint) ID() string { return e.id } + +// ServiceID returns the identifier the endpoint belongs to. +func (e Endpoint) ServiceID() string { return e.serviceID } + +// ResolveEndpoint resolves an endpoint from the context of a service and +// region the endpoint represents. See Partition.EndpointFor for usage and +// errors that can be returned. +func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) { + return e.p.EndpointFor(e.serviceID, e.id, opts...) +} + +// A ResolvedEndpoint is an endpoint that has been resolved based on a partition +// service, and region. +type ResolvedEndpoint struct { + // The endpoint URL + URL string + + // The region that should be used for signing requests. + SigningRegion string + + // The service name that should be used for signing requests. + SigningName string + + // States that the signing name for this endpoint was derived from metadata + // passed in, but was not explicitly modeled. + SigningNameDerived bool + + // The signing method that should be used for signing requests. + SigningMethod string +} + +// So that the Error interface type can be included as an anonymous field +// in the requestError struct and not conflict with the error.Error() method. +type awsError awserr.Error + +// A EndpointNotFoundError is returned when in StrictMatching mode, and the +// endpoint for the service and region cannot be found in any of the partitions. +type EndpointNotFoundError struct { + awsError + Partition string + Service string + Region string +} + +// A UnknownServiceError is returned when the service does not resolve to an +// endpoint. Includes a list of all known services for the partition. Returned +// when a partition does not support the service. +type UnknownServiceError struct { + awsError + Partition string + Service string + Known []string +} + +// NewUnknownServiceError builds and returns UnknownServiceError. +func NewUnknownServiceError(p, s string, known []string) UnknownServiceError { + return UnknownServiceError{ + awsError: awserr.New("UnknownServiceError", + "could not resolve endpoint for unknown service", nil), + Partition: p, + Service: s, + Known: known, + } +} + +// String returns the string representation of the error. +func (e UnknownServiceError) Error() string { + extra := fmt.Sprintf("partition: %q, service: %q", + e.Partition, e.Service) + if len(e.Known) > 0 { + extra += fmt.Sprintf(", known: %v", e.Known) + } + return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr()) +} + +// String returns the string representation of the error. +func (e UnknownServiceError) String() string { + return e.Error() +} + +// A UnknownEndpointError is returned when in StrictMatching mode and the +// service is valid, but the region does not resolve to an endpoint. Includes +// a list of all known endpoints for the service. +type UnknownEndpointError struct { + awsError + Partition string + Service string + Region string + Known []string +} + +// NewUnknownEndpointError builds and returns UnknownEndpointError. +func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError { + return UnknownEndpointError{ + awsError: awserr.New("UnknownEndpointError", + "could not resolve endpoint", nil), + Partition: p, + Service: s, + Region: r, + Known: known, + } +} + +// String returns the string representation of the error. +func (e UnknownEndpointError) Error() string { + extra := fmt.Sprintf("partition: %q, service: %q, region: %q", + e.Partition, e.Service, e.Region) + if len(e.Known) > 0 { + extra += fmt.Sprintf(", known: %v", e.Known) + } + return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr()) +} + +// String returns the string representation of the error. +func (e UnknownEndpointError) String() string { + return e.Error() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go new file mode 100644 index 000000000..523ad79ac --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go @@ -0,0 +1,308 @@ +package endpoints + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +type partitions []partition + +func (ps partitions) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) { + var opt Options + opt.Set(opts...) + + for i := 0; i < len(ps); i++ { + if !ps[i].canResolveEndpoint(service, region, opt.StrictMatching) { + continue + } + + return ps[i].EndpointFor(service, region, opts...) + } + + // If loose matching fallback to first partition format to use + // when resolving the endpoint. + if !opt.StrictMatching && len(ps) > 0 { + return ps[0].EndpointFor(service, region, opts...) + } + + return ResolvedEndpoint{}, NewUnknownEndpointError("all partitions", service, region, []string{}) +} + +// Partitions satisfies the EnumPartitions interface and returns a list +// of Partitions representing each partition represented in the SDK's +// endpoints model. +func (ps partitions) Partitions() []Partition { + parts := make([]Partition, 0, len(ps)) + for i := 0; i < len(ps); i++ { + parts = append(parts, ps[i].Partition()) + } + + return parts +} + +type partition struct { + ID string `json:"partition"` + Name string `json:"partitionName"` + DNSSuffix string `json:"dnsSuffix"` + RegionRegex regionRegex `json:"regionRegex"` + Defaults endpoint `json:"defaults"` + Regions regions `json:"regions"` + Services services `json:"services"` +} + +func (p partition) Partition() Partition { + return Partition{ + dnsSuffix: p.DNSSuffix, + id: p.ID, + p: &p, + } +} + +func (p partition) canResolveEndpoint(service, region string, strictMatch bool) bool { + s, hasService := p.Services[service] + _, hasEndpoint := s.Endpoints[region] + + if hasEndpoint && hasService { + return true + } + + if strictMatch { + return false + } + + return p.RegionRegex.MatchString(region) +} + +func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (resolved ResolvedEndpoint, err error) { + var opt Options + opt.Set(opts...) + + s, hasService := p.Services[service] + if !(hasService || opt.ResolveUnknownService) { + // Only return error if the resolver will not fallback to creating + // endpoint based on service endpoint ID passed in. + return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services)) + } + + e, hasEndpoint := s.endpointForRegion(region) + if !hasEndpoint && opt.StrictMatching { + return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(s.Endpoints)) + } + + defs := []endpoint{p.Defaults, s.Defaults} + return e.resolve(service, region, p.DNSSuffix, defs, opt), nil +} + +func serviceList(ss services) []string { + list := make([]string, 0, len(ss)) + for k := range ss { + list = append(list, k) + } + return list +} +func endpointList(es endpoints) []string { + list := make([]string, 0, len(es)) + for k := range es { + list = append(list, k) + } + return list +} + +type regionRegex struct { + *regexp.Regexp +} + +func (rr *regionRegex) UnmarshalJSON(b []byte) (err error) { + // Strip leading and trailing quotes + regex, err := strconv.Unquote(string(b)) + if err != nil { + return fmt.Errorf("unable to strip quotes from regex, %v", err) + } + + rr.Regexp, err = regexp.Compile(regex) + if err != nil { + return fmt.Errorf("unable to unmarshal region regex, %v", err) + } + return nil +} + +type regions map[string]region + +type region struct { + Description string `json:"description"` +} + +type services map[string]service + +type service struct { + PartitionEndpoint string `json:"partitionEndpoint"` + IsRegionalized boxedBool `json:"isRegionalized,omitempty"` + Defaults endpoint `json:"defaults"` + Endpoints endpoints `json:"endpoints"` +} + +func (s *service) endpointForRegion(region string) (endpoint, bool) { + if s.IsRegionalized == boxedFalse { + return s.Endpoints[s.PartitionEndpoint], region == s.PartitionEndpoint + } + + if e, ok := s.Endpoints[region]; ok { + return e, true + } + + // Unable to find any matching endpoint, return + // blank that will be used for generic endpoint creation. + return endpoint{}, false +} + +type endpoints map[string]endpoint + +type endpoint struct { + Hostname string `json:"hostname"` + Protocols []string `json:"protocols"` + CredentialScope credentialScope `json:"credentialScope"` + + // Custom fields not modeled + HasDualStack boxedBool `json:"-"` + DualStackHostname string `json:"-"` + + // Signature Version not used + SignatureVersions []string `json:"signatureVersions"` + + // SSLCommonName not used. + SSLCommonName string `json:"sslCommonName"` +} + +const ( + defaultProtocol = "https" + defaultSigner = "v4" +) + +var ( + protocolPriority = []string{"https", "http"} + signerPriority = []string{"v4", "v2"} +) + +func getByPriority(s []string, p []string, def string) string { + if len(s) == 0 { + return def + } + + for i := 0; i < len(p); i++ { + for j := 0; j < len(s); j++ { + if s[j] == p[i] { + return s[j] + } + } + } + + return s[0] +} + +func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint { + var merged endpoint + for _, def := range defs { + merged.mergeIn(def) + } + merged.mergeIn(e) + e = merged + + hostname := e.Hostname + + // Offset the hostname for dualstack if enabled + if opts.UseDualStack && e.HasDualStack == boxedTrue { + hostname = e.DualStackHostname + } + + u := strings.Replace(hostname, "{service}", service, 1) + u = strings.Replace(u, "{region}", region, 1) + u = strings.Replace(u, "{dnsSuffix}", dnsSuffix, 1) + + scheme := getEndpointScheme(e.Protocols, opts.DisableSSL) + u = fmt.Sprintf("%s://%s", scheme, u) + + signingRegion := e.CredentialScope.Region + if len(signingRegion) == 0 { + signingRegion = region + } + + signingName := e.CredentialScope.Service + var signingNameDerived bool + if len(signingName) == 0 { + signingName = service + signingNameDerived = true + } + + return ResolvedEndpoint{ + URL: u, + SigningRegion: signingRegion, + SigningName: signingName, + SigningNameDerived: signingNameDerived, + SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner), + } +} + +func getEndpointScheme(protocols []string, disableSSL bool) string { + if disableSSL { + return "http" + } + + return getByPriority(protocols, protocolPriority, defaultProtocol) +} + +func (e *endpoint) mergeIn(other endpoint) { + if len(other.Hostname) > 0 { + e.Hostname = other.Hostname + } + if len(other.Protocols) > 0 { + e.Protocols = other.Protocols + } + if len(other.SignatureVersions) > 0 { + e.SignatureVersions = other.SignatureVersions + } + if len(other.CredentialScope.Region) > 0 { + e.CredentialScope.Region = other.CredentialScope.Region + } + if len(other.CredentialScope.Service) > 0 { + e.CredentialScope.Service = other.CredentialScope.Service + } + if len(other.SSLCommonName) > 0 { + e.SSLCommonName = other.SSLCommonName + } + if other.HasDualStack != boxedBoolUnset { + e.HasDualStack = other.HasDualStack + } + if len(other.DualStackHostname) > 0 { + e.DualStackHostname = other.DualStackHostname + } +} + +type credentialScope struct { + Region string `json:"region"` + Service string `json:"service"` +} + +type boxedBool int + +func (b *boxedBool) UnmarshalJSON(buf []byte) error { + v, err := strconv.ParseBool(string(buf)) + if err != nil { + return err + } + + if v { + *b = boxedTrue + } else { + *b = boxedFalse + } + + return nil +} + +const ( + boxedBoolUnset boxedBool = iota + boxedFalse + boxedTrue +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go new file mode 100644 index 000000000..0fdfcc56e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go @@ -0,0 +1,351 @@ +// +build codegen + +package endpoints + +import ( + "fmt" + "io" + "reflect" + "strings" + "text/template" + "unicode" +) + +// A CodeGenOptions are the options for code generating the endpoints into +// Go code from the endpoints model definition. +type CodeGenOptions struct { + // Options for how the model will be decoded. + DecodeModelOptions DecodeModelOptions + + // Disables code generation of the service endpoint prefix IDs defined in + // the model. + DisableGenerateServiceIDs bool +} + +// Set combines all of the option functions together +func (d *CodeGenOptions) Set(optFns ...func(*CodeGenOptions)) { + for _, fn := range optFns { + fn(d) + } +} + +// CodeGenModel given a endpoints model file will decode it and attempt to +// generate Go code from the model definition. Error will be returned if +// the code is unable to be generated, or decoded. +func CodeGenModel(modelFile io.Reader, outFile io.Writer, optFns ...func(*CodeGenOptions)) error { + var opts CodeGenOptions + opts.Set(optFns...) + + resolver, err := DecodeModel(modelFile, func(d *DecodeModelOptions) { + *d = opts.DecodeModelOptions + }) + if err != nil { + return err + } + + v := struct { + Resolver + CodeGenOptions + }{ + Resolver: resolver, + CodeGenOptions: opts, + } + + tmpl := template.Must(template.New("tmpl").Funcs(funcMap).Parse(v3Tmpl)) + if err := tmpl.ExecuteTemplate(outFile, "defaults", v); err != nil { + return fmt.Errorf("failed to execute template, %v", err) + } + + return nil +} + +func toSymbol(v string) string { + out := []rune{} + for _, c := range strings.Title(v) { + if !(unicode.IsNumber(c) || unicode.IsLetter(c)) { + continue + } + + out = append(out, c) + } + + return string(out) +} + +func quoteString(v string) string { + return fmt.Sprintf("%q", v) +} + +func regionConstName(p, r string) string { + return toSymbol(p) + toSymbol(r) +} + +func partitionGetter(id string) string { + return fmt.Sprintf("%sPartition", toSymbol(id)) +} + +func partitionVarName(id string) string { + return fmt.Sprintf("%sPartition", strings.ToLower(toSymbol(id))) +} + +func listPartitionNames(ps partitions) string { + names := []string{} + switch len(ps) { + case 1: + return ps[0].Name + case 2: + return fmt.Sprintf("%s and %s", ps[0].Name, ps[1].Name) + default: + for i, p := range ps { + if i == len(ps)-1 { + names = append(names, "and "+p.Name) + } else { + names = append(names, p.Name) + } + } + return strings.Join(names, ", ") + } +} + +func boxedBoolIfSet(msg string, v boxedBool) string { + switch v { + case boxedTrue: + return fmt.Sprintf(msg, "boxedTrue") + case boxedFalse: + return fmt.Sprintf(msg, "boxedFalse") + default: + return "" + } +} + +func stringIfSet(msg, v string) string { + if len(v) == 0 { + return "" + } + + return fmt.Sprintf(msg, v) +} + +func stringSliceIfSet(msg string, vs []string) string { + if len(vs) == 0 { + return "" + } + + names := []string{} + for _, v := range vs { + names = append(names, `"`+v+`"`) + } + + return fmt.Sprintf(msg, strings.Join(names, ",")) +} + +func endpointIsSet(v endpoint) bool { + return !reflect.DeepEqual(v, endpoint{}) +} + +func serviceSet(ps partitions) map[string]struct{} { + set := map[string]struct{}{} + for _, p := range ps { + for id := range p.Services { + set[id] = struct{}{} + } + } + + return set +} + +var funcMap = template.FuncMap{ + "ToSymbol": toSymbol, + "QuoteString": quoteString, + "RegionConst": regionConstName, + "PartitionGetter": partitionGetter, + "PartitionVarName": partitionVarName, + "ListPartitionNames": listPartitionNames, + "BoxedBoolIfSet": boxedBoolIfSet, + "StringIfSet": stringIfSet, + "StringSliceIfSet": stringSliceIfSet, + "EndpointIsSet": endpointIsSet, + "ServicesSet": serviceSet, +} + +const v3Tmpl = ` +{{ define "defaults" -}} +// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT. + +package endpoints + +import ( + "regexp" +) + + {{ template "partition consts" $.Resolver }} + + {{ range $_, $partition := $.Resolver }} + {{ template "partition region consts" $partition }} + {{ end }} + + {{ if not $.DisableGenerateServiceIDs -}} + {{ template "service consts" $.Resolver }} + {{- end }} + + {{ template "endpoint resolvers" $.Resolver }} +{{- end }} + +{{ define "partition consts" }} + // Partition identifiers + const ( + {{ range $_, $p := . -}} + {{ ToSymbol $p.ID }}PartitionID = {{ QuoteString $p.ID }} // {{ $p.Name }} partition. + {{ end -}} + ) +{{- end }} + +{{ define "partition region consts" }} + // {{ .Name }} partition's regions. + const ( + {{ range $id, $region := .Regions -}} + {{ ToSymbol $id }}RegionID = {{ QuoteString $id }} // {{ $region.Description }}. + {{ end -}} + ) +{{- end }} + +{{ define "service consts" }} + // Service identifiers + const ( + {{ $serviceSet := ServicesSet . -}} + {{ range $id, $_ := $serviceSet -}} + {{ ToSymbol $id }}ServiceID = {{ QuoteString $id }} // {{ ToSymbol $id }}. + {{ end -}} + ) +{{- end }} + +{{ define "endpoint resolvers" }} + // DefaultResolver returns an Endpoint resolver that will be able + // to resolve endpoints for: {{ ListPartitionNames . }}. + // + // Use DefaultPartitions() to get the list of the default partitions. + func DefaultResolver() Resolver { + return defaultPartitions + } + + // DefaultPartitions returns a list of the partitions the SDK is bundled + // with. The available partitions are: {{ ListPartitionNames . }}. + // + // partitions := endpoints.DefaultPartitions + // for _, p := range partitions { + // // ... inspect partitions + // } + func DefaultPartitions() []Partition { + return defaultPartitions.Partitions() + } + + var defaultPartitions = partitions{ + {{ range $_, $partition := . -}} + {{ PartitionVarName $partition.ID }}, + {{ end }} + } + + {{ range $_, $partition := . -}} + {{ $name := PartitionGetter $partition.ID -}} + // {{ $name }} returns the Resolver for {{ $partition.Name }}. + func {{ $name }}() Partition { + return {{ PartitionVarName $partition.ID }}.Partition() + } + var {{ PartitionVarName $partition.ID }} = {{ template "gocode Partition" $partition }} + {{ end }} +{{ end }} + +{{ define "default partitions" }} + func DefaultPartitions() []Partition { + return []partition{ + {{ range $_, $partition := . -}} + // {{ ToSymbol $partition.ID}}Partition(), + {{ end }} + } + } +{{ end }} + +{{ define "gocode Partition" -}} +partition{ + {{ StringIfSet "ID: %q,\n" .ID -}} + {{ StringIfSet "Name: %q,\n" .Name -}} + {{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}} + RegionRegex: {{ template "gocode RegionRegex" .RegionRegex }}, + {{ if EndpointIsSet .Defaults -}} + Defaults: {{ template "gocode Endpoint" .Defaults }}, + {{- end }} + Regions: {{ template "gocode Regions" .Regions }}, + Services: {{ template "gocode Services" .Services }}, +} +{{- end }} + +{{ define "gocode RegionRegex" -}} +regionRegex{ + Regexp: func() *regexp.Regexp{ + reg, _ := regexp.Compile({{ QuoteString .Regexp.String }}) + return reg + }(), +} +{{- end }} + +{{ define "gocode Regions" -}} +regions{ + {{ range $id, $region := . -}} + "{{ $id }}": {{ template "gocode Region" $region }}, + {{ end -}} +} +{{- end }} + +{{ define "gocode Region" -}} +region{ + {{ StringIfSet "Description: %q,\n" .Description -}} +} +{{- end }} + +{{ define "gocode Services" -}} +services{ + {{ range $id, $service := . -}} + "{{ $id }}": {{ template "gocode Service" $service }}, + {{ end }} +} +{{- end }} + +{{ define "gocode Service" -}} +service{ + {{ StringIfSet "PartitionEndpoint: %q,\n" .PartitionEndpoint -}} + {{ BoxedBoolIfSet "IsRegionalized: %s,\n" .IsRegionalized -}} + {{ if EndpointIsSet .Defaults -}} + Defaults: {{ template "gocode Endpoint" .Defaults -}}, + {{- end }} + {{ if .Endpoints -}} + Endpoints: {{ template "gocode Endpoints" .Endpoints }}, + {{- end }} +} +{{- end }} + +{{ define "gocode Endpoints" -}} +endpoints{ + {{ range $id, $endpoint := . -}} + "{{ $id }}": {{ template "gocode Endpoint" $endpoint }}, + {{ end }} +} +{{- end }} + +{{ define "gocode Endpoint" -}} +endpoint{ + {{ StringIfSet "Hostname: %q,\n" .Hostname -}} + {{ StringIfSet "SSLCommonName: %q,\n" .SSLCommonName -}} + {{ StringSliceIfSet "Protocols: []string{%s},\n" .Protocols -}} + {{ StringSliceIfSet "SignatureVersions: []string{%s},\n" .SignatureVersions -}} + {{ if or .CredentialScope.Region .CredentialScope.Service -}} + CredentialScope: credentialScope{ + {{ StringIfSet "Region: %q,\n" .CredentialScope.Region -}} + {{ StringIfSet "Service: %q,\n" .CredentialScope.Service -}} + }, + {{- end }} + {{ BoxedBoolIfSet "HasDualStack: %s,\n" .HasDualStack -}} + {{ StringIfSet "DualStackHostname: %q,\n" .DualStackHostname -}} + +} +{{- end }} +` diff --git a/vendor/github.com/aws/aws-sdk-go/aws/errors.go b/vendor/github.com/aws/aws-sdk-go/aws/errors.go new file mode 100644 index 000000000..fa06f7a8f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/errors.go @@ -0,0 +1,13 @@ +package aws + +import "github.com/aws/aws-sdk-go/aws/awserr" + +var ( + // ErrMissingRegion is an error that is returned if region configuration is + // not found. + ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil) + + // ErrMissingEndpoint is an error that is returned if an endpoint cannot be + // resolved for a service. + ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil) +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go new file mode 100644 index 000000000..91a6f277a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go @@ -0,0 +1,12 @@ +package aws + +// JSONValue is a representation of a grab bag type that will be marshaled +// into a json string. This type can be used just like any other map. +// +// Example: +// +// values := aws.JSONValue{ +// "Foo": "Bar", +// } +// values["Baz"] = "Qux" +type JSONValue map[string]interface{} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/logger.go b/vendor/github.com/aws/aws-sdk-go/aws/logger.go new file mode 100644 index 000000000..6ed15b2ec --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/logger.go @@ -0,0 +1,118 @@ +package aws + +import ( + "log" + "os" +) + +// A LogLevelType defines the level logging should be performed at. Used to instruct +// the SDK which statements should be logged. +type LogLevelType uint + +// LogLevel returns the pointer to a LogLevel. Should be used to workaround +// not being able to take the address of a non-composite literal. +func LogLevel(l LogLevelType) *LogLevelType { + return &l +} + +// Value returns the LogLevel value or the default value LogOff if the LogLevel +// is nil. Safe to use on nil value LogLevelTypes. +func (l *LogLevelType) Value() LogLevelType { + if l != nil { + return *l + } + return LogOff +} + +// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be +// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If +// LogLevel is nil, will default to LogOff comparison. +func (l *LogLevelType) Matches(v LogLevelType) bool { + c := l.Value() + return c&v == v +} + +// AtLeast returns true if this LogLevel is at least high enough to satisfies v. +// Is safe to use on nil value LogLevelTypes. If LogLevel is nil, will default +// to LogOff comparison. +func (l *LogLevelType) AtLeast(v LogLevelType) bool { + c := l.Value() + return c >= v +} + +const ( + // LogOff states that no logging should be performed by the SDK. This is the + // default state of the SDK, and should be use to disable all logging. + LogOff LogLevelType = iota * 0x1000 + + // LogDebug state that debug output should be logged by the SDK. This should + // be used to inspect request made and responses received. + LogDebug +) + +// Debug Logging Sub Levels +const ( + // LogDebugWithSigning states that the SDK should log request signing and + // presigning events. This should be used to log the signing details of + // requests for debugging. Will also enable LogDebug. + LogDebugWithSigning LogLevelType = LogDebug | (1 << iota) + + // LogDebugWithHTTPBody states the SDK should log HTTP request and response + // HTTP bodys in addition to the headers and path. This should be used to + // see the body content of requests and responses made while using the SDK + // Will also enable LogDebug. + LogDebugWithHTTPBody + + // LogDebugWithRequestRetries states the SDK should log when service requests will + // be retried. This should be used to log when you want to log when service + // requests are being retried. Will also enable LogDebug. + LogDebugWithRequestRetries + + // LogDebugWithRequestErrors states the SDK should log when service requests fail + // to build, send, validate, or unmarshal. + LogDebugWithRequestErrors + + // LogDebugWithEventStreamBody states the SDK should log EventStream + // request and response bodys. This should be used to log the EventStream + // wire unmarshaled message content of requests and responses made while + // using the SDK Will also enable LogDebug. + LogDebugWithEventStreamBody +) + +// A Logger is a minimalistic interface for the SDK to log messages to. Should +// be used to provide custom logging writers for the SDK to use. +type Logger interface { + Log(...interface{}) +} + +// A LoggerFunc is a convenience type to convert a function taking a variadic +// list of arguments and wrap it so the Logger interface can be used. +// +// Example: +// s3.New(sess, &aws.Config{Logger: aws.LoggerFunc(func(args ...interface{}) { +// fmt.Fprintln(os.Stdout, args...) +// })}) +type LoggerFunc func(...interface{}) + +// Log calls the wrapped function with the arguments provided +func (f LoggerFunc) Log(args ...interface{}) { + f(args...) +} + +// NewDefaultLogger returns a Logger which will write log messages to stdout, and +// use same formatting runes as the stdlib log.Logger +func NewDefaultLogger() Logger { + return &defaultLogger{ + logger: log.New(os.Stdout, "", log.LstdFlags), + } +} + +// A defaultLogger provides a minimalistic logger satisfying the Logger interface. +type defaultLogger struct { + logger *log.Logger +} + +// Log logs the parameters to the stdlib logger. See log.Println. +func (l defaultLogger) Log(args ...interface{}) { + l.logger.Println(args...) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go new file mode 100644 index 000000000..d9b37f4d3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go @@ -0,0 +1,18 @@ +package request + +import ( + "strings" +) + +func isErrConnectionReset(err error) bool { + if strings.Contains(err.Error(), "read: connection reset") { + return false + } + + if strings.Contains(err.Error(), "connection reset") || + strings.Contains(err.Error(), "broken pipe") { + return true + } + + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go new file mode 100644 index 000000000..627ec722c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go @@ -0,0 +1,322 @@ +package request + +import ( + "fmt" + "strings" +) + +// A Handlers provides a collection of request handlers for various +// stages of handling requests. +type Handlers struct { + Validate HandlerList + Build HandlerList + Sign HandlerList + Send HandlerList + ValidateResponse HandlerList + Unmarshal HandlerList + UnmarshalStream HandlerList + UnmarshalMeta HandlerList + UnmarshalError HandlerList + Retry HandlerList + AfterRetry HandlerList + CompleteAttempt HandlerList + Complete HandlerList +} + +// Copy returns of this handler's lists. +func (h *Handlers) Copy() Handlers { + return Handlers{ + Validate: h.Validate.copy(), + Build: h.Build.copy(), + Sign: h.Sign.copy(), + Send: h.Send.copy(), + ValidateResponse: h.ValidateResponse.copy(), + Unmarshal: h.Unmarshal.copy(), + UnmarshalStream: h.UnmarshalStream.copy(), + UnmarshalError: h.UnmarshalError.copy(), + UnmarshalMeta: h.UnmarshalMeta.copy(), + Retry: h.Retry.copy(), + AfterRetry: h.AfterRetry.copy(), + CompleteAttempt: h.CompleteAttempt.copy(), + Complete: h.Complete.copy(), + } +} + +// Clear removes callback functions for all handlers +func (h *Handlers) Clear() { + h.Validate.Clear() + h.Build.Clear() + h.Send.Clear() + h.Sign.Clear() + h.Unmarshal.Clear() + h.UnmarshalStream.Clear() + h.UnmarshalMeta.Clear() + h.UnmarshalError.Clear() + h.ValidateResponse.Clear() + h.Retry.Clear() + h.AfterRetry.Clear() + h.CompleteAttempt.Clear() + h.Complete.Clear() +} + +// IsEmpty returns if there are no handlers in any of the handlerlists. +func (h *Handlers) IsEmpty() bool { + if h.Validate.Len() != 0 { + return false + } + if h.Build.Len() != 0 { + return false + } + if h.Send.Len() != 0 { + return false + } + if h.Sign.Len() != 0 { + return false + } + if h.Unmarshal.Len() != 0 { + return false + } + if h.UnmarshalStream.Len() != 0 { + return false + } + if h.UnmarshalMeta.Len() != 0 { + return false + } + if h.UnmarshalError.Len() != 0 { + return false + } + if h.ValidateResponse.Len() != 0 { + return false + } + if h.Retry.Len() != 0 { + return false + } + if h.AfterRetry.Len() != 0 { + return false + } + if h.CompleteAttempt.Len() != 0 { + return false + } + if h.Complete.Len() != 0 { + return false + } + + return true +} + +// A HandlerListRunItem represents an entry in the HandlerList which +// is being run. +type HandlerListRunItem struct { + Index int + Handler NamedHandler + Request *Request +} + +// A HandlerList manages zero or more handlers in a list. +type HandlerList struct { + list []NamedHandler + + // Called after each request handler in the list is called. If set + // and the func returns true the HandlerList will continue to iterate + // over the request handlers. If false is returned the HandlerList + // will stop iterating. + // + // Should be used if extra logic to be performed between each handler + // in the list. This can be used to terminate a list's iteration + // based on a condition such as error like, HandlerListStopOnError. + // Or for logging like HandlerListLogItem. + AfterEachFn func(item HandlerListRunItem) bool +} + +// A NamedHandler is a struct that contains a name and function callback. +type NamedHandler struct { + Name string + Fn func(*Request) +} + +// copy creates a copy of the handler list. +func (l *HandlerList) copy() HandlerList { + n := HandlerList{ + AfterEachFn: l.AfterEachFn, + } + if len(l.list) == 0 { + return n + } + + n.list = append(make([]NamedHandler, 0, len(l.list)), l.list...) + return n +} + +// Clear clears the handler list. +func (l *HandlerList) Clear() { + l.list = l.list[0:0] +} + +// Len returns the number of handlers in the list. +func (l *HandlerList) Len() int { + return len(l.list) +} + +// PushBack pushes handler f to the back of the handler list. +func (l *HandlerList) PushBack(f func(*Request)) { + l.PushBackNamed(NamedHandler{"__anonymous", f}) +} + +// PushBackNamed pushes named handler f to the back of the handler list. +func (l *HandlerList) PushBackNamed(n NamedHandler) { + if cap(l.list) == 0 { + l.list = make([]NamedHandler, 0, 5) + } + l.list = append(l.list, n) +} + +// PushFront pushes handler f to the front of the handler list. +func (l *HandlerList) PushFront(f func(*Request)) { + l.PushFrontNamed(NamedHandler{"__anonymous", f}) +} + +// PushFrontNamed pushes named handler f to the front of the handler list. +func (l *HandlerList) PushFrontNamed(n NamedHandler) { + if cap(l.list) == len(l.list) { + // Allocating new list required + l.list = append([]NamedHandler{n}, l.list...) + } else { + // Enough room to prepend into list. + l.list = append(l.list, NamedHandler{}) + copy(l.list[1:], l.list) + l.list[0] = n + } +} + +// Remove removes a NamedHandler n +func (l *HandlerList) Remove(n NamedHandler) { + l.RemoveByName(n.Name) +} + +// RemoveByName removes a NamedHandler by name. +func (l *HandlerList) RemoveByName(name string) { + for i := 0; i < len(l.list); i++ { + m := l.list[i] + if m.Name == name { + // Shift array preventing creating new arrays + copy(l.list[i:], l.list[i+1:]) + l.list[len(l.list)-1] = NamedHandler{} + l.list = l.list[:len(l.list)-1] + + // decrement list so next check to length is correct + i-- + } + } +} + +// SwapNamed will swap out any existing handlers with the same name as the +// passed in NamedHandler returning true if handlers were swapped. False is +// returned otherwise. +func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) { + for i := 0; i < len(l.list); i++ { + if l.list[i].Name == n.Name { + l.list[i].Fn = n.Fn + swapped = true + } + } + + return swapped +} + +// Swap will swap out all handlers matching the name passed in. The matched +// handlers will be swapped in. True is returned if the handlers were swapped. +func (l *HandlerList) Swap(name string, replace NamedHandler) bool { + var swapped bool + + for i := 0; i < len(l.list); i++ { + if l.list[i].Name == name { + l.list[i] = replace + swapped = true + } + } + + return swapped +} + +// SetBackNamed will replace the named handler if it exists in the handler list. +// If the handler does not exist the handler will be added to the end of the list. +func (l *HandlerList) SetBackNamed(n NamedHandler) { + if !l.SwapNamed(n) { + l.PushBackNamed(n) + } +} + +// SetFrontNamed will replace the named handler if it exists in the handler list. +// If the handler does not exist the handler will be added to the beginning of +// the list. +func (l *HandlerList) SetFrontNamed(n NamedHandler) { + if !l.SwapNamed(n) { + l.PushFrontNamed(n) + } +} + +// Run executes all handlers in the list with a given request object. +func (l *HandlerList) Run(r *Request) { + for i, h := range l.list { + h.Fn(r) + item := HandlerListRunItem{ + Index: i, Handler: h, Request: r, + } + if l.AfterEachFn != nil && !l.AfterEachFn(item) { + return + } + } +} + +// HandlerListLogItem logs the request handler and the state of the +// request's Error value. Always returns true to continue iterating +// request handlers in a HandlerList. +func HandlerListLogItem(item HandlerListRunItem) bool { + if item.Request.Config.Logger == nil { + return true + } + item.Request.Config.Logger.Log("DEBUG: RequestHandler", + item.Index, item.Handler.Name, item.Request.Error) + + return true +} + +// HandlerListStopOnError returns false to stop the HandlerList iterating +// over request handlers if Request.Error is not nil. True otherwise +// to continue iterating. +func HandlerListStopOnError(item HandlerListRunItem) bool { + return item.Request.Error == nil +} + +// WithAppendUserAgent will add a string to the user agent prefixed with a +// single white space. +func WithAppendUserAgent(s string) Option { + return func(r *Request) { + r.Handlers.Build.PushBack(func(r2 *Request) { + AddToUserAgent(r, s) + }) + } +} + +// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request +// header. If the extra parameters are provided they will be added as metadata to the +// name/version pair resulting in the following format. +// "name/version (extra0; extra1; ...)" +// The user agent part will be concatenated with this current request's user agent string. +func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) { + ua := fmt.Sprintf("%s/%s", name, version) + if len(extra) > 0 { + ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; ")) + } + return func(r *Request) { + AddToUserAgent(r, ua) + } +} + +// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header. +// The input string will be concatenated with the current request's user agent string. +func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) { + return func(r *Request) { + AddToUserAgent(r, s) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go new file mode 100644 index 000000000..79f79602b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go @@ -0,0 +1,24 @@ +package request + +import ( + "io" + "net/http" + "net/url" +) + +func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request { + req := new(http.Request) + *req = *r + req.URL = &url.URL{} + *req.URL = *r.URL + req.Body = body + + req.Header = http.Header{} + for k, v := range r.Header { + for _, vv := range v { + req.Header.Add(k, vv) + } + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go new file mode 100644 index 000000000..9370fa50c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go @@ -0,0 +1,65 @@ +package request + +import ( + "io" + "sync" + + "github.com/aws/aws-sdk-go/internal/sdkio" +) + +// offsetReader is a thread-safe io.ReadCloser to prevent racing +// with retrying requests +type offsetReader struct { + buf io.ReadSeeker + lock sync.Mutex + closed bool +} + +func newOffsetReader(buf io.ReadSeeker, offset int64) (*offsetReader, error) { + reader := &offsetReader{} + _, err := buf.Seek(offset, sdkio.SeekStart) + if err != nil { + return nil, err + } + + reader.buf = buf + return reader, nil +} + +// Close will close the instance of the offset reader's access to +// the underlying io.ReadSeeker. +func (o *offsetReader) Close() error { + o.lock.Lock() + defer o.lock.Unlock() + o.closed = true + return nil +} + +// Read is a thread-safe read of the underlying io.ReadSeeker +func (o *offsetReader) Read(p []byte) (int, error) { + o.lock.Lock() + defer o.lock.Unlock() + + if o.closed { + return 0, io.EOF + } + + return o.buf.Read(p) +} + +// Seek is a thread-safe seeking operation. +func (o *offsetReader) Seek(offset int64, whence int) (int64, error) { + o.lock.Lock() + defer o.lock.Unlock() + + return o.buf.Seek(offset, whence) +} + +// CloseAndCopy will return a new offsetReader with a copy of the old buffer +// and close the old buffer. +func (o *offsetReader) CloseAndCopy(offset int64) (*offsetReader, error) { + if err := o.Close(); err != nil { + return nil, err + } + return newOffsetReader(o.buf, offset) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go new file mode 100644 index 000000000..8e332cce6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go @@ -0,0 +1,670 @@ +package request + +import ( + "bytes" + "fmt" + "io" + "net/http" + "net/url" + "reflect" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/internal/sdkio" +) + +const ( + // ErrCodeSerialization is the serialization error code that is received + // during protocol unmarshaling. + ErrCodeSerialization = "SerializationError" + + // ErrCodeRead is an error that is returned during HTTP reads. + ErrCodeRead = "ReadError" + + // ErrCodeResponseTimeout is the connection timeout error that is received + // during body reads. + ErrCodeResponseTimeout = "ResponseTimeout" + + // ErrCodeInvalidPresignExpire is returned when the expire time provided to + // presign is invalid + ErrCodeInvalidPresignExpire = "InvalidPresignExpireError" + + // CanceledErrorCode is the error code that will be returned by an + // API request that was canceled. Requests given a aws.Context may + // return this error when canceled. + CanceledErrorCode = "RequestCanceled" +) + +// A Request is the service request to be made. +type Request struct { + Config aws.Config + ClientInfo metadata.ClientInfo + Handlers Handlers + + Retryer + AttemptTime time.Time + Time time.Time + Operation *Operation + HTTPRequest *http.Request + HTTPResponse *http.Response + Body io.ReadSeeker + BodyStart int64 // offset from beginning of Body that the request body starts + Params interface{} + Error error + Data interface{} + RequestID string + RetryCount int + Retryable *bool + RetryDelay time.Duration + NotHoist bool + SignedHeaderVals http.Header + LastSignedAt time.Time + DisableFollowRedirects bool + + // Additional API error codes that should be retried. IsErrorRetryable + // will consider these codes in addition to its built in cases. + RetryErrorCodes []string + + // Additional API error codes that should be retried with throttle backoff + // delay. IsErrorThrottle will consider these codes in addition to its + // built in cases. + ThrottleErrorCodes []string + + // A value greater than 0 instructs the request to be signed as Presigned URL + // You should not set this field directly. Instead use Request's + // Presign or PresignRequest methods. + ExpireTime time.Duration + + context aws.Context + + built bool + + // Need to persist an intermediate body between the input Body and HTTP + // request body because the HTTP Client's transport can maintain a reference + // to the HTTP request's body after the client has returned. This value is + // safe to use concurrently and wrap the input Body for each HTTP request. + safeBody *offsetReader +} + +// An Operation is the service API operation to be made. +type Operation struct { + Name string + HTTPMethod string + HTTPPath string + *Paginator + + BeforePresignFn func(r *Request) error +} + +// New returns a new Request pointer for the service API +// operation and parameters. +// +// Params is any value of input parameters to be the request payload. +// Data is pointer value to an object which the request's response +// payload will be deserialized to. +func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers, + retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request { + + method := operation.HTTPMethod + if method == "" { + method = "POST" + } + + httpReq, _ := http.NewRequest(method, "", nil) + + var err error + httpReq.URL, err = url.Parse(clientInfo.Endpoint + operation.HTTPPath) + if err != nil { + httpReq.URL = &url.URL{} + err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err) + } + + SanitizeHostForHeader(httpReq) + + r := &Request{ + Config: cfg, + ClientInfo: clientInfo, + Handlers: handlers.Copy(), + + Retryer: retryer, + Time: time.Now(), + ExpireTime: 0, + Operation: operation, + HTTPRequest: httpReq, + Body: nil, + Params: params, + Error: err, + Data: data, + } + r.SetBufferBody([]byte{}) + + return r +} + +// A Option is a functional option that can augment or modify a request when +// using a WithContext API operation method. +type Option func(*Request) + +// WithGetResponseHeader builds a request Option which will retrieve a single +// header value from the HTTP Response. If there are multiple values for the +// header key use WithGetResponseHeaders instead to access the http.Header +// map directly. The passed in val pointer must be non-nil. +// +// This Option can be used multiple times with a single API operation. +// +// var id2, versionID string +// svc.PutObjectWithContext(ctx, params, +// request.WithGetResponseHeader("x-amz-id-2", &id2), +// request.WithGetResponseHeader("x-amz-version-id", &versionID), +// ) +func WithGetResponseHeader(key string, val *string) Option { + return func(r *Request) { + r.Handlers.Complete.PushBack(func(req *Request) { + *val = req.HTTPResponse.Header.Get(key) + }) + } +} + +// WithGetResponseHeaders builds a request Option which will retrieve the +// headers from the HTTP response and assign them to the passed in headers +// variable. The passed in headers pointer must be non-nil. +// +// var headers http.Header +// svc.PutObjectWithContext(ctx, params, request.WithGetResponseHeaders(&headers)) +func WithGetResponseHeaders(headers *http.Header) Option { + return func(r *Request) { + r.Handlers.Complete.PushBack(func(req *Request) { + *headers = req.HTTPResponse.Header + }) + } +} + +// WithLogLevel is a request option that will set the request to use a specific +// log level when the request is made. +// +// svc.PutObjectWithContext(ctx, params, request.WithLogLevel(aws.LogDebugWithHTTPBody) +func WithLogLevel(l aws.LogLevelType) Option { + return func(r *Request) { + r.Config.LogLevel = aws.LogLevel(l) + } +} + +// ApplyOptions will apply each option to the request calling them in the order +// the were provided. +func (r *Request) ApplyOptions(opts ...Option) { + for _, opt := range opts { + opt(r) + } +} + +// Context will always returns a non-nil context. If Request does not have a +// context aws.BackgroundContext will be returned. +func (r *Request) Context() aws.Context { + if r.context != nil { + return r.context + } + return aws.BackgroundContext() +} + +// SetContext adds a Context to the current request that can be used to cancel +// a in-flight request. The Context value must not be nil, or this method will +// panic. +// +// Unlike http.Request.WithContext, SetContext does not return a copy of the +// Request. It is not safe to use use a single Request value for multiple +// requests. A new Request should be created for each API operation request. +// +// Go 1.6 and below: +// The http.Request's Cancel field will be set to the Done() value of +// the context. This will overwrite the Cancel field's value. +// +// Go 1.7 and above: +// The http.Request.WithContext will be used to set the context on the underlying +// http.Request. This will create a shallow copy of the http.Request. The SDK +// may create sub contexts in the future for nested requests such as retries. +func (r *Request) SetContext(ctx aws.Context) { + if ctx == nil { + panic("context cannot be nil") + } + setRequestContext(r, ctx) +} + +// WillRetry returns if the request's can be retried. +func (r *Request) WillRetry() bool { + if !aws.IsReaderSeekable(r.Body) && r.HTTPRequest.Body != NoBody { + return false + } + return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries() +} + +func fmtAttemptCount(retryCount, maxRetries int) string { + return fmt.Sprintf("attempt %v/%v", retryCount, maxRetries) +} + +// ParamsFilled returns if the request's parameters have been populated +// and the parameters are valid. False is returned if no parameters are +// provided or invalid. +func (r *Request) ParamsFilled() bool { + return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid() +} + +// DataFilled returns true if the request's data for response deserialization +// target has been set and is a valid. False is returned if data is not +// set, or is invalid. +func (r *Request) DataFilled() bool { + return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid() +} + +// SetBufferBody will set the request's body bytes that will be sent to +// the service API. +func (r *Request) SetBufferBody(buf []byte) { + r.SetReaderBody(bytes.NewReader(buf)) +} + +// SetStringBody sets the body of the request to be backed by a string. +func (r *Request) SetStringBody(s string) { + r.SetReaderBody(strings.NewReader(s)) +} + +// SetReaderBody will set the request's body reader. +func (r *Request) SetReaderBody(reader io.ReadSeeker) { + r.Body = reader + + if aws.IsReaderSeekable(reader) { + var err error + // Get the Bodies current offset so retries will start from the same + // initial position. + r.BodyStart, err = reader.Seek(0, sdkio.SeekCurrent) + if err != nil { + r.Error = awserr.New(ErrCodeSerialization, + "failed to determine start of request body", err) + return + } + } + r.ResetBody() +} + +// Presign returns the request's signed URL. Error will be returned +// if the signing fails. The expire parameter is only used for presigned Amazon +// S3 API requests. All other AWS services will use a fixed expiration +// time of 15 minutes. +// +// It is invalid to create a presigned URL with a expire duration 0 or less. An +// error is returned if expire duration is 0 or less. +func (r *Request) Presign(expire time.Duration) (string, error) { + r = r.copy() + + // Presign requires all headers be hoisted. There is no way to retrieve + // the signed headers not hoisted without this. Making the presigned URL + // useless. + r.NotHoist = false + + u, _, err := getPresignedURL(r, expire) + return u, err +} + +// PresignRequest behaves just like presign, with the addition of returning a +// set of headers that were signed. The expire parameter is only used for +// presigned Amazon S3 API requests. All other AWS services will use a fixed +// expiration time of 15 minutes. +// +// It is invalid to create a presigned URL with a expire duration 0 or less. An +// error is returned if expire duration is 0 or less. +// +// Returns the URL string for the API operation with signature in the query string, +// and the HTTP headers that were included in the signature. These headers must +// be included in any HTTP request made with the presigned URL. +// +// To prevent hoisting any headers to the query string set NotHoist to true on +// this Request value prior to calling PresignRequest. +func (r *Request) PresignRequest(expire time.Duration) (string, http.Header, error) { + r = r.copy() + return getPresignedURL(r, expire) +} + +// IsPresigned returns true if the request represents a presigned API url. +func (r *Request) IsPresigned() bool { + return r.ExpireTime != 0 +} + +func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, error) { + if expire <= 0 { + return "", nil, awserr.New( + ErrCodeInvalidPresignExpire, + "presigned URL requires an expire duration greater than 0", + nil, + ) + } + + r.ExpireTime = expire + + if r.Operation.BeforePresignFn != nil { + if err := r.Operation.BeforePresignFn(r); err != nil { + return "", nil, err + } + } + + if err := r.Sign(); err != nil { + return "", nil, err + } + + return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil +} + +const ( + notRetrying = "not retrying" +) + +func debugLogReqError(r *Request, stage, retryStr string, err error) { + if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) { + return + } + + r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v", + stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err)) +} + +// Build will build the request's object so it can be signed and sent +// to the service. Build will also validate all the request's parameters. +// Any additional build Handlers set on this request will be run +// in the order they were set. +// +// The request will only be built once. Multiple calls to build will have +// no effect. +// +// If any Validate or Build errors occur the build will stop and the error +// which occurred will be returned. +func (r *Request) Build() error { + if !r.built { + r.Handlers.Validate.Run(r) + if r.Error != nil { + debugLogReqError(r, "Validate Request", notRetrying, r.Error) + return r.Error + } + r.Handlers.Build.Run(r) + if r.Error != nil { + debugLogReqError(r, "Build Request", notRetrying, r.Error) + return r.Error + } + r.built = true + } + + return r.Error +} + +// Sign will sign the request, returning error if errors are encountered. +// +// Sign will build the request prior to signing. All Sign Handlers will +// be executed in the order they were set. +func (r *Request) Sign() error { + r.Build() + if r.Error != nil { + debugLogReqError(r, "Build Request", notRetrying, r.Error) + return r.Error + } + + r.Handlers.Sign.Run(r) + return r.Error +} + +func (r *Request) getNextRequestBody() (body io.ReadCloser, err error) { + if r.safeBody != nil { + r.safeBody.Close() + } + + r.safeBody, err = newOffsetReader(r.Body, r.BodyStart) + if err != nil { + return nil, awserr.New(ErrCodeSerialization, + "failed to get next request body reader", err) + } + + // Go 1.8 tightened and clarified the rules code needs to use when building + // requests with the http package. Go 1.8 removed the automatic detection + // of if the Request.Body was empty, or actually had bytes in it. The SDK + // always sets the Request.Body even if it is empty and should not actually + // be sent. This is incorrect. + // + // Go 1.8 did add a http.NoBody value that the SDK can use to tell the http + // client that the request really should be sent without a body. The + // Request.Body cannot be set to nil, which is preferable, because the + // field is exported and could introduce nil pointer dereferences for users + // of the SDK if they used that field. + // + // Related golang/go#18257 + l, err := aws.SeekerLen(r.Body) + if err != nil { + return nil, awserr.New(ErrCodeSerialization, + "failed to compute request body size", err) + } + + if l == 0 { + body = NoBody + } else if l > 0 { + body = r.safeBody + } else { + // Hack to prevent sending bodies for methods where the body + // should be ignored by the server. Sending bodies on these + // methods without an associated ContentLength will cause the + // request to socket timeout because the server does not handle + // Transfer-Encoding: chunked bodies for these methods. + // + // This would only happen if a aws.ReaderSeekerCloser was used with + // a io.Reader that was not also an io.Seeker, or did not implement + // Len() method. + switch r.Operation.HTTPMethod { + case "GET", "HEAD", "DELETE": + body = NoBody + default: + body = r.safeBody + } + } + + return body, nil +} + +// GetBody will return an io.ReadSeeker of the Request's underlying +// input body with a concurrency safe wrapper. +func (r *Request) GetBody() io.ReadSeeker { + return r.safeBody +} + +// Send will send the request, returning error if errors are encountered. +// +// Send will sign the request prior to sending. All Send Handlers will +// be executed in the order they were set. +// +// Canceling a request is non-deterministic. If a request has been canceled, +// then the transport will choose, randomly, one of the state channels during +// reads or getting the connection. +// +// readLoop() and getConn(req *Request, cm connectMethod) +// https://github.com/golang/go/blob/master/src/net/http/transport.go +// +// Send will not close the request.Request's body. +func (r *Request) Send() error { + defer func() { + // Regardless of success or failure of the request trigger the Complete + // request handlers. + r.Handlers.Complete.Run(r) + }() + + if err := r.Error; err != nil { + return err + } + + for { + r.Error = nil + r.AttemptTime = time.Now() + + if err := r.Sign(); err != nil { + debugLogReqError(r, "Sign Request", notRetrying, err) + return err + } + + if err := r.sendRequest(); err == nil { + return nil + } + r.Handlers.Retry.Run(r) + r.Handlers.AfterRetry.Run(r) + + if r.Error != nil || !aws.BoolValue(r.Retryable) { + return r.Error + } + + if err := r.prepareRetry(); err != nil { + r.Error = err + return err + } + } +} + +func (r *Request) prepareRetry() error { + if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) { + r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d", + r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount)) + } + + // The previous http.Request will have a reference to the r.Body + // and the HTTP Client's Transport may still be reading from + // the request's body even though the Client's Do returned. + r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil) + r.ResetBody() + if err := r.Error; err != nil { + return awserr.New(ErrCodeSerialization, + "failed to prepare body for retry", err) + + } + + // Closing response body to ensure that no response body is leaked + // between retry attempts. + if r.HTTPResponse != nil && r.HTTPResponse.Body != nil { + r.HTTPResponse.Body.Close() + } + + return nil +} + +func (r *Request) sendRequest() (sendErr error) { + defer r.Handlers.CompleteAttempt.Run(r) + + r.Retryable = nil + r.Handlers.Send.Run(r) + if r.Error != nil { + debugLogReqError(r, "Send Request", + fmtAttemptCount(r.RetryCount, r.MaxRetries()), + r.Error) + return r.Error + } + + r.Handlers.UnmarshalMeta.Run(r) + r.Handlers.ValidateResponse.Run(r) + if r.Error != nil { + r.Handlers.UnmarshalError.Run(r) + debugLogReqError(r, "Validate Response", + fmtAttemptCount(r.RetryCount, r.MaxRetries()), + r.Error) + return r.Error + } + + r.Handlers.Unmarshal.Run(r) + if r.Error != nil { + debugLogReqError(r, "Unmarshal Response", + fmtAttemptCount(r.RetryCount, r.MaxRetries()), + r.Error) + return r.Error + } + + return nil +} + +// copy will copy a request which will allow for local manipulation of the +// request. +func (r *Request) copy() *Request { + req := &Request{} + *req = *r + req.Handlers = r.Handlers.Copy() + op := *r.Operation + req.Operation = &op + return req +} + +// AddToUserAgent adds the string to the end of the request's current user agent. +func AddToUserAgent(r *Request, s string) { + curUA := r.HTTPRequest.Header.Get("User-Agent") + if len(curUA) > 0 { + s = curUA + " " + s + } + r.HTTPRequest.Header.Set("User-Agent", s) +} + +// SanitizeHostForHeader removes default port from host and updates request.Host +func SanitizeHostForHeader(r *http.Request) { + host := getHost(r) + port := portOnly(host) + if port != "" && isDefaultPort(r.URL.Scheme, port) { + r.Host = stripPort(host) + } +} + +// Returns host from request +func getHost(r *http.Request) string { + if r.Host != "" { + return r.Host + } + + return r.URL.Host +} + +// Hostname returns u.Host, without any port number. +// +// If Host is an IPv6 literal with a port number, Hostname returns the +// IPv6 literal without the square brackets. IPv6 literals may include +// a zone identifier. +// +// Copied from the Go 1.8 standard library (net/url) +func stripPort(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return hostport + } + if i := strings.IndexByte(hostport, ']'); i != -1 { + return strings.TrimPrefix(hostport[:i], "[") + } + return hostport[:colon] +} + +// Port returns the port part of u.Host, without the leading colon. +// If u.Host doesn't contain a port, Port returns an empty string. +// +// Copied from the Go 1.8 standard library (net/url) +func portOnly(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return "" + } + if i := strings.Index(hostport, "]:"); i != -1 { + return hostport[i+len("]:"):] + } + if strings.Contains(hostport, "]") { + return "" + } + return hostport[colon+len(":"):] +} + +// Returns true if the specified URI is using the standard port +// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs) +func isDefaultPort(scheme, port string) bool { + if port == "" { + return true + } + + lowerCaseScheme := strings.ToLower(scheme) + if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") { + return true + } + + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go new file mode 100644 index 000000000..e36e468b7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go @@ -0,0 +1,39 @@ +// +build !go1.8 + +package request + +import "io" + +// NoBody is an io.ReadCloser with no bytes. Read always returns EOF +// and Close always returns nil. It can be used in an outgoing client +// request to explicitly signal that a request has zero bytes. +// An alternative, however, is to simply set Request.Body to nil. +// +// Copy of Go 1.8 NoBody type from net/http/http.go +type noBody struct{} + +func (noBody) Read([]byte) (int, error) { return 0, io.EOF } +func (noBody) Close() error { return nil } +func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil } + +// NoBody is an empty reader that will trigger the Go HTTP client to not include +// and body in the HTTP request. +var NoBody = noBody{} + +// ResetBody rewinds the request body back to its starting position, and +// sets the HTTP Request body reference. When the body is read prior +// to being sent in the HTTP request it will need to be rewound. +// +// ResetBody will automatically be called by the SDK's build handler, but if +// the request is being used directly ResetBody must be called before the request +// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically +// call ResetBody. +func (r *Request) ResetBody() { + body, err := r.getNextRequestBody() + if err != nil { + r.Error = err + return + } + + r.HTTPRequest.Body = body +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go new file mode 100644 index 000000000..de1292f45 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go @@ -0,0 +1,36 @@ +// +build go1.8 + +package request + +import ( + "net/http" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// NoBody is a http.NoBody reader instructing Go HTTP client to not include +// and body in the HTTP request. +var NoBody = http.NoBody + +// ResetBody rewinds the request body back to its starting position, and +// sets the HTTP Request body reference. When the body is read prior +// to being sent in the HTTP request it will need to be rewound. +// +// ResetBody will automatically be called by the SDK's build handler, but if +// the request is being used directly ResetBody must be called before the request +// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically +// call ResetBody. +// +// Will also set the Go 1.8's http.Request.GetBody member to allow retrying +// PUT/POST redirects. +func (r *Request) ResetBody() { + body, err := r.getNextRequestBody() + if err != nil { + r.Error = awserr.New(ErrCodeSerialization, + "failed to reset request body", err) + return + } + + r.HTTPRequest.Body = body + r.HTTPRequest.GetBody = r.getNextRequestBody +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go new file mode 100644 index 000000000..a7365cd1e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go @@ -0,0 +1,14 @@ +// +build go1.7 + +package request + +import "github.com/aws/aws-sdk-go/aws" + +// setContext updates the Request to use the passed in context for cancellation. +// Context will also be used for request retry delay. +// +// Creates shallow copy of the http.Request with the WithContext method. +func setRequestContext(r *Request, ctx aws.Context) { + r.context = ctx + r.HTTPRequest = r.HTTPRequest.WithContext(ctx) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go new file mode 100644 index 000000000..307fa0705 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go @@ -0,0 +1,14 @@ +// +build !go1.7 + +package request + +import "github.com/aws/aws-sdk-go/aws" + +// setContext updates the Request to use the passed in context for cancellation. +// Context will also be used for request retry delay. +// +// Creates shallow copy of the http.Request with the WithContext method. +func setRequestContext(r *Request, ctx aws.Context) { + r.context = ctx + r.HTTPRequest.Cancel = ctx.Done() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go new file mode 100644 index 000000000..f093fc542 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go @@ -0,0 +1,264 @@ +package request + +import ( + "reflect" + "sync/atomic" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" +) + +// A Pagination provides paginating of SDK API operations which are paginatable. +// Generally you should not use this type directly, but use the "Pages" API +// operations method to automatically perform pagination for you. Such as, +// "S3.ListObjectsPages", and "S3.ListObjectsPagesWithContext" methods. +// +// Pagination differs from a Paginator type in that pagination is the type that +// does the pagination between API operations, and Paginator defines the +// configuration that will be used per page request. +// +// cont := true +// for p.Next() && cont { +// data := p.Page().(*s3.ListObjectsOutput) +// // process the page's data +// } +// return p.Err() +// +// See service client API operation Pages methods for examples how the SDK will +// use the Pagination type. +type Pagination struct { + // Function to return a Request value for each pagination request. + // Any configuration or handlers that need to be applied to the request + // prior to getting the next page should be done here before the request + // returned. + // + // NewRequest should always be built from the same API operations. It is + // undefined if different API operations are returned on subsequent calls. + NewRequest func() (*Request, error) + // EndPageOnSameToken, when enabled, will allow the paginator to stop on + // token that are the same as its previous tokens. + EndPageOnSameToken bool + + started bool + prevTokens []interface{} + nextTokens []interface{} + + err error + curPage interface{} +} + +// HasNextPage will return true if Pagination is able to determine that the API +// operation has additional pages. False will be returned if there are no more +// pages remaining. +// +// Will always return true if Next has not been called yet. +func (p *Pagination) HasNextPage() bool { + if !p.started { + return true + } + + hasNextPage := len(p.nextTokens) != 0 + if p.EndPageOnSameToken { + return hasNextPage && !awsutil.DeepEqual(p.nextTokens, p.prevTokens) + } + return hasNextPage +} + +// Err returns the error Pagination encountered when retrieving the next page. +func (p *Pagination) Err() error { + return p.err +} + +// Page returns the current page. Page should only be called after a successful +// call to Next. It is undefined what Page will return if Page is called after +// Next returns false. +func (p *Pagination) Page() interface{} { + return p.curPage +} + +// Next will attempt to retrieve the next page for the API operation. When a page +// is retrieved true will be returned. If the page cannot be retrieved, or there +// are no more pages false will be returned. +// +// Use the Page method to retrieve the current page data. The data will need +// to be cast to the API operation's output type. +// +// Use the Err method to determine if an error occurred if Page returns false. +func (p *Pagination) Next() bool { + if !p.HasNextPage() { + return false + } + + req, err := p.NewRequest() + if err != nil { + p.err = err + return false + } + + if p.started { + for i, intok := range req.Operation.InputTokens { + awsutil.SetValueAtPath(req.Params, intok, p.nextTokens[i]) + } + } + p.started = true + + err = req.Send() + if err != nil { + p.err = err + return false + } + + p.prevTokens = p.nextTokens + p.nextTokens = req.nextPageTokens() + p.curPage = req.Data + + return true +} + +// A Paginator is the configuration data that defines how an API operation +// should be paginated. This type is used by the API service models to define +// the generated pagination config for service APIs. +// +// The Pagination type is what provides iterating between pages of an API. It +// is only used to store the token metadata the SDK should use for performing +// pagination. +type Paginator struct { + InputTokens []string + OutputTokens []string + LimitToken string + TruncationToken string +} + +// nextPageTokens returns the tokens to use when asking for the next page of data. +func (r *Request) nextPageTokens() []interface{} { + if r.Operation.Paginator == nil { + return nil + } + if r.Operation.TruncationToken != "" { + tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken) + if len(tr) == 0 { + return nil + } + + switch v := tr[0].(type) { + case *bool: + if !aws.BoolValue(v) { + return nil + } + case bool: + if !v { + return nil + } + } + } + + tokens := []interface{}{} + tokenAdded := false + for _, outToken := range r.Operation.OutputTokens { + vs, _ := awsutil.ValuesAtPath(r.Data, outToken) + if len(vs) == 0 { + tokens = append(tokens, nil) + continue + } + v := vs[0] + + switch tv := v.(type) { + case *string: + if len(aws.StringValue(tv)) == 0 { + tokens = append(tokens, nil) + continue + } + case string: + if len(tv) == 0 { + tokens = append(tokens, nil) + continue + } + } + + tokenAdded = true + tokens = append(tokens, v) + } + if !tokenAdded { + return nil + } + + return tokens +} + +// Ensure a deprecated item is only logged once instead of each time its used. +func logDeprecatedf(logger aws.Logger, flag *int32, msg string) { + if logger == nil { + return + } + if atomic.CompareAndSwapInt32(flag, 0, 1) { + logger.Log(msg) + } +} + +var ( + logDeprecatedHasNextPage int32 + logDeprecatedNextPage int32 + logDeprecatedEachPage int32 +) + +// HasNextPage returns true if this request has more pages of data available. +// +// Deprecated Use Pagination type for configurable pagination of API operations +func (r *Request) HasNextPage() bool { + logDeprecatedf(r.Config.Logger, &logDeprecatedHasNextPage, + "Request.HasNextPage deprecated. Use Pagination type for configurable pagination of API operations") + + return len(r.nextPageTokens()) > 0 +} + +// NextPage returns a new Request that can be executed to return the next +// page of result data. Call .Send() on this request to execute it. +// +// Deprecated Use Pagination type for configurable pagination of API operations +func (r *Request) NextPage() *Request { + logDeprecatedf(r.Config.Logger, &logDeprecatedNextPage, + "Request.NextPage deprecated. Use Pagination type for configurable pagination of API operations") + + tokens := r.nextPageTokens() + if len(tokens) == 0 { + return nil + } + + data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface() + nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data) + for i, intok := range nr.Operation.InputTokens { + awsutil.SetValueAtPath(nr.Params, intok, tokens[i]) + } + return nr +} + +// EachPage iterates over each page of a paginated request object. The fn +// parameter should be a function with the following sample signature: +// +// func(page *T, lastPage bool) bool { +// return true // return false to stop iterating +// } +// +// Where "T" is the structure type matching the output structure of the given +// operation. For example, a request object generated by +// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput +// as the structure "T". The lastPage value represents whether the page is +// the last page of data or not. The return value of this function should +// return true to keep iterating or false to stop. +// +// Deprecated Use Pagination type for configurable pagination of API operations +func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error { + logDeprecatedf(r.Config.Logger, &logDeprecatedEachPage, + "Request.EachPage deprecated. Use Pagination type for configurable pagination of API operations") + + for page := r; page != nil; page = page.NextPage() { + if err := page.Send(); err != nil { + return err + } + if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage { + return page.Error + } + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go new file mode 100644 index 000000000..ede5341bc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go @@ -0,0 +1,266 @@ +package request + +import ( + "net" + "net/url" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// Retryer provides the interface drive the SDK's request retry behavior. The +// Retryer implementation is responsible for implementing exponential backoff, +// and determine if a request API error should be retried. +// +// client.DefaultRetryer is the SDK's default implementation of the Retryer. It +// uses the which uses the Request.IsErrorRetryable and Request.IsErrorThrottle +// methods to determine if the request is retried. +type Retryer interface { + // RetryRules return the retry delay that should be used by the SDK before + // making another request attempt for the failed request. + RetryRules(*Request) time.Duration + + // ShouldRetry returns if the failed request is retryable. + // + // Implementations may consider request attempt count when determining if a + // request is retryable, but the SDK will use MaxRetries to limit the + // number of attempts a request are made. + ShouldRetry(*Request) bool + + // MaxRetries is the number of times a request may be retried before + // failing. + MaxRetries() int +} + +// WithRetryer sets a Retryer value to the given Config returning the Config +// value for chaining. +func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config { + cfg.Retryer = retryer + return cfg +} + +// retryableCodes is a collection of service response codes which are retry-able +// without any further action. +var retryableCodes = map[string]struct{}{ + "RequestError": {}, + "RequestTimeout": {}, + ErrCodeResponseTimeout: {}, + "RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout +} + +var throttleCodes = map[string]struct{}{ + "ProvisionedThroughputExceededException": {}, + "Throttling": {}, + "ThrottlingException": {}, + "RequestLimitExceeded": {}, + "RequestThrottled": {}, + "RequestThrottledException": {}, + "TooManyRequestsException": {}, // Lambda functions + "PriorRequestNotComplete": {}, // Route53 + "TransactionInProgressException": {}, +} + +// credsExpiredCodes is a collection of error codes which signify the credentials +// need to be refreshed. Expired tokens require refreshing of credentials, and +// resigning before the request can be retried. +var credsExpiredCodes = map[string]struct{}{ + "ExpiredToken": {}, + "ExpiredTokenException": {}, + "RequestExpired": {}, // EC2 Only +} + +func isCodeThrottle(code string) bool { + _, ok := throttleCodes[code] + return ok +} + +func isCodeRetryable(code string) bool { + if _, ok := retryableCodes[code]; ok { + return true + } + + return isCodeExpiredCreds(code) +} + +func isCodeExpiredCreds(code string) bool { + _, ok := credsExpiredCodes[code] + return ok +} + +var validParentCodes = map[string]struct{}{ + ErrCodeSerialization: {}, + ErrCodeRead: {}, +} + +type temporaryError interface { + Temporary() bool +} + +func isNestedErrorRetryable(parentErr awserr.Error) bool { + if parentErr == nil { + return false + } + + if _, ok := validParentCodes[parentErr.Code()]; !ok { + return false + } + + err := parentErr.OrigErr() + if err == nil { + return false + } + + if aerr, ok := err.(awserr.Error); ok { + return isCodeRetryable(aerr.Code()) + } + + if t, ok := err.(temporaryError); ok { + return t.Temporary() || isErrConnectionReset(err) + } + + return isErrConnectionReset(err) +} + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if error is nil. +func IsErrorRetryable(err error) bool { + return shouldRetryError(err) +} + +type temporary interface { + Temporary() bool +} + +func shouldRetryError(origErr error) bool { + switch err := origErr.(type) { + case awserr.Error: + if err.Code() == CanceledErrorCode { + return false + } + if isNestedErrorRetryable(err) { + return true + } + + origErr := err.OrigErr() + var shouldRetry bool + if origErr != nil { + shouldRetry := shouldRetryError(origErr) + if err.Code() == "RequestError" && !shouldRetry { + return false + } + } + if isCodeRetryable(err.Code()) { + return true + } + return shouldRetry + + case *url.Error: + if strings.Contains(err.Error(), "connection refused") { + // Refused connections should be retried as the service may not yet + // be running on the port. Go TCP dial considers refused + // connections as not temporary. + return true + } + // *url.Error only implements Temporary after golang 1.6 but since + // url.Error only wraps the error: + return shouldRetryError(err.Err) + + case temporary: + if netErr, ok := err.(*net.OpError); ok && netErr.Op == "dial" { + return true + } + // If the error is temporary, we want to allow continuation of the + // retry process + return err.Temporary() || isErrConnectionReset(origErr) + + case nil: + // `awserr.Error.OrigErr()` can be nil, meaning there was an error but + // because we don't know the cause, it is marked as retryable. See + // TestRequest4xxUnretryable for an example. + return true + + default: + switch err.Error() { + case "net/http: request canceled", + "net/http: request canceled while waiting for connection": + // known 1.5 error case when an http request is cancelled + return false + } + // here we don't know the error; so we allow a retry. + return true + } +} + +// IsErrorThrottle returns whether the error is to be throttled based on its code. +// Returns false if error is nil. +func IsErrorThrottle(err error) bool { + if aerr, ok := err.(awserr.Error); ok && aerr != nil { + return isCodeThrottle(aerr.Code()) + } + return false +} + +// IsErrorExpiredCreds returns whether the error code is a credential expiry +// error. Returns false if error is nil. +func IsErrorExpiredCreds(err error) bool { + if aerr, ok := err.(awserr.Error); ok && aerr != nil { + return isCodeExpiredCreds(aerr.Code()) + } + return false +} + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorRetryable +func (r *Request) IsErrorRetryable() bool { + if r.Error == nil { + return false + } + if isErrCode(r.Error, r.RetryErrorCodes) { + return true + } + + return IsErrorRetryable(r.Error) +} + +// IsErrorThrottle returns whether the error is to be throttled based on its +// code. Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorThrottle +func (r *Request) IsErrorThrottle() bool { + if isErrCode(r.Error, r.ThrottleErrorCodes) { + return true + } + + if r.HTTPResponse != nil { + switch r.HTTPResponse.StatusCode { + case 429, 502, 503, 504: + return true + } + } + + return IsErrorThrottle(r.Error) +} + +func isErrCode(err error, codes []string) bool { + if aerr, ok := err.(awserr.Error); ok { + for _, code := range codes { + if code == aerr.Code() { + return true + } + } + } + + return false +} + +// IsErrorExpired returns whether the error code is a credential expiry error. +// Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorExpiredCreds +func (r *Request) IsErrorExpired() bool { + return IsErrorExpiredCreds(r.Error) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go new file mode 100644 index 000000000..09a44eb98 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go @@ -0,0 +1,94 @@ +package request + +import ( + "io" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +var timeoutErr = awserr.New( + ErrCodeResponseTimeout, + "read on body has reached the timeout limit", + nil, +) + +type readResult struct { + n int + err error +} + +// timeoutReadCloser will handle body reads that take too long. +// We will return a ErrReadTimeout error if a timeout occurs. +type timeoutReadCloser struct { + reader io.ReadCloser + duration time.Duration +} + +// Read will spin off a goroutine to call the reader's Read method. We will +// select on the timer's channel or the read's channel. Whoever completes first +// will be returned. +func (r *timeoutReadCloser) Read(b []byte) (int, error) { + timer := time.NewTimer(r.duration) + c := make(chan readResult, 1) + + go func() { + n, err := r.reader.Read(b) + timer.Stop() + c <- readResult{n: n, err: err} + }() + + select { + case data := <-c: + return data.n, data.err + case <-timer.C: + return 0, timeoutErr + } +} + +func (r *timeoutReadCloser) Close() error { + return r.reader.Close() +} + +const ( + // HandlerResponseTimeout is what we use to signify the name of the + // response timeout handler. + HandlerResponseTimeout = "ResponseTimeoutHandler" +) + +// adaptToResponseTimeoutError is a handler that will replace any top level error +// to a ErrCodeResponseTimeout, if its child is that. +func adaptToResponseTimeoutError(req *Request) { + if err, ok := req.Error.(awserr.Error); ok { + aerr, ok := err.OrigErr().(awserr.Error) + if ok && aerr.Code() == ErrCodeResponseTimeout { + req.Error = aerr + } + } +} + +// WithResponseReadTimeout is a request option that will wrap the body in a timeout read closer. +// This will allow for per read timeouts. If a timeout occurred, we will return the +// ErrCodeResponseTimeout. +// +// svc.PutObjectWithContext(ctx, params, request.WithTimeoutReadCloser(30 * time.Second) +func WithResponseReadTimeout(duration time.Duration) Option { + return func(r *Request) { + + var timeoutHandler = NamedHandler{ + HandlerResponseTimeout, + func(req *Request) { + req.HTTPResponse.Body = &timeoutReadCloser{ + reader: req.HTTPResponse.Body, + duration: duration, + } + }} + + // remove the handler so we are not stomping over any new durations. + r.Handlers.Send.RemoveByName(HandlerResponseTimeout) + r.Handlers.Send.PushBackNamed(timeoutHandler) + + r.Handlers.Unmarshal.PushBack(adaptToResponseTimeoutError) + r.Handlers.UnmarshalError.PushBack(adaptToResponseTimeoutError) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go b/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go new file mode 100644 index 000000000..8630683f3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/validation.go @@ -0,0 +1,286 @@ +package request + +import ( + "bytes" + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +const ( + // InvalidParameterErrCode is the error code for invalid parameters errors + InvalidParameterErrCode = "InvalidParameter" + // ParamRequiredErrCode is the error code for required parameter errors + ParamRequiredErrCode = "ParamRequiredError" + // ParamMinValueErrCode is the error code for fields with too low of a + // number value. + ParamMinValueErrCode = "ParamMinValueError" + // ParamMinLenErrCode is the error code for fields without enough elements. + ParamMinLenErrCode = "ParamMinLenError" + // ParamMaxLenErrCode is the error code for value being too long. + ParamMaxLenErrCode = "ParamMaxLenError" + + // ParamFormatErrCode is the error code for a field with invalid + // format or characters. + ParamFormatErrCode = "ParamFormatInvalidError" +) + +// Validator provides a way for types to perform validation logic on their +// input values that external code can use to determine if a type's values +// are valid. +type Validator interface { + Validate() error +} + +// An ErrInvalidParams provides wrapping of invalid parameter errors found when +// validating API operation input parameters. +type ErrInvalidParams struct { + // Context is the base context of the invalid parameter group. + Context string + errs []ErrInvalidParam +} + +// Add adds a new invalid parameter error to the collection of invalid +// parameters. The context of the invalid parameter will be updated to reflect +// this collection. +func (e *ErrInvalidParams) Add(err ErrInvalidParam) { + err.SetContext(e.Context) + e.errs = append(e.errs, err) +} + +// AddNested adds the invalid parameter errors from another ErrInvalidParams +// value into this collection. The nested errors will have their nested context +// updated and base context to reflect the merging. +// +// Use for nested validations errors. +func (e *ErrInvalidParams) AddNested(nestedCtx string, nested ErrInvalidParams) { + for _, err := range nested.errs { + err.SetContext(e.Context) + err.AddNestedContext(nestedCtx) + e.errs = append(e.errs, err) + } +} + +// Len returns the number of invalid parameter errors +func (e ErrInvalidParams) Len() int { + return len(e.errs) +} + +// Code returns the code of the error +func (e ErrInvalidParams) Code() string { + return InvalidParameterErrCode +} + +// Message returns the message of the error +func (e ErrInvalidParams) Message() string { + return fmt.Sprintf("%d validation error(s) found.", len(e.errs)) +} + +// Error returns the string formatted form of the invalid parameters. +func (e ErrInvalidParams) Error() string { + w := &bytes.Buffer{} + fmt.Fprintf(w, "%s: %s\n", e.Code(), e.Message()) + + for _, err := range e.errs { + fmt.Fprintf(w, "- %s\n", err.Message()) + } + + return w.String() +} + +// OrigErr returns the invalid parameters as a awserr.BatchedErrors value +func (e ErrInvalidParams) OrigErr() error { + return awserr.NewBatchError( + InvalidParameterErrCode, e.Message(), e.OrigErrs()) +} + +// OrigErrs returns a slice of the invalid parameters +func (e ErrInvalidParams) OrigErrs() []error { + errs := make([]error, len(e.errs)) + for i := 0; i < len(errs); i++ { + errs[i] = e.errs[i] + } + + return errs +} + +// An ErrInvalidParam represents an invalid parameter error type. +type ErrInvalidParam interface { + awserr.Error + + // Field name the error occurred on. + Field() string + + // SetContext updates the context of the error. + SetContext(string) + + // AddNestedContext updates the error's context to include a nested level. + AddNestedContext(string) +} + +type errInvalidParam struct { + context string + nestedContext string + field string + code string + msg string +} + +// Code returns the error code for the type of invalid parameter. +func (e *errInvalidParam) Code() string { + return e.code +} + +// Message returns the reason the parameter was invalid, and its context. +func (e *errInvalidParam) Message() string { + return fmt.Sprintf("%s, %s.", e.msg, e.Field()) +} + +// Error returns the string version of the invalid parameter error. +func (e *errInvalidParam) Error() string { + return fmt.Sprintf("%s: %s", e.code, e.Message()) +} + +// OrigErr returns nil, Implemented for awserr.Error interface. +func (e *errInvalidParam) OrigErr() error { + return nil +} + +// Field Returns the field and context the error occurred. +func (e *errInvalidParam) Field() string { + field := e.context + if len(field) > 0 { + field += "." + } + if len(e.nestedContext) > 0 { + field += fmt.Sprintf("%s.", e.nestedContext) + } + field += e.field + + return field +} + +// SetContext updates the base context of the error. +func (e *errInvalidParam) SetContext(ctx string) { + e.context = ctx +} + +// AddNestedContext prepends a context to the field's path. +func (e *errInvalidParam) AddNestedContext(ctx string) { + if len(e.nestedContext) == 0 { + e.nestedContext = ctx + } else { + e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext) + } + +} + +// An ErrParamRequired represents an required parameter error. +type ErrParamRequired struct { + errInvalidParam +} + +// NewErrParamRequired creates a new required parameter error. +func NewErrParamRequired(field string) *ErrParamRequired { + return &ErrParamRequired{ + errInvalidParam{ + code: ParamRequiredErrCode, + field: field, + msg: fmt.Sprintf("missing required field"), + }, + } +} + +// An ErrParamMinValue represents a minimum value parameter error. +type ErrParamMinValue struct { + errInvalidParam + min float64 +} + +// NewErrParamMinValue creates a new minimum value parameter error. +func NewErrParamMinValue(field string, min float64) *ErrParamMinValue { + return &ErrParamMinValue{ + errInvalidParam: errInvalidParam{ + code: ParamMinValueErrCode, + field: field, + msg: fmt.Sprintf("minimum field value of %v", min), + }, + min: min, + } +} + +// MinValue returns the field's require minimum value. +// +// float64 is returned for both int and float min values. +func (e *ErrParamMinValue) MinValue() float64 { + return e.min +} + +// An ErrParamMinLen represents a minimum length parameter error. +type ErrParamMinLen struct { + errInvalidParam + min int +} + +// NewErrParamMinLen creates a new minimum length parameter error. +func NewErrParamMinLen(field string, min int) *ErrParamMinLen { + return &ErrParamMinLen{ + errInvalidParam: errInvalidParam{ + code: ParamMinLenErrCode, + field: field, + msg: fmt.Sprintf("minimum field size of %v", min), + }, + min: min, + } +} + +// MinLen returns the field's required minimum length. +func (e *ErrParamMinLen) MinLen() int { + return e.min +} + +// An ErrParamMaxLen represents a maximum length parameter error. +type ErrParamMaxLen struct { + errInvalidParam + max int +} + +// NewErrParamMaxLen creates a new maximum length parameter error. +func NewErrParamMaxLen(field string, max int, value string) *ErrParamMaxLen { + return &ErrParamMaxLen{ + errInvalidParam: errInvalidParam{ + code: ParamMaxLenErrCode, + field: field, + msg: fmt.Sprintf("maximum size of %v, %v", max, value), + }, + max: max, + } +} + +// MaxLen returns the field's required minimum length. +func (e *ErrParamMaxLen) MaxLen() int { + return e.max +} + +// An ErrParamFormat represents a invalid format parameter error. +type ErrParamFormat struct { + errInvalidParam + format string +} + +// NewErrParamFormat creates a new invalid format parameter error. +func NewErrParamFormat(field string, format, value string) *ErrParamFormat { + return &ErrParamFormat{ + errInvalidParam: errInvalidParam{ + code: ParamFormatErrCode, + field: field, + msg: fmt.Sprintf("format %v, %v", format, value), + }, + format: format, + } +} + +// Format returns the field's required format. +func (e *ErrParamFormat) Format() string { + return e.format +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go new file mode 100644 index 000000000..4601f883c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go @@ -0,0 +1,295 @@ +package request + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/awsutil" +) + +// WaiterResourceNotReadyErrorCode is the error code returned by a waiter when +// the waiter's max attempts have been exhausted. +const WaiterResourceNotReadyErrorCode = "ResourceNotReady" + +// A WaiterOption is a function that will update the Waiter value's fields to +// configure the waiter. +type WaiterOption func(*Waiter) + +// WithWaiterMaxAttempts returns the maximum number of times the waiter should +// attempt to check the resource for the target state. +func WithWaiterMaxAttempts(max int) WaiterOption { + return func(w *Waiter) { + w.MaxAttempts = max + } +} + +// WaiterDelay will return a delay the waiter should pause between attempts to +// check the resource state. The passed in attempt is the number of times the +// Waiter has checked the resource state. +// +// Attempt is the number of attempts the Waiter has made checking the resource +// state. +type WaiterDelay func(attempt int) time.Duration + +// ConstantWaiterDelay returns a WaiterDelay that will always return a constant +// delay the waiter should use between attempts. It ignores the number of +// attempts made. +func ConstantWaiterDelay(delay time.Duration) WaiterDelay { + return func(attempt int) time.Duration { + return delay + } +} + +// WithWaiterDelay will set the Waiter to use the WaiterDelay passed in. +func WithWaiterDelay(delayer WaiterDelay) WaiterOption { + return func(w *Waiter) { + w.Delay = delayer + } +} + +// WithWaiterLogger returns a waiter option to set the logger a waiter +// should use to log warnings and errors to. +func WithWaiterLogger(logger aws.Logger) WaiterOption { + return func(w *Waiter) { + w.Logger = logger + } +} + +// WithWaiterRequestOptions returns a waiter option setting the request +// options for each request the waiter makes. Appends to waiter's request +// options already set. +func WithWaiterRequestOptions(opts ...Option) WaiterOption { + return func(w *Waiter) { + w.RequestOptions = append(w.RequestOptions, opts...) + } +} + +// A Waiter provides the functionality to perform a blocking call which will +// wait for a resource state to be satisfied by a service. +// +// This type should not be used directly. The API operations provided in the +// service packages prefixed with "WaitUntil" should be used instead. +type Waiter struct { + Name string + Acceptors []WaiterAcceptor + Logger aws.Logger + + MaxAttempts int + Delay WaiterDelay + + RequestOptions []Option + NewRequest func([]Option) (*Request, error) + SleepWithContext func(aws.Context, time.Duration) error +} + +// ApplyOptions updates the waiter with the list of waiter options provided. +func (w *Waiter) ApplyOptions(opts ...WaiterOption) { + for _, fn := range opts { + fn(w) + } +} + +// WaiterState are states the waiter uses based on WaiterAcceptor definitions +// to identify if the resource state the waiter is waiting on has occurred. +type WaiterState int + +// String returns the string representation of the waiter state. +func (s WaiterState) String() string { + switch s { + case SuccessWaiterState: + return "success" + case FailureWaiterState: + return "failure" + case RetryWaiterState: + return "retry" + default: + return "unknown waiter state" + } +} + +// States the waiter acceptors will use to identify target resource states. +const ( + SuccessWaiterState WaiterState = iota // waiter successful + FailureWaiterState // waiter failed + RetryWaiterState // waiter needs to be retried +) + +// WaiterMatchMode is the mode that the waiter will use to match the WaiterAcceptor +// definition's Expected attribute. +type WaiterMatchMode int + +// Modes the waiter will use when inspecting API response to identify target +// resource states. +const ( + PathAllWaiterMatch WaiterMatchMode = iota // match on all paths + PathWaiterMatch // match on specific path + PathAnyWaiterMatch // match on any path + PathListWaiterMatch // match on list of paths + StatusWaiterMatch // match on status code + ErrorWaiterMatch // match on error +) + +// String returns the string representation of the waiter match mode. +func (m WaiterMatchMode) String() string { + switch m { + case PathAllWaiterMatch: + return "pathAll" + case PathWaiterMatch: + return "path" + case PathAnyWaiterMatch: + return "pathAny" + case PathListWaiterMatch: + return "pathList" + case StatusWaiterMatch: + return "status" + case ErrorWaiterMatch: + return "error" + default: + return "unknown waiter match mode" + } +} + +// WaitWithContext will make requests for the API operation using NewRequest to +// build API requests. The request's response will be compared against the +// Waiter's Acceptors to determine the successful state of the resource the +// waiter is inspecting. +// +// The passed in context must not be nil. If it is nil a panic will occur. The +// Context will be used to cancel the waiter's pending requests and retry delays. +// Use aws.BackgroundContext if no context is available. +// +// The waiter will continue until the target state defined by the Acceptors, +// or the max attempts expires. +// +// Will return the WaiterResourceNotReadyErrorCode error code if the waiter's +// retryer ShouldRetry returns false. This normally will happen when the max +// wait attempts expires. +func (w Waiter) WaitWithContext(ctx aws.Context) error { + + for attempt := 1; ; attempt++ { + req, err := w.NewRequest(w.RequestOptions) + if err != nil { + waiterLogf(w.Logger, "unable to create request %v", err) + return err + } + req.Handlers.Build.PushBack(MakeAddToUserAgentFreeFormHandler("Waiter")) + err = req.Send() + + // See if any of the acceptors match the request's response, or error + for _, a := range w.Acceptors { + if matched, matchErr := a.match(w.Name, w.Logger, req, err); matched { + return matchErr + } + } + + // The Waiter should only check the resource state MaxAttempts times + // This is here instead of in the for loop above to prevent delaying + // unnecessary when the waiter will not retry. + if attempt == w.MaxAttempts { + break + } + + // Delay to wait before inspecting the resource again + delay := w.Delay(attempt) + if sleepFn := req.Config.SleepDelay; sleepFn != nil { + // Support SleepDelay for backwards compatibility and testing + sleepFn(delay) + } else { + sleepCtxFn := w.SleepWithContext + if sleepCtxFn == nil { + sleepCtxFn = aws.SleepWithContext + } + + if err := sleepCtxFn(ctx, delay); err != nil { + return awserr.New(CanceledErrorCode, "waiter context canceled", err) + } + } + } + + return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil) +} + +// A WaiterAcceptor provides the information needed to wait for an API operation +// to complete. +type WaiterAcceptor struct { + State WaiterState + Matcher WaiterMatchMode + Argument string + Expected interface{} +} + +// match returns if the acceptor found a match with the passed in request +// or error. True is returned if the acceptor made a match, error is returned +// if there was an error attempting to perform the match. +func (a *WaiterAcceptor) match(name string, l aws.Logger, req *Request, err error) (bool, error) { + result := false + var vals []interface{} + + switch a.Matcher { + case PathAllWaiterMatch, PathWaiterMatch: + // Require all matches to be equal for result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + if len(vals) == 0 { + break + } + result = true + for _, val := range vals { + if !awsutil.DeepEqual(val, a.Expected) { + result = false + break + } + } + case PathAnyWaiterMatch: + // Only a single match needs to equal for the result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + for _, val := range vals { + if awsutil.DeepEqual(val, a.Expected) { + result = true + break + } + } + case PathListWaiterMatch: + // ignored matcher + case StatusWaiterMatch: + s := a.Expected.(int) + result = s == req.HTTPResponse.StatusCode + case ErrorWaiterMatch: + if aerr, ok := err.(awserr.Error); ok { + result = aerr.Code() == a.Expected.(string) + } + default: + waiterLogf(l, "WARNING: Waiter %s encountered unexpected matcher: %s", + name, a.Matcher) + } + + if !result { + // If there was no matching result found there is nothing more to do + // for this response, retry the request. + return false, nil + } + + switch a.State { + case SuccessWaiterState: + // waiter completed + return true, nil + case FailureWaiterState: + // Waiter failure state triggered + return true, awserr.New(WaiterResourceNotReadyErrorCode, + "failed waiting for successful resource state", err) + case RetryWaiterState: + // clear the error and retry the operation + return false, nil + default: + waiterLogf(l, "WARNING: Waiter %s encountered unexpected state: %s", + name, a.State) + return false, nil + } +} + +func waiterLogf(logger aws.Logger, msg string, args ...interface{}) { + if logger != nil { + logger.Log(fmt.Sprintf(msg, args...)) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go new file mode 100644 index 000000000..ea9ebb6f6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go @@ -0,0 +1,26 @@ +// +build go1.7 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go new file mode 100644 index 000000000..fec39dfc1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go @@ -0,0 +1,22 @@ +// +build !go1.6,go1.5 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go new file mode 100644 index 000000000..1c5a5391e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go @@ -0,0 +1,23 @@ +// +build !go1.7,go1.6 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/credentials.go b/vendor/github.com/aws/aws-sdk-go/aws/session/credentials.go new file mode 100644 index 000000000..7713ccfca --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/credentials.go @@ -0,0 +1,259 @@ +package session + +import ( + "fmt" + "os" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/processcreds" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/shareddefaults" +) + +func resolveCredentials(cfg *aws.Config, + envCfg envConfig, sharedCfg sharedConfig, + handlers request.Handlers, + sessOpts Options, +) (*credentials.Credentials, error) { + + switch { + case len(sessOpts.Profile) != 0: + // User explicitly provided an Profile in the session's configuration + // so load that profile from shared config first. + // Github(aws/aws-sdk-go#2727) + return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts) + + case envCfg.Creds.HasKeys(): + // Environment credentials + return credentials.NewStaticCredentialsFromCreds(envCfg.Creds), nil + + case len(envCfg.WebIdentityTokenFilePath) != 0: + // Web identity token from environment, RoleARN required to also be + // set. + return assumeWebIdentity(cfg, handlers, + envCfg.WebIdentityTokenFilePath, + envCfg.RoleARN, + envCfg.RoleSessionName, + ) + + default: + // Fallback to the "default" credential resolution chain. + return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts) + } +} + +// WebIdentityEmptyRoleARNErr will occur if 'AWS_WEB_IDENTITY_TOKEN_FILE' was set but +// 'AWS_IAM_ROLE_ARN' was not set. +var WebIdentityEmptyRoleARNErr = awserr.New(stscreds.ErrCodeWebIdentity, "role ARN is not set", nil) + +// WebIdentityEmptyTokenFilePathErr will occur if 'AWS_IAM_ROLE_ARN' was set but +// 'AWS_WEB_IDENTITY_TOKEN_FILE' was not set. +var WebIdentityEmptyTokenFilePathErr = awserr.New(stscreds.ErrCodeWebIdentity, "token file path is not set", nil) + +func assumeWebIdentity(cfg *aws.Config, handlers request.Handlers, + filepath string, + roleARN, sessionName string, +) (*credentials.Credentials, error) { + + if len(filepath) == 0 { + return nil, WebIdentityEmptyTokenFilePathErr + } + + if len(roleARN) == 0 { + return nil, WebIdentityEmptyRoleARNErr + } + + creds := stscreds.NewWebIdentityCredentials( + &Session{ + Config: cfg, + Handlers: handlers.Copy(), + }, + roleARN, + sessionName, + filepath, + ) + + return creds, nil +} + +func resolveCredsFromProfile(cfg *aws.Config, + envCfg envConfig, sharedCfg sharedConfig, + handlers request.Handlers, + sessOpts Options, +) (creds *credentials.Credentials, err error) { + + switch { + case sharedCfg.SourceProfile != nil: + // Assume IAM role with credentials source from a different profile. + creds, err = resolveCredsFromProfile(cfg, envCfg, + *sharedCfg.SourceProfile, handlers, sessOpts, + ) + + case sharedCfg.Creds.HasKeys(): + // Static Credentials from Shared Config/Credentials file. + creds = credentials.NewStaticCredentialsFromCreds( + sharedCfg.Creds, + ) + + case len(sharedCfg.CredentialProcess) != 0: + // Get credentials from CredentialProcess + creds = processcreds.NewCredentials(sharedCfg.CredentialProcess) + + case len(sharedCfg.CredentialSource) != 0: + creds, err = resolveCredsFromSource(cfg, envCfg, + sharedCfg, handlers, sessOpts, + ) + + case len(sharedCfg.WebIdentityTokenFile) != 0: + // Credentials from Assume Web Identity token require an IAM Role, and + // that roll will be assumed. May be wrapped with another assume role + // via SourceProfile. + return assumeWebIdentity(cfg, handlers, + sharedCfg.WebIdentityTokenFile, + sharedCfg.RoleARN, + sharedCfg.RoleSessionName, + ) + + default: + // Fallback to default credentials provider, include mock errors for + // the credential chain so user can identify why credentials failed to + // be retrieved. + creds = credentials.NewCredentials(&credentials.ChainProvider{ + VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), + Providers: []credentials.Provider{ + &credProviderError{ + Err: awserr.New("EnvAccessKeyNotFound", + "failed to find credentials in the environment.", nil), + }, + &credProviderError{ + Err: awserr.New("SharedCredsLoad", + fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil), + }, + defaults.RemoteCredProvider(*cfg, handlers), + }, + }) + } + if err != nil { + return nil, err + } + + if len(sharedCfg.RoleARN) > 0 { + cfgCp := *cfg + cfgCp.Credentials = creds + return credsFromAssumeRole(cfgCp, handlers, sharedCfg, sessOpts) + } + + return creds, nil +} + +// valid credential source values +const ( + credSourceEc2Metadata = "Ec2InstanceMetadata" + credSourceEnvironment = "Environment" + credSourceECSContainer = "EcsContainer" +) + +func resolveCredsFromSource(cfg *aws.Config, + envCfg envConfig, sharedCfg sharedConfig, + handlers request.Handlers, + sessOpts Options, +) (creds *credentials.Credentials, err error) { + + switch sharedCfg.CredentialSource { + case credSourceEc2Metadata: + p := defaults.RemoteCredProvider(*cfg, handlers) + creds = credentials.NewCredentials(p) + + case credSourceEnvironment: + creds = credentials.NewStaticCredentialsFromCreds(envCfg.Creds) + + case credSourceECSContainer: + if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 { + return nil, ErrSharedConfigECSContainerEnvVarEmpty + } + + p := defaults.RemoteCredProvider(*cfg, handlers) + creds = credentials.NewCredentials(p) + + default: + return nil, ErrSharedConfigInvalidCredSource + } + + return creds, nil +} + +func credsFromAssumeRole(cfg aws.Config, + handlers request.Handlers, + sharedCfg sharedConfig, + sessOpts Options, +) (*credentials.Credentials, error) { + + if len(sharedCfg.MFASerial) != 0 && sessOpts.AssumeRoleTokenProvider == nil { + // AssumeRole Token provider is required if doing Assume Role + // with MFA. + return nil, AssumeRoleTokenProviderNotSetError{} + } + + return stscreds.NewCredentials( + &Session{ + Config: &cfg, + Handlers: handlers.Copy(), + }, + sharedCfg.RoleARN, + func(opt *stscreds.AssumeRoleProvider) { + opt.RoleSessionName = sharedCfg.RoleSessionName + opt.Duration = sessOpts.AssumeRoleDuration + + // Assume role with external ID + if len(sharedCfg.ExternalID) > 0 { + opt.ExternalID = aws.String(sharedCfg.ExternalID) + } + + // Assume role with MFA + if len(sharedCfg.MFASerial) > 0 { + opt.SerialNumber = aws.String(sharedCfg.MFASerial) + opt.TokenProvider = sessOpts.AssumeRoleTokenProvider + } + }, + ), nil +} + +// AssumeRoleTokenProviderNotSetError is an error returned when creating a +// session when the MFAToken option is not set when shared config is configured +// load assume a role with an MFA token. +type AssumeRoleTokenProviderNotSetError struct{} + +// Code is the short id of the error. +func (e AssumeRoleTokenProviderNotSetError) Code() string { + return "AssumeRoleTokenProviderNotSetError" +} + +// Message is the description of the error +func (e AssumeRoleTokenProviderNotSetError) Message() string { + return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.") +} + +// OrigErr is the underlying error that caused the failure. +func (e AssumeRoleTokenProviderNotSetError) OrigErr() error { + return nil +} + +// Error satisfies the error interface. +func (e AssumeRoleTokenProviderNotSetError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", nil) +} + +type credProviderError struct { + Err error +} + +func (c credProviderError) Retrieve() (credentials.Value, error) { + return credentials.Value{}, c.Err +} +func (c credProviderError) IsExpired() bool { + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go new file mode 100644 index 000000000..7ec66e7e5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go @@ -0,0 +1,245 @@ +/* +Package session provides configuration for the SDK's service clients. Sessions +can be shared across service clients that share the same base configuration. + +Sessions are safe to use concurrently as long as the Session is not being +modified. Sessions should be cached when possible, because creating a new +Session will load all configuration values from the environment, and config +files each time the Session is created. Sharing the Session value across all of +your service clients will ensure the configuration is loaded the fewest number +of times possible. + +Sessions options from Shared Config + +By default NewSession will only load credentials from the shared credentials +file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is +set to a truthy value the Session will be created from the configuration +values from the shared config (~/.aws/config) and shared credentials +(~/.aws/credentials) files. Using the NewSessionWithOptions with +SharedConfigState set to SharedConfigEnable will create the session as if the +AWS_SDK_LOAD_CONFIG environment variable was set. + +Credential and config loading order + +The Session will attempt to load configuration and credentials from the +environment, configuration files, and other credential sources. The order +configuration is loaded in is: + + * Environment Variables + * Shared Credentials file + * Shared Configuration file (if SharedConfig is enabled) + * EC2 Instance Metadata (credentials only) + +The Environment variables for credentials will have precedence over shared +config even if SharedConfig is enabled. To override this behavior, and use +shared config credentials instead specify the session.Options.Profile, (e.g. +when using credential_source=Environment to assume a role). + + sess, err := session.NewSessionWithOptions(session.Options{ + Profile: "myProfile", + }) + +Creating Sessions + +Creating a Session without additional options will load credentials region, and +profile loaded from the environment and shared config automatically. See, +"Environment Variables" section for information on environment variables used +by Session. + + // Create Session + sess, err := session.NewSession() + + +When creating Sessions optional aws.Config values can be passed in that will +override the default, or loaded, config values the Session is being created +with. This allows you to provide additional, or case based, configuration +as needed. + + // Create a Session with a custom region + sess, err := session.NewSession(&aws.Config{ + Region: aws.String("us-west-2"), + }) + +Use NewSessionWithOptions to provide additional configuration driving how the +Session's configuration will be loaded. Such as, specifying shared config +profile, or override the shared config state, (AWS_SDK_LOAD_CONFIG). + + // Equivalent to session.NewSession() + sess, err := session.NewSessionWithOptions(session.Options{ + // Options + }) + + sess, err := session.NewSessionWithOptions(session.Options{ + // Specify profile to load for the session's config + Profile: "profile_name", + + // Provide SDK Config options, such as Region. + Config: aws.Config{ + Region: aws.String("us-west-2"), + }, + + // Force enable Shared Config support + SharedConfigState: session.SharedConfigEnable, + }) + +Adding Handlers + +You can add handlers to a session to decorate API operation, (e.g. adding HTTP +headers). All clients that use the Session receive a copy of the Session's +handlers. For example, the following request handler added to the Session logs +every requests made. + + // Create a session, and add additional handlers for all service + // clients created with the Session to inherit. Adds logging handler. + sess := session.Must(session.NewSession()) + + sess.Handlers.Send.PushFront(func(r *request.Request) { + // Log every request made and its payload + logger.Printf("Request: %s/%s, Params: %s", + r.ClientInfo.ServiceName, r.Operation, r.Params) + }) + +Shared Config Fields + +By default the SDK will only load the shared credentials file's +(~/.aws/credentials) credentials values, and all other config is provided by +the environment variables, SDK defaults, and user provided aws.Config values. + +If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable +option is used to create the Session the full shared config values will be +loaded. This includes credentials, region, and support for assume role. In +addition the Session will load its configuration from both the shared config +file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both +files have the same format. + +If both config files are present the configuration from both files will be +read. The Session will be created from configuration values from the shared +credentials file (~/.aws/credentials) over those in the shared config file +(~/.aws/config). + +Credentials are the values the SDK uses to authenticating requests with AWS +Services. When specified in a file, both aws_access_key_id and +aws_secret_access_key must be provided together in the same file to be +considered valid. They will be ignored if both are not present. +aws_session_token is an optional field that can be provided in addition to the +other two fields. + + aws_access_key_id = AKID + aws_secret_access_key = SECRET + aws_session_token = TOKEN + + ; region only supported if SharedConfigEnabled. + region = us-east-1 + +Assume Role configuration + +The role_arn field allows you to configure the SDK to assume an IAM role using +a set of credentials from another source. Such as when paired with static +credentials, "profile_source", "credential_process", or "credential_source" +fields. If "role_arn" is provided, a source of credentials must also be +specified, such as "source_profile", "credential_source", or +"credential_process". + + role_arn = arn:aws:iam:::role/ + source_profile = profile_with_creds + external_id = 1234 + mfa_serial = + role_session_name = session_name + + +The SDK supports assuming a role with MFA token. If "mfa_serial" is set, you +must also set the Session Option.AssumeRoleTokenProvider. The Session will fail +to load if the AssumeRoleTokenProvider is not specified. + + sess := session.Must(session.NewSessionWithOptions(session.Options{ + AssumeRoleTokenProvider: stscreds.StdinTokenProvider, + })) + +To setup Assume Role outside of a session see the stscreds.AssumeRoleProvider +documentation. + +Environment Variables + +When a Session is created several environment variables can be set to adjust +how the SDK functions, and what configuration data it loads when creating +Sessions. All environment values are optional, but some values like credentials +require multiple of the values to set or the partial values will be ignored. +All environment variable values are strings unless otherwise noted. + +Environment configuration values. If set both Access Key ID and Secret Access +Key must be provided. Session Token and optionally also be provided, but is +not required. + + # Access Key ID + AWS_ACCESS_KEY_ID=AKID + AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. + + # Secret Access Key + AWS_SECRET_ACCESS_KEY=SECRET + AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. + + # Session Token + AWS_SESSION_TOKEN=TOKEN + +Region value will instruct the SDK where to make service API requests to. If is +not provided in the environment the region must be provided before a service +client request is made. + + AWS_REGION=us-east-1 + + # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, + # and AWS_REGION is not also set. + AWS_DEFAULT_REGION=us-east-1 + +Profile name the SDK should load use when loading shared config from the +configuration files. If not provided "default" will be used as the profile name. + + AWS_PROFILE=my_profile + + # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, + # and AWS_PROFILE is not also set. + AWS_DEFAULT_PROFILE=my_profile + +SDK load config instructs the SDK to load the shared config in addition to +shared credentials. This also expands the configuration loaded so the shared +credentials will have parity with the shared config file. This also enables +Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE +env values as well. + + AWS_SDK_LOAD_CONFIG=1 + +Shared credentials file path can be set to instruct the SDK to use an alternative +file for the shared credentials. If not set the file will be loaded from +$HOME/.aws/credentials on Linux/Unix based systems, and +%USERPROFILE%\.aws\credentials on Windows. + + AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials + +Shared config file path can be set to instruct the SDK to use an alternative +file for the shared config. If not set the file will be loaded from +$HOME/.aws/config on Linux/Unix based systems, and +%USERPROFILE%\.aws\config on Windows. + + AWS_CONFIG_FILE=$HOME/my_shared_config + +Path to a custom Credentials Authority (CA) bundle PEM file that the SDK +will use instead of the default system's root CA bundle. Use this only +if you want to replace the CA bundle the SDK uses for TLS requests. + + AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle + +Enabling this option will attempt to merge the Transport into the SDK's HTTP +client. If the client's Transport is not a http.Transport an error will be +returned. If the Transport's TLS config is set this option will cause the SDK +to overwrite the Transport's TLS config's RootCAs value. If the CA bundle file +contains multiple certificates all of them will be loaded. + +The Session option CustomCABundle is also available when creating sessions +to also enable this feature. CustomCABundle session option field has priority +over the AWS_CA_BUNDLE environment variable, and will be used if both are set. + +Setting a custom HTTPClient in the aws.Config options will override this setting. +To use this option and custom HTTP client, the HTTP client needs to be provided +when creating the session. Not the service client. +*/ +package session diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go new file mode 100644 index 000000000..3a998d5bd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go @@ -0,0 +1,273 @@ +package session + +import ( + "os" + "strconv" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/defaults" +) + +// EnvProviderName provides a name of the provider when config is loaded from environment. +const EnvProviderName = "EnvConfigCredentials" + +// envConfig is a collection of environment values the SDK will read +// setup config from. All environment values are optional. But some values +// such as credentials require multiple values to be complete or the values +// will be ignored. +type envConfig struct { + // Environment configuration values. If set both Access Key ID and Secret Access + // Key must be provided. Session Token and optionally also be provided, but is + // not required. + // + // # Access Key ID + // AWS_ACCESS_KEY_ID=AKID + // AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. + // + // # Secret Access Key + // AWS_SECRET_ACCESS_KEY=SECRET + // AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. + // + // # Session Token + // AWS_SESSION_TOKEN=TOKEN + Creds credentials.Value + + // Region value will instruct the SDK where to make service API requests to. If is + // not provided in the environment the region must be provided before a service + // client request is made. + // + // AWS_REGION=us-east-1 + // + // # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, + // # and AWS_REGION is not also set. + // AWS_DEFAULT_REGION=us-east-1 + Region string + + // Profile name the SDK should load use when loading shared configuration from the + // shared configuration files. If not provided "default" will be used as the + // profile name. + // + // AWS_PROFILE=my_profile + // + // # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, + // # and AWS_PROFILE is not also set. + // AWS_DEFAULT_PROFILE=my_profile + Profile string + + // SDK load config instructs the SDK to load the shared config in addition to + // shared credentials. This also expands the configuration loaded from the shared + // credentials to have parity with the shared config file. This also enables + // Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE + // env values as well. + // + // AWS_SDK_LOAD_CONFIG=1 + EnableSharedConfig bool + + // Shared credentials file path can be set to instruct the SDK to use an alternate + // file for the shared credentials. If not set the file will be loaded from + // $HOME/.aws/credentials on Linux/Unix based systems, and + // %USERPROFILE%\.aws\credentials on Windows. + // + // AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials + SharedCredentialsFile string + + // Shared config file path can be set to instruct the SDK to use an alternate + // file for the shared config. If not set the file will be loaded from + // $HOME/.aws/config on Linux/Unix based systems, and + // %USERPROFILE%\.aws\config on Windows. + // + // AWS_CONFIG_FILE=$HOME/my_shared_config + SharedConfigFile string + + // Sets the path to a custom Credentials Authority (CA) Bundle PEM file + // that the SDK will use instead of the system's root CA bundle. + // Only use this if you want to configure the SDK to use a custom set + // of CAs. + // + // Enabling this option will attempt to merge the Transport + // into the SDK's HTTP client. If the client's Transport is + // not a http.Transport an error will be returned. If the + // Transport's TLS config is set this option will cause the + // SDK to overwrite the Transport's TLS config's RootCAs value. + // + // Setting a custom HTTPClient in the aws.Config options will override this setting. + // To use this option and custom HTTP client, the HTTP client needs to be provided + // when creating the session. Not the service client. + // + // AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle + CustomCABundle string + + csmEnabled string + CSMEnabled bool + CSMPort string + CSMClientID string + CSMHost string + + // Enables endpoint discovery via environment variables. + // + // AWS_ENABLE_ENDPOINT_DISCOVERY=true + EnableEndpointDiscovery *bool + enableEndpointDiscovery string + + // Specifies the WebIdentity token the SDK should use to assume a role + // with. + // + // AWS_WEB_IDENTITY_TOKEN_FILE=file_path + WebIdentityTokenFilePath string + + // Specifies the IAM role arn to use when assuming an role. + // + // AWS_ROLE_ARN=role_arn + RoleARN string + + // Specifies the IAM role session name to use when assuming a role. + // + // AWS_ROLE_SESSION_NAME=session_name + RoleSessionName string +} + +var ( + csmEnabledEnvKey = []string{ + "AWS_CSM_ENABLED", + } + csmHostEnvKey = []string{ + "AWS_CSM_HOST", + } + csmPortEnvKey = []string{ + "AWS_CSM_PORT", + } + csmClientIDEnvKey = []string{ + "AWS_CSM_CLIENT_ID", + } + credAccessEnvKey = []string{ + "AWS_ACCESS_KEY_ID", + "AWS_ACCESS_KEY", + } + credSecretEnvKey = []string{ + "AWS_SECRET_ACCESS_KEY", + "AWS_SECRET_KEY", + } + credSessionEnvKey = []string{ + "AWS_SESSION_TOKEN", + } + + enableEndpointDiscoveryEnvKey = []string{ + "AWS_ENABLE_ENDPOINT_DISCOVERY", + } + + regionEnvKeys = []string{ + "AWS_REGION", + "AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set + } + profileEnvKeys = []string{ + "AWS_PROFILE", + "AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set + } + sharedCredsFileEnvKey = []string{ + "AWS_SHARED_CREDENTIALS_FILE", + } + sharedConfigFileEnvKey = []string{ + "AWS_CONFIG_FILE", + } + webIdentityTokenFilePathEnvKey = []string{ + "AWS_WEB_IDENTITY_TOKEN_FILE", + } + roleARNEnvKey = []string{ + "AWS_ROLE_ARN", + } + roleSessionNameEnvKey = []string{ + "AWS_ROLE_SESSION_NAME", + } +) + +// loadEnvConfig retrieves the SDK's environment configuration. +// See `envConfig` for the values that will be retrieved. +// +// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value +// the shared SDK config will be loaded in addition to the SDK's specific +// configuration values. +func loadEnvConfig() envConfig { + enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG")) + return envConfigLoad(enableSharedConfig) +} + +// loadEnvSharedConfig retrieves the SDK's environment configuration, and the +// SDK shared config. See `envConfig` for the values that will be retrieved. +// +// Loads the shared configuration in addition to the SDK's specific configuration. +// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG` +// environment variable is set. +func loadSharedEnvConfig() envConfig { + return envConfigLoad(true) +} + +func envConfigLoad(enableSharedConfig bool) envConfig { + cfg := envConfig{} + + cfg.EnableSharedConfig = enableSharedConfig + + // Static environment credentials + var creds credentials.Value + setFromEnvVal(&creds.AccessKeyID, credAccessEnvKey) + setFromEnvVal(&creds.SecretAccessKey, credSecretEnvKey) + setFromEnvVal(&creds.SessionToken, credSessionEnvKey) + if creds.HasKeys() { + // Require logical grouping of credentials + creds.ProviderName = EnvProviderName + cfg.Creds = creds + } + + // Role Metadata + setFromEnvVal(&cfg.RoleARN, roleARNEnvKey) + setFromEnvVal(&cfg.RoleSessionName, roleSessionNameEnvKey) + + // Web identity environment variables + setFromEnvVal(&cfg.WebIdentityTokenFilePath, webIdentityTokenFilePathEnvKey) + + // CSM environment variables + setFromEnvVal(&cfg.csmEnabled, csmEnabledEnvKey) + setFromEnvVal(&cfg.CSMHost, csmHostEnvKey) + setFromEnvVal(&cfg.CSMPort, csmPortEnvKey) + setFromEnvVal(&cfg.CSMClientID, csmClientIDEnvKey) + cfg.CSMEnabled = len(cfg.csmEnabled) > 0 + + regionKeys := regionEnvKeys + profileKeys := profileEnvKeys + if !cfg.EnableSharedConfig { + regionKeys = regionKeys[:1] + profileKeys = profileKeys[:1] + } + + setFromEnvVal(&cfg.Region, regionKeys) + setFromEnvVal(&cfg.Profile, profileKeys) + + // endpoint discovery is in reference to it being enabled. + setFromEnvVal(&cfg.enableEndpointDiscovery, enableEndpointDiscoveryEnvKey) + if len(cfg.enableEndpointDiscovery) > 0 { + cfg.EnableEndpointDiscovery = aws.Bool(cfg.enableEndpointDiscovery != "false") + } + + setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey) + setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey) + + if len(cfg.SharedCredentialsFile) == 0 { + cfg.SharedCredentialsFile = defaults.SharedCredentialsFilename() + } + if len(cfg.SharedConfigFile) == 0 { + cfg.SharedConfigFile = defaults.SharedConfigFilename() + } + + cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") + + return cfg +} + +func setFromEnvVal(dst *string, keys []string) { + for _, k := range keys { + if v := os.Getenv(k); len(v) > 0 { + *dst = v + break + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go new file mode 100644 index 000000000..1b4fcdb10 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go @@ -0,0 +1,609 @@ +package session + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/csm" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/endpoints" + "github.com/aws/aws-sdk-go/aws/request" +) + +const ( + // ErrCodeSharedConfig represents an error that occurs in the shared + // configuration logic + ErrCodeSharedConfig = "SharedConfigErr" +) + +// ErrSharedConfigSourceCollision will be returned if a section contains both +// source_profile and credential_source +var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil) + +// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment +// variables are empty and Environment was set as the credential source +var ErrSharedConfigECSContainerEnvVarEmpty = awserr.New(ErrCodeSharedConfig, "EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set", nil) + +// ErrSharedConfigInvalidCredSource will be returned if an invalid credential source was provided +var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credential source values must be EcsContainer, Ec2InstanceMetadata, or Environment", nil) + +// A Session provides a central location to create service clients from and +// store configurations and request handlers for those services. +// +// Sessions are safe to create service clients concurrently, but it is not safe +// to mutate the Session concurrently. +// +// The Session satisfies the service client's client.ConfigProvider. +type Session struct { + Config *aws.Config + Handlers request.Handlers +} + +// New creates a new instance of the handlers merging in the provided configs +// on top of the SDK's default configurations. Once the Session is created it +// can be mutated to modify the Config or Handlers. The Session is safe to be +// read concurrently, but it should not be written to concurrently. +// +// If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New +// method could now encounter an error when loading the configuration. When +// The environment variable is set, and an error occurs, New will return a +// session that will fail all requests reporting the error that occurred while +// loading the session. Use NewSession to get the error when creating the +// session. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded, in addition to +// the shared credentials file (~/.aws/credentials). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. +// +// Deprecated: Use NewSession functions to create sessions instead. NewSession +// has the same functionality as New except an error can be returned when the +// func is called instead of waiting to receive an error until a request is made. +func New(cfgs ...*aws.Config) *Session { + // load initial config from environment + envCfg := loadEnvConfig() + + if envCfg.EnableSharedConfig { + var cfg aws.Config + cfg.MergeIn(cfgs...) + s, err := NewSessionWithOptions(Options{ + Config: cfg, + SharedConfigState: SharedConfigEnable, + }) + if err != nil { + // Old session.New expected all errors to be discovered when + // a request is made, and would report the errors then. This + // needs to be replicated if an error occurs while creating + // the session. + msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " + + "Use session.NewSession to handle errors occurring during session creation." + + // Session creation failed, need to report the error and prevent + // any requests from succeeding. + s = &Session{Config: defaults.Config()} + s.Config.MergeIn(cfgs...) + s.Config.Logger.Log("ERROR:", msg, "Error:", err) + s.Handlers.Validate.PushBack(func(r *request.Request) { + r.Error = err + }) + } + + return s + } + + s := deprecatedNewSession(cfgs...) + if envCfg.CSMEnabled { + err := enableCSM(&s.Handlers, envCfg.CSMClientID, + envCfg.CSMHost, envCfg.CSMPort, s.Config.Logger) + if err != nil { + err = fmt.Errorf("failed to enable CSM, %v", err) + s.Config.Logger.Log("ERROR:", err.Error()) + s.Handlers.Validate.PushBack(func(r *request.Request) { + r.Error = err + }) + } + } + + return s +} + +// NewSession returns a new Session created from SDK defaults, config files, +// environment, and user provided config files. Once the Session is created +// it can be mutated to modify the Config or Handlers. The Session is safe to +// be read concurrently, but it should not be written to concurrently. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded in addition to +// the shared credentials file (~/.aws/credentials). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. Enabling the Shared Config will also allow the Session +// to be built with retrieving credentials with AssumeRole set in the config. +// +// See the NewSessionWithOptions func for information on how to override or +// control through code how the Session will be created. Such as specifying the +// config profile, and controlling if shared config is enabled or not. +func NewSession(cfgs ...*aws.Config) (*Session, error) { + opts := Options{} + opts.Config.MergeIn(cfgs...) + + return NewSessionWithOptions(opts) +} + +// SharedConfigState provides the ability to optionally override the state +// of the session's creation based on the shared config being enabled or +// disabled. +type SharedConfigState int + +const ( + // SharedConfigStateFromEnv does not override any state of the + // AWS_SDK_LOAD_CONFIG env var. It is the default value of the + // SharedConfigState type. + SharedConfigStateFromEnv SharedConfigState = iota + + // SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value + // and disables the shared config functionality. + SharedConfigDisable + + // SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value + // and enables the shared config functionality. + SharedConfigEnable +) + +// Options provides the means to control how a Session is created and what +// configuration values will be loaded. +// +type Options struct { + // Provides config values for the SDK to use when creating service clients + // and making API requests to services. Any value set in with this field + // will override the associated value provided by the SDK defaults, + // environment or config files where relevant. + // + // If not set, configuration values from from SDK defaults, environment, + // config will be used. + Config aws.Config + + // Overrides the config profile the Session should be created from. If not + // set the value of the environment variable will be loaded (AWS_PROFILE, + // or AWS_DEFAULT_PROFILE if the Shared Config is enabled). + // + // If not set and environment variables are not set the "default" + // (DefaultSharedConfigProfile) will be used as the profile to load the + // session config from. + Profile string + + // Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG + // environment variable. By default a Session will be created using the + // value provided by the AWS_SDK_LOAD_CONFIG environment variable. + // + // Setting this value to SharedConfigEnable or SharedConfigDisable + // will allow you to override the AWS_SDK_LOAD_CONFIG environment variable + // and enable or disable the shared config functionality. + SharedConfigState SharedConfigState + + // Ordered list of files the session will load configuration from. + // It will override environment variable AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE. + SharedConfigFiles []string + + // When the SDK's shared config is configured to assume a role with MFA + // this option is required in order to provide the mechanism that will + // retrieve the MFA token. There is no default value for this field. If + // it is not set an error will be returned when creating the session. + // + // This token provider will be called when ever the assumed role's + // credentials need to be refreshed. Within the context of service clients + // all sharing the same session the SDK will ensure calls to the token + // provider are atomic. When sharing a token provider across multiple + // sessions additional synchronization logic is needed to ensure the + // token providers do not introduce race conditions. It is recommend to + // share the session where possible. + // + // stscreds.StdinTokenProvider is a basic implementation that will prompt + // from stdin for the MFA token code. + // + // This field is only used if the shared configuration is enabled, and + // the config enables assume role wit MFA via the mfa_serial field. + AssumeRoleTokenProvider func() (string, error) + + // When the SDK's shared config is configured to assume a role this option + // may be provided to set the expiry duration of the STS credentials. + // Defaults to 15 minutes if not set as documented in the + // stscreds.AssumeRoleProvider. + AssumeRoleDuration time.Duration + + // Reader for a custom Credentials Authority (CA) bundle in PEM format that + // the SDK will use instead of the default system's root CA bundle. Use this + // only if you want to replace the CA bundle the SDK uses for TLS requests. + // + // Enabling this option will attempt to merge the Transport into the SDK's HTTP + // client. If the client's Transport is not a http.Transport an error will be + // returned. If the Transport's TLS config is set this option will cause the SDK + // to overwrite the Transport's TLS config's RootCAs value. If the CA + // bundle reader contains multiple certificates all of them will be loaded. + // + // The Session option CustomCABundle is also available when creating sessions + // to also enable this feature. CustomCABundle session option field has priority + // over the AWS_CA_BUNDLE environment variable, and will be used if both are set. + CustomCABundle io.Reader + + // The handlers that the session and all API clients will be created with. + // This must be a complete set of handlers. Use the defaults.Handlers() + // function to initialize this value before changing the handlers to be + // used by the SDK. + Handlers request.Handlers +} + +// NewSessionWithOptions returns a new Session created from SDK defaults, config files, +// environment, and user provided config files. This func uses the Options +// values to configure how the Session is created. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded in addition to +// the shared credentials file (~/.aws/credentials). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. Enabling the Shared Config will also allow the Session +// to be built with retrieving credentials with AssumeRole set in the config. +// +// // Equivalent to session.New +// sess := session.Must(session.NewSessionWithOptions(session.Options{})) +// +// // Specify profile to load for the session's config +// sess := session.Must(session.NewSessionWithOptions(session.Options{ +// Profile: "profile_name", +// })) +// +// // Specify profile for config and region for requests +// sess := session.Must(session.NewSessionWithOptions(session.Options{ +// Config: aws.Config{Region: aws.String("us-east-1")}, +// Profile: "profile_name", +// })) +// +// // Force enable Shared Config support +// sess := session.Must(session.NewSessionWithOptions(session.Options{ +// SharedConfigState: session.SharedConfigEnable, +// })) +func NewSessionWithOptions(opts Options) (*Session, error) { + var envCfg envConfig + if opts.SharedConfigState == SharedConfigEnable { + envCfg = loadSharedEnvConfig() + } else { + envCfg = loadEnvConfig() + } + + if len(opts.Profile) != 0 { + envCfg.Profile = opts.Profile + } + + switch opts.SharedConfigState { + case SharedConfigDisable: + envCfg.EnableSharedConfig = false + case SharedConfigEnable: + envCfg.EnableSharedConfig = true + } + + // Only use AWS_CA_BUNDLE if session option is not provided. + if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil { + f, err := os.Open(envCfg.CustomCABundle) + if err != nil { + return nil, awserr.New("LoadCustomCABundleError", + "failed to open custom CA bundle PEM file", err) + } + defer f.Close() + opts.CustomCABundle = f + } + + return newSession(opts, envCfg, &opts.Config) +} + +// Must is a helper function to ensure the Session is valid and there was no +// error when calling a NewSession function. +// +// This helper is intended to be used in variable initialization to load the +// Session and configuration at startup. Such as: +// +// var sess = session.Must(session.NewSession()) +func Must(sess *Session, err error) *Session { + if err != nil { + panic(err) + } + + return sess +} + +func deprecatedNewSession(cfgs ...*aws.Config) *Session { + cfg := defaults.Config() + handlers := defaults.Handlers() + + // Apply the passed in configs so the configuration can be applied to the + // default credential chain + cfg.MergeIn(cfgs...) + if cfg.EndpointResolver == nil { + // An endpoint resolver is required for a session to be able to provide + // endpoints for service client configurations. + cfg.EndpointResolver = endpoints.DefaultResolver() + } + cfg.Credentials = defaults.CredChain(cfg, handlers) + + // Reapply any passed in configs to override credentials if set + cfg.MergeIn(cfgs...) + + s := &Session{ + Config: cfg, + Handlers: handlers, + } + + initHandlers(s) + return s +} + +func enableCSM(handlers *request.Handlers, + clientID, host, port string, + logger aws.Logger, +) error { + if logger != nil { + logger.Log("Enabling CSM") + } + + r, err := csm.Start(clientID, csm.AddressWithDefaults(host, port)) + if err != nil { + return err + } + r.InjectHandlers(handlers) + + return nil +} + +func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { + cfg := defaults.Config() + + handlers := opts.Handlers + if handlers.IsEmpty() { + handlers = defaults.Handlers() + } + + // Get a merged version of the user provided config to determine if + // credentials were. + userCfg := &aws.Config{} + userCfg.MergeIn(cfgs...) + cfg.MergeIn(userCfg) + + // Ordered config files will be loaded in with later files overwriting + // previous config file values. + var cfgFiles []string + if opts.SharedConfigFiles != nil { + cfgFiles = opts.SharedConfigFiles + } else { + cfgFiles = []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile} + if !envCfg.EnableSharedConfig { + // The shared config file (~/.aws/config) is only loaded if instructed + // to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG). + cfgFiles = cfgFiles[1:] + } + } + + // Load additional config from file(s) + sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles, envCfg.EnableSharedConfig) + if err != nil { + if _, ok := err.(SharedConfigProfileNotExistsError); !ok { + return nil, err + } + } + + if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil { + return nil, err + } + + s := &Session{ + Config: cfg, + Handlers: handlers, + } + + initHandlers(s) + if envCfg.CSMEnabled { + err := enableCSM(&s.Handlers, envCfg.CSMClientID, + envCfg.CSMHost, envCfg.CSMPort, s.Config.Logger) + if err != nil { + return nil, err + } + } + + // Setup HTTP client with custom cert bundle if enabled + if opts.CustomCABundle != nil { + if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil { + return nil, err + } + } + + return s, nil +} + +func loadCustomCABundle(s *Session, bundle io.Reader) error { + var t *http.Transport + switch v := s.Config.HTTPClient.Transport.(type) { + case *http.Transport: + t = v + default: + if s.Config.HTTPClient.Transport != nil { + return awserr.New("LoadCustomCABundleError", + "unable to load custom CA bundle, HTTPClient's transport unsupported type", nil) + } + } + if t == nil { + // Nil transport implies `http.DefaultTransport` should be used. Since + // the SDK cannot modify, nor copy the `DefaultTransport` specifying + // the values the next closest behavior. + t = getCABundleTransport() + } + + p, err := loadCertPool(bundle) + if err != nil { + return err + } + if t.TLSClientConfig == nil { + t.TLSClientConfig = &tls.Config{} + } + t.TLSClientConfig.RootCAs = p + + s.Config.HTTPClient.Transport = t + + return nil +} + +func loadCertPool(r io.Reader) (*x509.CertPool, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, awserr.New("LoadCustomCABundleError", + "failed to read custom CA bundle PEM file", err) + } + + p := x509.NewCertPool() + if !p.AppendCertsFromPEM(b) { + return nil, awserr.New("LoadCustomCABundleError", + "failed to load custom CA bundle PEM file", err) + } + + return p, nil +} + +func mergeConfigSrcs(cfg, userCfg *aws.Config, + envCfg envConfig, sharedCfg sharedConfig, + handlers request.Handlers, + sessOpts Options, +) error { + + // Region if not already set by user + if len(aws.StringValue(cfg.Region)) == 0 { + if len(envCfg.Region) > 0 { + cfg.WithRegion(envCfg.Region) + } else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 { + cfg.WithRegion(sharedCfg.Region) + } + } + + if cfg.EnableEndpointDiscovery == nil { + if envCfg.EnableEndpointDiscovery != nil { + cfg.WithEndpointDiscovery(*envCfg.EnableEndpointDiscovery) + } else if envCfg.EnableSharedConfig && sharedCfg.EnableEndpointDiscovery != nil { + cfg.WithEndpointDiscovery(*sharedCfg.EnableEndpointDiscovery) + } + } + + // Configure credentials if not already set by the user when creating the + // Session. + if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { + creds, err := resolveCredentials(cfg, envCfg, sharedCfg, handlers, sessOpts) + if err != nil { + return err + } + cfg.Credentials = creds + } + + return nil +} + +func initHandlers(s *Session) { + // Add the Validate parameter handler if it is not disabled. + s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) + if !aws.BoolValue(s.Config.DisableParamValidation) { + s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler) + } +} + +// Copy creates and returns a copy of the current Session, coping the config +// and handlers. If any additional configs are provided they will be merged +// on top of the Session's copied config. +// +// // Create a copy of the current Session, configured for the us-west-2 region. +// sess.Copy(&aws.Config{Region: aws.String("us-west-2")}) +func (s *Session) Copy(cfgs ...*aws.Config) *Session { + newSession := &Session{ + Config: s.Config.Copy(cfgs...), + Handlers: s.Handlers.Copy(), + } + + initHandlers(newSession) + + return newSession +} + +// ClientConfig satisfies the client.ConfigProvider interface and is used to +// configure the service client instances. Passing the Session to the service +// client's constructor (New) will use this method to configure the client. +func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config { + // Backwards compatibility, the error will be eaten if user calls ClientConfig + // directly. All SDK services will use ClientconfigWithError. + cfg, _ := s.clientConfigWithErr(serviceName, cfgs...) + + return cfg +} + +func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) { + s = s.Copy(cfgs...) + + var resolved endpoints.ResolvedEndpoint + var err error + + region := aws.StringValue(s.Config.Region) + + if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 { + resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL)) + resolved.SigningRegion = region + } else { + resolved, err = s.Config.EndpointResolver.EndpointFor( + serviceName, region, + func(opt *endpoints.Options) { + opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL) + opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack) + + // Support the condition where the service is modeled but its + // endpoint metadata is not available. + opt.ResolveUnknownService = true + }, + ) + } + + return client.Config{ + Config: s.Config, + Handlers: s.Handlers, + Endpoint: resolved.URL, + SigningRegion: resolved.SigningRegion, + SigningNameDerived: resolved.SigningNameDerived, + SigningName: resolved.SigningName, + }, err +} + +// ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception +// that the EndpointResolver will not be used to resolve the endpoint. The only +// endpoint set must come from the aws.Config.Endpoint field. +func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Config { + s = s.Copy(cfgs...) + + var resolved endpoints.ResolvedEndpoint + + region := aws.StringValue(s.Config.Region) + + if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 { + resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL)) + resolved.SigningRegion = region + } + + return client.Config{ + Config: s.Config, + Handlers: s.Handlers, + Endpoint: resolved.URL, + SigningRegion: resolved.SigningRegion, + SigningNameDerived: resolved.SigningNameDerived, + SigningName: resolved.SigningName, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go new file mode 100644 index 000000000..5170b4982 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go @@ -0,0 +1,466 @@ +package session + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/internal/ini" +) + +const ( + // Static Credentials group + accessKeyIDKey = `aws_access_key_id` // group required + secretAccessKey = `aws_secret_access_key` // group required + sessionTokenKey = `aws_session_token` // optional + + // Assume Role Credentials group + roleArnKey = `role_arn` // group required + sourceProfileKey = `source_profile` // group required (or credential_source) + credentialSourceKey = `credential_source` // group required (or source_profile) + externalIDKey = `external_id` // optional + mfaSerialKey = `mfa_serial` // optional + roleSessionNameKey = `role_session_name` // optional + + // Additional Config fields + regionKey = `region` + + // endpoint discovery group + enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional + + // External Credential Process + credentialProcessKey = `credential_process` // optional + + // Web Identity Token File + webIdentityTokenFileKey = `web_identity_token_file` // optional + + // DefaultSharedConfigProfile is the default profile to be used when + // loading configuration from the config files if another profile name + // is not provided. + DefaultSharedConfigProfile = `default` +) + +// sharedConfig represents the configuration fields of the SDK config files. +type sharedConfig struct { + // Credentials values from the config file. Both aws_access_key_id and + // aws_secret_access_key must be provided together in the same file to be + // considered valid. The values will be ignored if not a complete group. + // aws_session_token is an optional field that can be provided if both of + // the other two fields are also provided. + // + // aws_access_key_id + // aws_secret_access_key + // aws_session_token + Creds credentials.Value + + CredentialSource string + CredentialProcess string + WebIdentityTokenFile string + + RoleARN string + RoleSessionName string + ExternalID string + MFASerial string + + SourceProfileName string + SourceProfile *sharedConfig + + // Region is the region the SDK should use for looking up AWS service + // endpoints and signing requests. + // + // region + Region string + + // EnableEndpointDiscovery can be enabled in the shared config by setting + // endpoint_discovery_enabled to true + // + // endpoint_discovery_enabled = true + EnableEndpointDiscovery *bool +} + +type sharedConfigFile struct { + Filename string + IniData ini.Sections +} + +// loadSharedConfig retrieves the configuration from the list of files using +// the profile provided. The order the files are listed will determine +// precedence. Values in subsequent files will overwrite values defined in +// earlier files. +// +// For example, given two files A and B. Both define credentials. If the order +// of the files are A then B, B's credential values will be used instead of +// A's. +// +// See sharedConfig.setFromFile for information how the config files +// will be loaded. +func loadSharedConfig(profile string, filenames []string, exOpts bool) (sharedConfig, error) { + if len(profile) == 0 { + profile = DefaultSharedConfigProfile + } + + files, err := loadSharedConfigIniFiles(filenames) + if err != nil { + return sharedConfig{}, err + } + + cfg := sharedConfig{} + profiles := map[string]struct{}{} + if err = cfg.setFromIniFiles(profiles, profile, files, exOpts); err != nil { + return sharedConfig{}, err + } + + return cfg, nil +} + +func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) { + files := make([]sharedConfigFile, 0, len(filenames)) + + for _, filename := range filenames { + sections, err := ini.OpenFile(filename) + if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ini.ErrCodeUnableToReadFile { + // Skip files which can't be opened and read for whatever reason + continue + } else if err != nil { + return nil, SharedConfigLoadError{Filename: filename, Err: err} + } + + files = append(files, sharedConfigFile{ + Filename: filename, IniData: sections, + }) + } + + return files, nil +} + +func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile string, files []sharedConfigFile, exOpts bool) error { + // Trim files from the list that don't exist. + var skippedFiles int + var profileNotFoundErr error + for _, f := range files { + if err := cfg.setFromIniFile(profile, f, exOpts); err != nil { + if _, ok := err.(SharedConfigProfileNotExistsError); ok { + // Ignore profiles not defined in individual files. + profileNotFoundErr = err + skippedFiles++ + continue + } + return err + } + } + if skippedFiles == len(files) { + // If all files were skipped because the profile is not found, return + // the original profile not found error. + return profileNotFoundErr + } + + if _, ok := profiles[profile]; ok { + // if this is the second instance of the profile the Assume Role + // options must be cleared because they are only valid for the + // first reference of a profile. The self linked instance of the + // profile only have credential provider options. + cfg.clearAssumeRoleOptions() + } else { + // First time a profile has been seen, It must either be a assume role + // or credentials. Assert if the credential type requires a role ARN, + // the ARN is also set. + if err := cfg.validateCredentialsRequireARN(profile); err != nil { + return err + } + } + profiles[profile] = struct{}{} + + if err := cfg.validateCredentialType(); err != nil { + return err + } + + // Link source profiles for assume roles + if len(cfg.SourceProfileName) != 0 { + // Linked profile via source_profile ignore credential provider + // options, the source profile must provide the credentials. + cfg.clearCredentialOptions() + + srcCfg := &sharedConfig{} + err := srcCfg.setFromIniFiles(profiles, cfg.SourceProfileName, files, exOpts) + if err != nil { + // SourceProfile that doesn't exist is an error in configuration. + if _, ok := err.(SharedConfigProfileNotExistsError); ok { + err = SharedConfigAssumeRoleError{ + RoleARN: cfg.RoleARN, + SourceProfile: cfg.SourceProfileName, + } + } + return err + } + + if !srcCfg.hasCredentials() { + return SharedConfigAssumeRoleError{ + RoleARN: cfg.RoleARN, + SourceProfile: cfg.SourceProfileName, + } + } + + cfg.SourceProfile = srcCfg + } + + return nil +} + +// setFromFile loads the configuration from the file using the profile +// provided. A sharedConfig pointer type value is used so that multiple config +// file loadings can be chained. +// +// Only loads complete logically grouped values, and will not set fields in cfg +// for incomplete grouped values in the config. Such as credentials. For +// example if a config file only includes aws_access_key_id but no +// aws_secret_access_key the aws_access_key_id will be ignored. +func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, exOpts bool) error { + section, ok := file.IniData.GetSection(profile) + if !ok { + // Fallback to to alternate profile name: profile + section, ok = file.IniData.GetSection(fmt.Sprintf("profile %s", profile)) + if !ok { + return SharedConfigProfileNotExistsError{Profile: profile, Err: nil} + } + } + + if exOpts { + // Assume Role Parameters + updateString(&cfg.RoleARN, section, roleArnKey) + updateString(&cfg.ExternalID, section, externalIDKey) + updateString(&cfg.MFASerial, section, mfaSerialKey) + updateString(&cfg.RoleSessionName, section, roleSessionNameKey) + updateString(&cfg.SourceProfileName, section, sourceProfileKey) + updateString(&cfg.CredentialSource, section, credentialSourceKey) + + updateString(&cfg.Region, section, regionKey) + } + + updateString(&cfg.CredentialProcess, section, credentialProcessKey) + updateString(&cfg.WebIdentityTokenFile, section, webIdentityTokenFileKey) + + // Shared Credentials + creds := credentials.Value{ + AccessKeyID: section.String(accessKeyIDKey), + SecretAccessKey: section.String(secretAccessKey), + SessionToken: section.String(sessionTokenKey), + ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename), + } + if creds.HasKeys() { + cfg.Creds = creds + } + + // Endpoint discovery + if section.Has(enableEndpointDiscoveryKey) { + v := section.Bool(enableEndpointDiscoveryKey) + cfg.EnableEndpointDiscovery = &v + } + + return nil +} + +func (cfg *sharedConfig) validateCredentialsRequireARN(profile string) error { + var credSource string + + switch { + case len(cfg.SourceProfileName) != 0: + credSource = sourceProfileKey + case len(cfg.CredentialSource) != 0: + credSource = credentialSourceKey + case len(cfg.WebIdentityTokenFile) != 0: + credSource = webIdentityTokenFileKey + } + + if len(credSource) != 0 && len(cfg.RoleARN) == 0 { + return CredentialRequiresARNError{ + Type: credSource, + Profile: profile, + } + } + + return nil +} + +func (cfg *sharedConfig) validateCredentialType() error { + // Only one or no credential type can be defined. + if !oneOrNone( + len(cfg.SourceProfileName) != 0, + len(cfg.CredentialSource) != 0, + len(cfg.CredentialProcess) != 0, + len(cfg.WebIdentityTokenFile) != 0, + ) { + return ErrSharedConfigSourceCollision + } + + return nil +} + +func (cfg *sharedConfig) hasCredentials() bool { + switch { + case len(cfg.SourceProfileName) != 0: + case len(cfg.CredentialSource) != 0: + case len(cfg.CredentialProcess) != 0: + case len(cfg.WebIdentityTokenFile) != 0: + case cfg.Creds.HasKeys(): + default: + return false + } + + return true +} + +func (cfg *sharedConfig) clearCredentialOptions() { + cfg.CredentialSource = "" + cfg.CredentialProcess = "" + cfg.WebIdentityTokenFile = "" + cfg.Creds = credentials.Value{} +} + +func (cfg *sharedConfig) clearAssumeRoleOptions() { + cfg.RoleARN = "" + cfg.ExternalID = "" + cfg.MFASerial = "" + cfg.RoleSessionName = "" + cfg.SourceProfileName = "" +} + +func oneOrNone(bs ...bool) bool { + var count int + + for _, b := range bs { + if b { + count++ + if count > 1 { + return false + } + } + } + + return true +} + +// updateString will only update the dst with the value in the section key, key +// is present in the section. +func updateString(dst *string, section ini.Section, key string) { + if !section.Has(key) { + return + } + *dst = section.String(key) +} + +// SharedConfigLoadError is an error for the shared config file failed to load. +type SharedConfigLoadError struct { + Filename string + Err error +} + +// Code is the short id of the error. +func (e SharedConfigLoadError) Code() string { + return "SharedConfigLoadError" +} + +// Message is the description of the error +func (e SharedConfigLoadError) Message() string { + return fmt.Sprintf("failed to load config file, %s", e.Filename) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigLoadError) OrigErr() error { + return e.Err +} + +// Error satisfies the error interface. +func (e SharedConfigLoadError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", e.Err) +} + +// SharedConfigProfileNotExistsError is an error for the shared config when +// the profile was not find in the config file. +type SharedConfigProfileNotExistsError struct { + Profile string + Err error +} + +// Code is the short id of the error. +func (e SharedConfigProfileNotExistsError) Code() string { + return "SharedConfigProfileNotExistsError" +} + +// Message is the description of the error +func (e SharedConfigProfileNotExistsError) Message() string { + return fmt.Sprintf("failed to get profile, %s", e.Profile) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigProfileNotExistsError) OrigErr() error { + return e.Err +} + +// Error satisfies the error interface. +func (e SharedConfigProfileNotExistsError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", e.Err) +} + +// SharedConfigAssumeRoleError is an error for the shared config when the +// profile contains assume role information, but that information is invalid +// or not complete. +type SharedConfigAssumeRoleError struct { + RoleARN string + SourceProfile string +} + +// Code is the short id of the error. +func (e SharedConfigAssumeRoleError) Code() string { + return "SharedConfigAssumeRoleError" +} + +// Message is the description of the error +func (e SharedConfigAssumeRoleError) Message() string { + return fmt.Sprintf( + "failed to load assume role for %s, source profile %s has no shared credentials", + e.RoleARN, e.SourceProfile, + ) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigAssumeRoleError) OrigErr() error { + return nil +} + +// Error satisfies the error interface. +func (e SharedConfigAssumeRoleError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", nil) +} + +// CredentialRequiresARNError provides the error for shared config credentials +// that are incorrectly configured in the shared config or credentials file. +type CredentialRequiresARNError struct { + // type of credentials that were configured. + Type string + + // Profile name the credentials were in. + Profile string +} + +// Code is the short id of the error. +func (e CredentialRequiresARNError) Code() string { + return "CredentialRequiresARNError" +} + +// Message is the description of the error +func (e CredentialRequiresARNError) Message() string { + return fmt.Sprintf( + "credential type %s requires role_arn, profile %s", + e.Type, e.Profile, + ) +} + +// OrigErr is the underlying error that caused the failure. +func (e CredentialRequiresARNError) OrigErr() error { + return nil +} + +// Error satisfies the error interface. +func (e CredentialRequiresARNError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", nil) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go new file mode 100644 index 000000000..244c86da0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go @@ -0,0 +1,82 @@ +package v4 + +import ( + "net/http" + "strings" +) + +// validator houses a set of rule needed for validation of a +// string value +type rules []rule + +// rule interface allows for more flexible rules and just simply +// checks whether or not a value adheres to that rule +type rule interface { + IsValid(value string) bool +} + +// IsValid will iterate through all rules and see if any rules +// apply to the value and supports nested rules +func (r rules) IsValid(value string) bool { + for _, rule := range r { + if rule.IsValid(value) { + return true + } + } + return false +} + +// mapRule generic rule for maps +type mapRule map[string]struct{} + +// IsValid for the map rule satisfies whether it exists in the map +func (m mapRule) IsValid(value string) bool { + _, ok := m[value] + return ok +} + +// whitelist is a generic rule for whitelisting +type whitelist struct { + rule +} + +// IsValid for whitelist checks if the value is within the whitelist +func (w whitelist) IsValid(value string) bool { + return w.rule.IsValid(value) +} + +// blacklist is a generic rule for blacklisting +type blacklist struct { + rule +} + +// IsValid for whitelist checks if the value is within the whitelist +func (b blacklist) IsValid(value string) bool { + return !b.rule.IsValid(value) +} + +type patterns []string + +// IsValid for patterns checks each pattern and returns if a match has +// been found +func (p patterns) IsValid(value string) bool { + for _, pattern := range p { + if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) { + return true + } + } + return false +} + +// inclusiveRules rules allow for rules to depend on one another +type inclusiveRules []rule + +// IsValid will return true if all rules are true +func (r inclusiveRules) IsValid(value string) bool { + for _, rule := range r { + if !rule.IsValid(value) { + return false + } + } + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go new file mode 100644 index 000000000..6aa2ed241 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go @@ -0,0 +1,7 @@ +package v4 + +// WithUnsignedPayload will enable and set the UnsignedPayload field to +// true of the signer. +func WithUnsignedPayload(v4 *Signer) { + v4.UnsignedPayload = true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go new file mode 100644 index 000000000..bd082e9d1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go @@ -0,0 +1,24 @@ +// +build go1.5 + +package v4 + +import ( + "net/url" + "strings" +) + +func getURIPath(u *url.URL) string { + var uri string + + if len(u.Opaque) > 0 { + uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/") + } else { + uri = u.EscapedPath() + } + + if len(uri) == 0 { + uri = "/" + } + + return uri +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go new file mode 100644 index 000000000..8104793aa --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go @@ -0,0 +1,806 @@ +// Package v4 implements signing for AWS V4 signer +// +// Provides request signing for request that need to be signed with +// AWS V4 Signatures. +// +// Standalone Signer +// +// Generally using the signer outside of the SDK should not require any additional +// logic when using Go v1.5 or higher. The signer does this by taking advantage +// of the URL.EscapedPath method. If your request URI requires additional escaping +// you many need to use the URL.Opaque to define what the raw URI should be sent +// to the service as. +// +// The signer will first check the URL.Opaque field, and use its value if set. +// The signer does require the URL.Opaque field to be set in the form of: +// +// "///" +// +// // e.g. +// "//example.com/some/path" +// +// The leading "//" and hostname are required or the URL.Opaque escaping will +// not work correctly. +// +// If URL.Opaque is not set the signer will fallback to the URL.EscapedPath() +// method and using the returned value. If you're using Go v1.4 you must set +// URL.Opaque if the URI path needs escaping. If URL.Opaque is not set with +// Go v1.5 the signer will fallback to URL.Path. +// +// AWS v4 signature validation requires that the canonical string's URI path +// element must be the URI escaped form of the HTTP request's path. +// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html +// +// The Go HTTP client will perform escaping automatically on the request. Some +// of these escaping may cause signature validation errors because the HTTP +// request differs from the URI path or query that the signature was generated. +// https://golang.org/pkg/net/url/#URL.EscapedPath +// +// Because of this, it is recommended that when using the signer outside of the +// SDK that explicitly escaping the request prior to being signed is preferable, +// and will help prevent signature validation errors. This can be done by setting +// the URL.Opaque or URL.RawPath. The SDK will use URL.Opaque first and then +// call URL.EscapedPath() if Opaque is not set. +// +// If signing a request intended for HTTP2 server, and you're using Go 1.6.2 +// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the +// request URL. https://github.com/golang/go/issues/16847 points to a bug in +// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP +// message. URL.Opaque generally will force Go to make requests with absolute URL. +// URL.RawPath does not do this, but RawPath must be a valid escaping of Path +// or url.EscapedPath will ignore the RawPath escaping. +// +// Test `TestStandaloneSign` provides a complete example of using the signer +// outside of the SDK and pre-escaping the URI path. +package v4 + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/sdkio" + "github.com/aws/aws-sdk-go/private/protocol/rest" +) + +const ( + authHeaderPrefix = "AWS4-HMAC-SHA256" + timeFormat = "20060102T150405Z" + shortTimeFormat = "20060102" + + // emptyStringSHA256 is a SHA256 of an empty string + emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` +) + +var ignoredHeaders = rules{ + blacklist{ + mapRule{ + "Authorization": struct{}{}, + "User-Agent": struct{}{}, + "X-Amzn-Trace-Id": struct{}{}, + }, + }, +} + +// requiredSignedHeaders is a whitelist for build canonical headers. +var requiredSignedHeaders = rules{ + whitelist{ + mapRule{ + "Cache-Control": struct{}{}, + "Content-Disposition": struct{}{}, + "Content-Encoding": struct{}{}, + "Content-Language": struct{}{}, + "Content-Md5": struct{}{}, + "Content-Type": struct{}{}, + "Expires": struct{}{}, + "If-Match": struct{}{}, + "If-Modified-Since": struct{}{}, + "If-None-Match": struct{}{}, + "If-Unmodified-Since": struct{}{}, + "Range": struct{}{}, + "X-Amz-Acl": struct{}{}, + "X-Amz-Copy-Source": struct{}{}, + "X-Amz-Copy-Source-If-Match": struct{}{}, + "X-Amz-Copy-Source-If-Modified-Since": struct{}{}, + "X-Amz-Copy-Source-If-None-Match": struct{}{}, + "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{}, + "X-Amz-Copy-Source-Range": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Grant-Full-control": struct{}{}, + "X-Amz-Grant-Read": struct{}{}, + "X-Amz-Grant-Read-Acp": struct{}{}, + "X-Amz-Grant-Write": struct{}{}, + "X-Amz-Grant-Write-Acp": struct{}{}, + "X-Amz-Metadata-Directive": struct{}{}, + "X-Amz-Mfa": struct{}{}, + "X-Amz-Request-Payer": struct{}{}, + "X-Amz-Server-Side-Encryption": struct{}{}, + "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Storage-Class": struct{}{}, + "X-Amz-Tagging": struct{}{}, + "X-Amz-Website-Redirect-Location": struct{}{}, + "X-Amz-Content-Sha256": struct{}{}, + }, + }, + patterns{"X-Amz-Meta-"}, +} + +// allowedHoisting is a whitelist for build query headers. The boolean value +// represents whether or not it is a pattern. +var allowedQueryHoisting = inclusiveRules{ + blacklist{requiredSignedHeaders}, + patterns{"X-Amz-"}, +} + +// Signer applies AWS v4 signing to given request. Use this to sign requests +// that need to be signed with AWS V4 Signatures. +type Signer struct { + // The authentication credentials the request will be signed against. + // This value must be set to sign requests. + Credentials *credentials.Credentials + + // Sets the log level the signer should use when reporting information to + // the logger. If the logger is nil nothing will be logged. See + // aws.LogLevelType for more information on available logging levels + // + // By default nothing will be logged. + Debug aws.LogLevelType + + // The logger loging information will be written to. If there the logger + // is nil, nothing will be logged. + Logger aws.Logger + + // Disables the Signer's moving HTTP header key/value pairs from the HTTP + // request header to the request's query string. This is most commonly used + // with pre-signed requests preventing headers from being added to the + // request's query string. + DisableHeaderHoisting bool + + // Disables the automatic escaping of the URI path of the request for the + // siganture's canonical string's path. For services that do not need additional + // escaping then use this to disable the signer escaping the path. + // + // S3 is an example of a service that does not need additional escaping. + // + // http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html + DisableURIPathEscaping bool + + // Disables the automatical setting of the HTTP request's Body field with the + // io.ReadSeeker passed in to the signer. This is useful if you're using a + // custom wrapper around the body for the io.ReadSeeker and want to preserve + // the Body value on the Request.Body. + // + // This does run the risk of signing a request with a body that will not be + // sent in the request. Need to ensure that the underlying data of the Body + // values are the same. + DisableRequestBodyOverwrite bool + + // currentTimeFn returns the time value which represents the current time. + // This value should only be used for testing. If it is nil the default + // time.Now will be used. + currentTimeFn func() time.Time + + // UnsignedPayload will prevent signing of the payload. This will only + // work for services that have support for this. + UnsignedPayload bool +} + +// NewSigner returns a Signer pointer configured with the credentials and optional +// option values provided. If not options are provided the Signer will use its +// default configuration. +func NewSigner(credentials *credentials.Credentials, options ...func(*Signer)) *Signer { + v4 := &Signer{ + Credentials: credentials, + } + + for _, option := range options { + option(v4) + } + + return v4 +} + +type signingCtx struct { + ServiceName string + Region string + Request *http.Request + Body io.ReadSeeker + Query url.Values + Time time.Time + ExpireTime time.Duration + SignedHeaderVals http.Header + + DisableURIPathEscaping bool + + credValues credentials.Value + isPresign bool + formattedTime string + formattedShortTime string + unsignedPayload bool + + bodyDigest string + signedHeaders string + canonicalHeaders string + canonicalString string + credentialString string + stringToSign string + signature string + authorization string +} + +// Sign signs AWS v4 requests with the provided body, service name, region the +// request is made to, and time the request is signed at. The signTime allows +// you to specify that a request is signed for the future, and cannot be +// used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. Generally for signed requests this value +// is not needed as the full request context will be captured by the http.Request +// value. It is included for reference though. +// +// Sign will set the request's Body to be the `body` parameter passed in. If +// the body is not already an io.ReadCloser, it will be wrapped within one. If +// a `nil` body parameter passed to Sign, the request's Body field will be +// also set to nil. Its important to note that this functionality will not +// change the request's ContentLength of the request. +// +// Sign differs from Presign in that it will sign the request using HTTP +// header values. This type of signing is intended for http.Request values that +// will not be shared, or are shared in a way the header values on the request +// will not be lost. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, 0, false, signTime) +} + +// Presign signs AWS v4 requests with the provided body, service name, region +// the request is made to, and time the request is signed at. The signTime +// allows you to specify that a request is signed for the future, and cannot +// be used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. For presigned requests these headers +// and their values must be included on the HTTP request when it is made. This +// is helpful to know what header values need to be shared with the party the +// presigned request will be distributed to. +// +// Presign differs from Sign in that it will sign the request using query string +// instead of header values. This allows you to share the Presigned Request's +// URL with third parties, or distribute it throughout your system with minimal +// dependencies. +// +// Presign also takes an exp value which is the duration the +// signed request will be valid after the signing time. This is allows you to +// set when the request will expire. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +// +// Presigning a S3 request will not compute the body's SHA256 hash by default. +// This is done due to the general use case for S3 presigned URLs is to share +// PUT/GET capabilities. If you would like to include the body's SHA256 in the +// presigned request's signature you can set the "X-Amz-Content-Sha256" +// HTTP header and that will be included in the request's signature. +func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, exp, true, signTime) +} + +func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) { + currentTimeFn := v4.currentTimeFn + if currentTimeFn == nil { + currentTimeFn = time.Now + } + + ctx := &signingCtx{ + Request: r, + Body: body, + Query: r.URL.Query(), + Time: signTime, + ExpireTime: exp, + isPresign: isPresign, + ServiceName: service, + Region: region, + DisableURIPathEscaping: v4.DisableURIPathEscaping, + unsignedPayload: v4.UnsignedPayload, + } + + for key := range ctx.Query { + sort.Strings(ctx.Query[key]) + } + + if ctx.isRequestSigned() { + ctx.Time = currentTimeFn() + ctx.handlePresignRemoval() + } + + var err error + ctx.credValues, err = v4.Credentials.Get() + if err != nil { + return http.Header{}, err + } + + ctx.sanitizeHostForHeader() + ctx.assignAmzQueryValues() + if err := ctx.build(v4.DisableHeaderHoisting); err != nil { + return nil, err + } + + // If the request is not presigned the body should be attached to it. This + // prevents the confusion of wanting to send a signed request without + // the body the request was signed for attached. + if !(v4.DisableRequestBodyOverwrite || ctx.isPresign) { + var reader io.ReadCloser + if body != nil { + var ok bool + if reader, ok = body.(io.ReadCloser); !ok { + reader = ioutil.NopCloser(body) + } + } + r.Body = reader + } + + if v4.Debug.Matches(aws.LogDebugWithSigning) { + v4.logSigningInfo(ctx) + } + + return ctx.SignedHeaderVals, nil +} + +func (ctx *signingCtx) sanitizeHostForHeader() { + request.SanitizeHostForHeader(ctx.Request) +} + +func (ctx *signingCtx) handlePresignRemoval() { + if !ctx.isPresign { + return + } + + // The credentials have expired for this request. The current signing + // is invalid, and needs to be request because the request will fail. + ctx.removePresign() + + // Update the request's query string to ensure the values stays in + // sync in the case retrieving the new credentials fails. + ctx.Request.URL.RawQuery = ctx.Query.Encode() +} + +func (ctx *signingCtx) assignAmzQueryValues() { + if ctx.isPresign { + ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix) + if ctx.credValues.SessionToken != "" { + ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } else { + ctx.Query.Del("X-Amz-Security-Token") + } + + return + } + + if ctx.credValues.SessionToken != "" { + ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } +} + +// SignRequestHandler is a named request handler the SDK will use to sign +// service client request with using the V4 signature. +var SignRequestHandler = request.NamedHandler{ + Name: "v4.SignRequestHandler", Fn: SignSDKRequest, +} + +// SignSDKRequest signs an AWS request with the V4 signature. This +// request handler should only be used with the SDK's built in service client's +// API operation requests. +// +// This function should not be used on its on its own, but in conjunction with +// an AWS service client's API operation call. To sign a standalone request +// not created by a service client's API operation method use the "Sign" or +// "Presign" functions of the "Signer" type. +// +// If the credentials of the request's config are set to +// credentials.AnonymousCredentials the request will not be signed. +func SignSDKRequest(req *request.Request) { + SignSDKRequestWithCurrentTime(req, time.Now) +} + +// BuildNamedHandler will build a generic handler for signing. +func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler { + return request.NamedHandler{ + Name: name, + Fn: func(req *request.Request) { + SignSDKRequestWithCurrentTime(req, time.Now, opts...) + }, + } +} + +// SignSDKRequestWithCurrentTime will sign the SDK's request using the time +// function passed in. Behaves the same as SignSDKRequest with the exception +// the request is signed with the value returned by the current time function. +func SignSDKRequestWithCurrentTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) { + // If the request does not need to be signed ignore the signing of the + // request if the AnonymousCredentials object is used. + if req.Config.Credentials == credentials.AnonymousCredentials { + return + } + + region := req.ClientInfo.SigningRegion + if region == "" { + region = aws.StringValue(req.Config.Region) + } + + name := req.ClientInfo.SigningName + if name == "" { + name = req.ClientInfo.ServiceName + } + + v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) { + v4.Debug = req.Config.LogLevel.Value() + v4.Logger = req.Config.Logger + v4.DisableHeaderHoisting = req.NotHoist + v4.currentTimeFn = curTimeFn + if name == "s3" { + // S3 service should not have any escaping applied + v4.DisableURIPathEscaping = true + } + // Prevents setting the HTTPRequest's Body. Since the Body could be + // wrapped in a custom io.Closer that we do not want to be stompped + // on top of by the signer. + v4.DisableRequestBodyOverwrite = true + }) + + for _, opt := range opts { + opt(v4) + } + + curTime := curTimeFn() + signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(), + name, region, req.ExpireTime, req.ExpireTime > 0, curTime, + ) + if err != nil { + req.Error = err + req.SignedHeaderVals = nil + return + } + + req.SignedHeaderVals = signedHeaders + req.LastSignedAt = curTime +} + +const logSignInfoMsg = `DEBUG: Request Signature: +---[ CANONICAL STRING ]----------------------------- +%s +---[ STRING TO SIGN ]-------------------------------- +%s%s +-----------------------------------------------------` +const logSignedURLMsg = ` +---[ SIGNED URL ]------------------------------------ +%s` + +func (v4 *Signer) logSigningInfo(ctx *signingCtx) { + signedURLMsg := "" + if ctx.isPresign { + signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String()) + } + msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg) + v4.Logger.Log(msg) +} + +func (ctx *signingCtx) build(disableHeaderHoisting bool) error { + ctx.buildTime() // no depends + ctx.buildCredentialString() // no depends + + if err := ctx.buildBodyDigest(); err != nil { + return err + } + + unsignedHeaders := ctx.Request.Header + if ctx.isPresign { + if !disableHeaderHoisting { + urlValues := url.Values{} + urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends + for k := range urlValues { + ctx.Query[k] = urlValues[k] + } + } + } + + ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) + ctx.buildCanonicalString() // depends on canon headers / signed headers + ctx.buildStringToSign() // depends on canon string + ctx.buildSignature() // depends on string to sign + + if ctx.isPresign { + ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature + } else { + parts := []string{ + authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString, + "SignedHeaders=" + ctx.signedHeaders, + "Signature=" + ctx.signature, + } + ctx.Request.Header.Set("Authorization", strings.Join(parts, ", ")) + } + + return nil +} + +func (ctx *signingCtx) buildTime() { + ctx.formattedTime = ctx.Time.UTC().Format(timeFormat) + ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat) + + if ctx.isPresign { + duration := int64(ctx.ExpireTime / time.Second) + ctx.Query.Set("X-Amz-Date", ctx.formattedTime) + ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10)) + } else { + ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime) + } +} + +func (ctx *signingCtx) buildCredentialString() { + ctx.credentialString = strings.Join([]string{ + ctx.formattedShortTime, + ctx.Region, + ctx.ServiceName, + "aws4_request", + }, "/") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString) + } +} + +func buildQuery(r rule, header http.Header) (url.Values, http.Header) { + query := url.Values{} + unsignedHeaders := http.Header{} + for k, h := range header { + if r.IsValid(k) { + query[k] = h + } else { + unsignedHeaders[k] = h + } + } + + return query, unsignedHeaders +} +func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) { + var headers []string + headers = append(headers, "host") + for k, v := range header { + canonicalKey := http.CanonicalHeaderKey(k) + if !r.IsValid(canonicalKey) { + continue // ignored header + } + if ctx.SignedHeaderVals == nil { + ctx.SignedHeaderVals = make(http.Header) + } + + lowerCaseKey := strings.ToLower(k) + if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok { + // include additional values + ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...) + continue + } + + headers = append(headers, lowerCaseKey) + ctx.SignedHeaderVals[lowerCaseKey] = v + } + sort.Strings(headers) + + ctx.signedHeaders = strings.Join(headers, ";") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders) + } + + headerValues := make([]string, len(headers)) + for i, k := range headers { + if k == "host" { + if ctx.Request.Host != "" { + headerValues[i] = "host:" + ctx.Request.Host + } else { + headerValues[i] = "host:" + ctx.Request.URL.Host + } + } else { + headerValues[i] = k + ":" + + strings.Join(ctx.SignedHeaderVals[k], ",") + } + } + stripExcessSpaces(headerValues) + ctx.canonicalHeaders = strings.Join(headerValues, "\n") +} + +func (ctx *signingCtx) buildCanonicalString() { + ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1) + + uri := getURIPath(ctx.Request.URL) + + if !ctx.DisableURIPathEscaping { + uri = rest.EscapePath(uri, false) + } + + ctx.canonicalString = strings.Join([]string{ + ctx.Request.Method, + uri, + ctx.Request.URL.RawQuery, + ctx.canonicalHeaders + "\n", + ctx.signedHeaders, + ctx.bodyDigest, + }, "\n") +} + +func (ctx *signingCtx) buildStringToSign() { + ctx.stringToSign = strings.Join([]string{ + authHeaderPrefix, + ctx.formattedTime, + ctx.credentialString, + hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))), + }, "\n") +} + +func (ctx *signingCtx) buildSignature() { + secret := ctx.credValues.SecretAccessKey + date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime)) + region := makeHmac(date, []byte(ctx.Region)) + service := makeHmac(region, []byte(ctx.ServiceName)) + credentials := makeHmac(service, []byte("aws4_request")) + signature := makeHmac(credentials, []byte(ctx.stringToSign)) + ctx.signature = hex.EncodeToString(signature) +} + +func (ctx *signingCtx) buildBodyDigest() error { + hash := ctx.Request.Header.Get("X-Amz-Content-Sha256") + if hash == "" { + includeSHA256Header := ctx.unsignedPayload || + ctx.ServiceName == "s3" || + ctx.ServiceName == "glacier" + + s3Presign := ctx.isPresign && ctx.ServiceName == "s3" + + if ctx.unsignedPayload || s3Presign { + hash = "UNSIGNED-PAYLOAD" + includeSHA256Header = !s3Presign + } else if ctx.Body == nil { + hash = emptyStringSHA256 + } else { + if !aws.IsReaderSeekable(ctx.Body) { + return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body) + } + hashBytes, err := makeSha256Reader(ctx.Body) + if err != nil { + return err + } + hash = hex.EncodeToString(hashBytes) + } + + if includeSHA256Header { + ctx.Request.Header.Set("X-Amz-Content-Sha256", hash) + } + } + ctx.bodyDigest = hash + + return nil +} + +// isRequestSigned returns if the request is currently signed or presigned +func (ctx *signingCtx) isRequestSigned() bool { + if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" { + return true + } + if ctx.Request.Header.Get("Authorization") != "" { + return true + } + + return false +} + +// unsign removes signing flags for both signed and presigned requests. +func (ctx *signingCtx) removePresign() { + ctx.Query.Del("X-Amz-Algorithm") + ctx.Query.Del("X-Amz-Signature") + ctx.Query.Del("X-Amz-Security-Token") + ctx.Query.Del("X-Amz-Date") + ctx.Query.Del("X-Amz-Expires") + ctx.Query.Del("X-Amz-Credential") + ctx.Query.Del("X-Amz-SignedHeaders") +} + +func makeHmac(key []byte, data []byte) []byte { + hash := hmac.New(sha256.New, key) + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256(data []byte) []byte { + hash := sha256.New() + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256Reader(reader io.ReadSeeker) (hashBytes []byte, err error) { + hash := sha256.New() + start, err := reader.Seek(0, sdkio.SeekCurrent) + if err != nil { + return nil, err + } + defer func() { + // ensure error is return if unable to seek back to start of payload. + _, err = reader.Seek(start, sdkio.SeekStart) + }() + + // Use CopyN to avoid allocating the 32KB buffer in io.Copy for bodies + // smaller than 32KB. Fall back to io.Copy if we fail to determine the size. + size, err := aws.SeekerLen(reader) + if err != nil { + io.Copy(hash, reader) + } else { + io.CopyN(hash, reader, size) + } + + return hash.Sum(nil), nil +} + +const doubleSpace = " " + +// stripExcessSpaces will rewrite the passed in slice's string values to not +// contain multiple side-by-side spaces. +func stripExcessSpaces(vals []string) { + var j, k, l, m, spaces int + for i, str := range vals { + // Trim trailing spaces + for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- { + } + + // Trim leading spaces + for k = 0; k < j && str[k] == ' '; k++ { + } + str = str[k : j+1] + + // Strip multiple spaces. + j = strings.Index(str, doubleSpace) + if j < 0 { + vals[i] = str + continue + } + + buf := []byte(str) + for k, m, l = j, j, len(buf); k < l; k++ { + if buf[k] == ' ' { + if spaces == 0 { + // First space. + buf[m] = buf[k] + m++ + } + spaces++ + } else { + // End of multiple spaces. + spaces = 0 + buf[m] = buf[k] + m++ + } + } + + vals[i] = string(buf[:m]) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/types.go b/vendor/github.com/aws/aws-sdk-go/aws/types.go new file mode 100644 index 000000000..455091540 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/types.go @@ -0,0 +1,207 @@ +package aws + +import ( + "io" + "sync" + + "github.com/aws/aws-sdk-go/internal/sdkio" +) + +// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Allows the +// SDK to accept an io.Reader that is not also an io.Seeker for unsigned +// streaming payload API operations. +// +// A ReadSeekCloser wrapping an nonseekable io.Reader used in an API +// operation's input will prevent that operation being retried in the case of +// network errors, and cause operation requests to fail if the operation +// requires payload signing. +// +// Note: If using With S3 PutObject to stream an object upload The SDK's S3 +// Upload manager (s3manager.Uploader) provides support for streaming with the +// ability to retry network errors. +func ReadSeekCloser(r io.Reader) ReaderSeekerCloser { + return ReaderSeekerCloser{r} +} + +// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and +// io.Closer interfaces to the underlying object if they are available. +type ReaderSeekerCloser struct { + r io.Reader +} + +// IsReaderSeekable returns if the underlying reader type can be seeked. A +// io.Reader might not actually be seekable if it is the ReaderSeekerCloser +// type. +func IsReaderSeekable(r io.Reader) bool { + switch v := r.(type) { + case ReaderSeekerCloser: + return v.IsSeeker() + case *ReaderSeekerCloser: + return v.IsSeeker() + case io.ReadSeeker: + return true + default: + return false + } +} + +// Read reads from the reader up to size of p. The number of bytes read, and +// error if it occurred will be returned. +// +// If the reader is not an io.Reader zero bytes read, and nil error will be +// returned. +// +// Performs the same functionality as io.Reader Read +func (r ReaderSeekerCloser) Read(p []byte) (int, error) { + switch t := r.r.(type) { + case io.Reader: + return t.Read(p) + } + return 0, nil +} + +// Seek sets the offset for the next Read to offset, interpreted according to +// whence: 0 means relative to the origin of the file, 1 means relative to the +// current offset, and 2 means relative to the end. Seek returns the new offset +// and an error, if any. +// +// If the ReaderSeekerCloser is not an io.Seeker nothing will be done. +func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) { + switch t := r.r.(type) { + case io.Seeker: + return t.Seek(offset, whence) + } + return int64(0), nil +} + +// IsSeeker returns if the underlying reader is also a seeker. +func (r ReaderSeekerCloser) IsSeeker() bool { + _, ok := r.r.(io.Seeker) + return ok +} + +// HasLen returns the length of the underlying reader if the value implements +// the Len() int method. +func (r ReaderSeekerCloser) HasLen() (int, bool) { + type lenner interface { + Len() int + } + + if lr, ok := r.r.(lenner); ok { + return lr.Len(), true + } + + return 0, false +} + +// GetLen returns the length of the bytes remaining in the underlying reader. +// Checks first for Len(), then io.Seeker to determine the size of the +// underlying reader. +// +// Will return -1 if the length cannot be determined. +func (r ReaderSeekerCloser) GetLen() (int64, error) { + if l, ok := r.HasLen(); ok { + return int64(l), nil + } + + if s, ok := r.r.(io.Seeker); ok { + return seekerLen(s) + } + + return -1, nil +} + +// SeekerLen attempts to get the number of bytes remaining at the seeker's +// current position. Returns the number of bytes remaining or error. +func SeekerLen(s io.Seeker) (int64, error) { + // Determine if the seeker is actually seekable. ReaderSeekerCloser + // hides the fact that a io.Readers might not actually be seekable. + switch v := s.(type) { + case ReaderSeekerCloser: + return v.GetLen() + case *ReaderSeekerCloser: + return v.GetLen() + } + + return seekerLen(s) +} + +func seekerLen(s io.Seeker) (int64, error) { + curOffset, err := s.Seek(0, sdkio.SeekCurrent) + if err != nil { + return 0, err + } + + endOffset, err := s.Seek(0, sdkio.SeekEnd) + if err != nil { + return 0, err + } + + _, err = s.Seek(curOffset, sdkio.SeekStart) + if err != nil { + return 0, err + } + + return endOffset - curOffset, nil +} + +// Close closes the ReaderSeekerCloser. +// +// If the ReaderSeekerCloser is not an io.Closer nothing will be done. +func (r ReaderSeekerCloser) Close() error { + switch t := r.r.(type) { + case io.Closer: + return t.Close() + } + return nil +} + +// A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface +// Can be used with the s3manager.Downloader to download content to a buffer +// in memory. Safe to use concurrently. +type WriteAtBuffer struct { + buf []byte + m sync.Mutex + + // GrowthCoeff defines the growth rate of the internal buffer. By + // default, the growth rate is 1, where expanding the internal + // buffer will allocate only enough capacity to fit the new expected + // length. + GrowthCoeff float64 +} + +// NewWriteAtBuffer creates a WriteAtBuffer with an internal buffer +// provided by buf. +func NewWriteAtBuffer(buf []byte) *WriteAtBuffer { + return &WriteAtBuffer{buf: buf} +} + +// WriteAt writes a slice of bytes to a buffer starting at the position provided +// The number of bytes written will be returned, or error. Can overwrite previous +// written slices if the write ats overlap. +func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) { + pLen := len(p) + expLen := pos + int64(pLen) + b.m.Lock() + defer b.m.Unlock() + if int64(len(b.buf)) < expLen { + if int64(cap(b.buf)) < expLen { + if b.GrowthCoeff < 1 { + b.GrowthCoeff = 1 + } + newBuf := make([]byte, expLen, int64(b.GrowthCoeff*float64(expLen))) + copy(newBuf, b.buf) + b.buf = newBuf + } + b.buf = b.buf[:expLen] + } + copy(b.buf[pos:], p) + return pLen, nil +} + +// Bytes returns a slice of bytes written to the buffer. +func (b *WriteAtBuffer) Bytes() []byte { + b.m.Lock() + defer b.m.Unlock() + return b.buf +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/url.go b/vendor/github.com/aws/aws-sdk-go/aws/url.go new file mode 100644 index 000000000..6192b2455 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/url.go @@ -0,0 +1,12 @@ +// +build go1.8 + +package aws + +import "net/url" + +// URLHostname will extract the Hostname without port from the URL value. +// +// Wrapper of net/url#URL.Hostname for backwards Go version compatibility. +func URLHostname(url *url.URL) string { + return url.Hostname() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go new file mode 100644 index 000000000..0210d2720 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go @@ -0,0 +1,29 @@ +// +build !go1.8 + +package aws + +import ( + "net/url" + "strings" +) + +// URLHostname will extract the Hostname without port from the URL value. +// +// Copy of Go 1.8's net/url#URL.Hostname functionality. +func URLHostname(url *url.URL) string { + return stripPort(url.Host) + +} + +// stripPort is copy of Go 1.8 url#URL.Hostname functionality. +// https://golang.org/src/net/url/url.go +func stripPort(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return hostport + } + if i := strings.IndexByte(hostport, ']'); i != -1 { + return strings.TrimPrefix(hostport[:i], "[") + } + return hostport[:colon] +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go new file mode 100644 index 000000000..75501aa53 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -0,0 +1,8 @@ +// Package aws provides core functionality for making requests to AWS services. +package aws + +// SDKName is the name of this AWS SDK +const SDKName = "aws-sdk-go" + +// SDKVersion is the version of this SDK +const SDKVersion = "1.23.0" diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go new file mode 100644 index 000000000..e83a99886 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go @@ -0,0 +1,120 @@ +package ini + +// ASTKind represents different states in the parse table +// and the type of AST that is being constructed +type ASTKind int + +// ASTKind* is used in the parse table to transition between +// the different states +const ( + ASTKindNone = ASTKind(iota) + ASTKindStart + ASTKindExpr + ASTKindEqualExpr + ASTKindStatement + ASTKindSkipStatement + ASTKindExprStatement + ASTKindSectionStatement + ASTKindNestedSectionStatement + ASTKindCompletedNestedSectionStatement + ASTKindCommentStatement + ASTKindCompletedSectionStatement +) + +func (k ASTKind) String() string { + switch k { + case ASTKindNone: + return "none" + case ASTKindStart: + return "start" + case ASTKindExpr: + return "expr" + case ASTKindStatement: + return "stmt" + case ASTKindSectionStatement: + return "section_stmt" + case ASTKindExprStatement: + return "expr_stmt" + case ASTKindCommentStatement: + return "comment" + case ASTKindNestedSectionStatement: + return "nested_section_stmt" + case ASTKindCompletedSectionStatement: + return "completed_stmt" + case ASTKindSkipStatement: + return "skip" + default: + return "" + } +} + +// AST interface allows us to determine what kind of node we +// are on and casting may not need to be necessary. +// +// The root is always the first node in Children +type AST struct { + Kind ASTKind + Root Token + RootToken bool + Children []AST +} + +func newAST(kind ASTKind, root AST, children ...AST) AST { + return AST{ + Kind: kind, + Children: append([]AST{root}, children...), + } +} + +func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST { + return AST{ + Kind: kind, + Root: root, + RootToken: true, + Children: children, + } +} + +// AppendChild will append to the list of children an AST has. +func (a *AST) AppendChild(child AST) { + a.Children = append(a.Children, child) +} + +// GetRoot will return the root AST which can be the first entry +// in the children list or a token. +func (a *AST) GetRoot() AST { + if a.RootToken { + return *a + } + + if len(a.Children) == 0 { + return AST{} + } + + return a.Children[0] +} + +// GetChildren will return the current AST's list of children +func (a *AST) GetChildren() []AST { + if len(a.Children) == 0 { + return []AST{} + } + + if a.RootToken { + return a.Children + } + + return a.Children[1:] +} + +// SetChildren will set and override all children of the AST. +func (a *AST) SetChildren(children []AST) { + if a.RootToken { + a.Children = children + } else { + a.Children = append(a.Children[:1], children...) + } +} + +// Start is used to indicate the starting state of the parse table. +var Start = newAST(ASTKindStart, AST{}) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go new file mode 100644 index 000000000..0895d53cb --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go @@ -0,0 +1,11 @@ +package ini + +var commaRunes = []rune(",") + +func isComma(b rune) bool { + return b == ',' +} + +func newCommaToken() Token { + return newToken(TokenComma, commaRunes, NoneType) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go new file mode 100644 index 000000000..0b76999ba --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go @@ -0,0 +1,35 @@ +package ini + +// isComment will return whether or not the next byte(s) is a +// comment. +func isComment(b []rune) bool { + if len(b) == 0 { + return false + } + + switch b[0] { + case ';': + return true + case '#': + return true + } + + return false +} + +// newCommentToken will create a comment token and +// return how many bytes were read. +func newCommentToken(b []rune) (Token, int, error) { + i := 0 + for ; i < len(b); i++ { + if b[i] == '\n' { + break + } + + if len(b)-i > 2 && b[i] == '\r' && b[i+1] == '\n' { + break + } + } + + return newToken(TokenComment, b[:i], NoneType), i, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go new file mode 100644 index 000000000..25ce0fe13 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go @@ -0,0 +1,29 @@ +// Package ini is an LL(1) parser for configuration files. +// +// Example: +// sections, err := ini.OpenFile("/path/to/file") +// if err != nil { +// panic(err) +// } +// +// profile := "foo" +// section, ok := sections.GetSection(profile) +// if !ok { +// fmt.Printf("section %q could not be found", profile) +// } +// +// Below is the BNF that describes this parser +// Grammar: +// stmt -> value stmt' +// stmt' -> epsilon | op stmt +// value -> number | string | boolean | quoted_string +// +// section -> [ section' +// section' -> value section_close +// section_close -> ] +// +// SkipState will skip (NL WS)+ +// +// comment -> # comment' | ; comment' +// comment' -> epsilon | value +package ini diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go new file mode 100644 index 000000000..04345a54c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go @@ -0,0 +1,4 @@ +package ini + +// emptyToken is used to satisfy the Token interface +var emptyToken = newToken(TokenNone, []rune{}, NoneType) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go new file mode 100644 index 000000000..91ba2a59d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go @@ -0,0 +1,24 @@ +package ini + +// newExpression will return an expression AST. +// Expr represents an expression +// +// grammar: +// expr -> string | number +func newExpression(tok Token) AST { + return newASTWithRootToken(ASTKindExpr, tok) +} + +func newEqualExpr(left AST, tok Token) AST { + return newASTWithRootToken(ASTKindEqualExpr, tok, left) +} + +// EqualExprKey will return a LHS value in the equal expr +func EqualExprKey(ast AST) string { + children := ast.GetChildren() + if len(children) == 0 || ast.Kind != ASTKindEqualExpr { + return "" + } + + return string(children[0].Root.Raw()) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go new file mode 100644 index 000000000..8d462f77e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go @@ -0,0 +1,17 @@ +// +build gofuzz + +package ini + +import ( + "bytes" +) + +func Fuzz(data []byte) int { + b := bytes.NewReader(data) + + if _, err := Parse(b); err != nil { + return 0 + } + + return 1 +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go new file mode 100644 index 000000000..3b0ca7afe --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go @@ -0,0 +1,51 @@ +package ini + +import ( + "io" + "os" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +// OpenFile takes a path to a given file, and will open and parse +// that file. +func OpenFile(path string) (Sections, error) { + f, err := os.Open(path) + if err != nil { + return Sections{}, awserr.New(ErrCodeUnableToReadFile, "unable to open file", err) + } + defer f.Close() + + return Parse(f) +} + +// Parse will parse the given file using the shared config +// visitor. +func Parse(f io.Reader) (Sections, error) { + tree, err := ParseAST(f) + if err != nil { + return Sections{}, err + } + + v := NewDefaultVisitor() + if err = Walk(tree, v); err != nil { + return Sections{}, err + } + + return v.Sections, nil +} + +// ParseBytes will parse the given bytes and return the parsed sections. +func ParseBytes(b []byte) (Sections, error) { + tree, err := ParseASTBytes(b) + if err != nil { + return Sections{}, err + } + + v := NewDefaultVisitor() + if err = Walk(tree, v); err != nil { + return Sections{}, err + } + + return v.Sections, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go new file mode 100644 index 000000000..582c024ad --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go @@ -0,0 +1,165 @@ +package ini + +import ( + "bytes" + "io" + "io/ioutil" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +const ( + // ErrCodeUnableToReadFile is used when a file is failed to be + // opened or read from. + ErrCodeUnableToReadFile = "FailedRead" +) + +// TokenType represents the various different tokens types +type TokenType int + +func (t TokenType) String() string { + switch t { + case TokenNone: + return "none" + case TokenLit: + return "literal" + case TokenSep: + return "sep" + case TokenOp: + return "op" + case TokenWS: + return "ws" + case TokenNL: + return "newline" + case TokenComment: + return "comment" + case TokenComma: + return "comma" + default: + return "" + } +} + +// TokenType enums +const ( + TokenNone = TokenType(iota) + TokenLit + TokenSep + TokenComma + TokenOp + TokenWS + TokenNL + TokenComment +) + +type iniLexer struct{} + +// Tokenize will return a list of tokens during lexical analysis of the +// io.Reader. +func (l *iniLexer) Tokenize(r io.Reader) ([]Token, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, awserr.New(ErrCodeUnableToReadFile, "unable to read file", err) + } + + return l.tokenize(b) +} + +func (l *iniLexer) tokenize(b []byte) ([]Token, error) { + runes := bytes.Runes(b) + var err error + n := 0 + tokenAmount := countTokens(runes) + tokens := make([]Token, tokenAmount) + count := 0 + + for len(runes) > 0 && count < tokenAmount { + switch { + case isWhitespace(runes[0]): + tokens[count], n, err = newWSToken(runes) + case isComma(runes[0]): + tokens[count], n = newCommaToken(), 1 + case isComment(runes): + tokens[count], n, err = newCommentToken(runes) + case isNewline(runes): + tokens[count], n, err = newNewlineToken(runes) + case isSep(runes): + tokens[count], n, err = newSepToken(runes) + case isOp(runes): + tokens[count], n, err = newOpToken(runes) + default: + tokens[count], n, err = newLitToken(runes) + } + + if err != nil { + return nil, err + } + + count++ + + runes = runes[n:] + } + + return tokens[:count], nil +} + +func countTokens(runes []rune) int { + count, n := 0, 0 + var err error + + for len(runes) > 0 { + switch { + case isWhitespace(runes[0]): + _, n, err = newWSToken(runes) + case isComma(runes[0]): + _, n = newCommaToken(), 1 + case isComment(runes): + _, n, err = newCommentToken(runes) + case isNewline(runes): + _, n, err = newNewlineToken(runes) + case isSep(runes): + _, n, err = newSepToken(runes) + case isOp(runes): + _, n, err = newOpToken(runes) + default: + _, n, err = newLitToken(runes) + } + + if err != nil { + return 0 + } + + count++ + runes = runes[n:] + } + + return count + 1 +} + +// Token indicates a metadata about a given value. +type Token struct { + t TokenType + ValueType ValueType + base int + raw []rune +} + +var emptyValue = Value{} + +func newToken(t TokenType, raw []rune, v ValueType) Token { + return Token{ + t: t, + raw: raw, + ValueType: v, + } +} + +// Raw return the raw runes that were consumed +func (tok Token) Raw() []rune { + return tok.raw +} + +// Type returns the token type +func (tok Token) Type() TokenType { + return tok.t +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go new file mode 100644 index 000000000..e56dcee2f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go @@ -0,0 +1,349 @@ +package ini + +import ( + "fmt" + "io" +) + +// State enums for the parse table +const ( + InvalidState = iota + // stmt -> value stmt' + StatementState + // stmt' -> MarkComplete | op stmt + StatementPrimeState + // value -> number | string | boolean | quoted_string + ValueState + // section -> [ section' + OpenScopeState + // section' -> value section_close + SectionState + // section_close -> ] + CloseScopeState + // SkipState will skip (NL WS)+ + SkipState + // SkipTokenState will skip any token and push the previous + // state onto the stack. + SkipTokenState + // comment -> # comment' | ; comment' + // comment' -> MarkComplete | value + CommentState + // MarkComplete state will complete statements and move that + // to the completed AST list + MarkCompleteState + // TerminalState signifies that the tokens have been fully parsed + TerminalState +) + +// parseTable is a state machine to dictate the grammar above. +var parseTable = map[ASTKind]map[TokenType]int{ + ASTKindStart: map[TokenType]int{ + TokenLit: StatementState, + TokenSep: OpenScopeState, + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenComment: CommentState, + TokenNone: TerminalState, + }, + ASTKindCommentStatement: map[TokenType]int{ + TokenLit: StatementState, + TokenSep: OpenScopeState, + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenComment: CommentState, + TokenNone: MarkCompleteState, + }, + ASTKindExpr: map[TokenType]int{ + TokenOp: StatementPrimeState, + TokenLit: ValueState, + TokenSep: OpenScopeState, + TokenWS: ValueState, + TokenNL: SkipState, + TokenComment: CommentState, + TokenNone: MarkCompleteState, + }, + ASTKindEqualExpr: map[TokenType]int{ + TokenLit: ValueState, + TokenWS: SkipTokenState, + TokenNL: SkipState, + }, + ASTKindStatement: map[TokenType]int{ + TokenLit: SectionState, + TokenSep: CloseScopeState, + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenComment: CommentState, + TokenNone: MarkCompleteState, + }, + ASTKindExprStatement: map[TokenType]int{ + TokenLit: ValueState, + TokenSep: OpenScopeState, + TokenOp: ValueState, + TokenWS: ValueState, + TokenNL: MarkCompleteState, + TokenComment: CommentState, + TokenNone: TerminalState, + TokenComma: SkipState, + }, + ASTKindSectionStatement: map[TokenType]int{ + TokenLit: SectionState, + TokenOp: SectionState, + TokenSep: CloseScopeState, + TokenWS: SectionState, + TokenNL: SkipTokenState, + }, + ASTKindCompletedSectionStatement: map[TokenType]int{ + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenLit: StatementState, + TokenSep: OpenScopeState, + TokenComment: CommentState, + TokenNone: MarkCompleteState, + }, + ASTKindSkipStatement: map[TokenType]int{ + TokenLit: StatementState, + TokenSep: OpenScopeState, + TokenWS: SkipTokenState, + TokenNL: SkipTokenState, + TokenComment: CommentState, + TokenNone: TerminalState, + }, +} + +// ParseAST will parse input from an io.Reader using +// an LL(1) parser. +func ParseAST(r io.Reader) ([]AST, error) { + lexer := iniLexer{} + tokens, err := lexer.Tokenize(r) + if err != nil { + return []AST{}, err + } + + return parse(tokens) +} + +// ParseASTBytes will parse input from a byte slice using +// an LL(1) parser. +func ParseASTBytes(b []byte) ([]AST, error) { + lexer := iniLexer{} + tokens, err := lexer.tokenize(b) + if err != nil { + return []AST{}, err + } + + return parse(tokens) +} + +func parse(tokens []Token) ([]AST, error) { + start := Start + stack := newParseStack(3, len(tokens)) + + stack.Push(start) + s := newSkipper() + +loop: + for stack.Len() > 0 { + k := stack.Pop() + + var tok Token + if len(tokens) == 0 { + // this occurs when all the tokens have been processed + // but reduction of what's left on the stack needs to + // occur. + tok = emptyToken + } else { + tok = tokens[0] + } + + step := parseTable[k.Kind][tok.Type()] + if s.ShouldSkip(tok) { + // being in a skip state with no tokens will break out of + // the parse loop since there is nothing left to process. + if len(tokens) == 0 { + break loop + } + + step = SkipTokenState + } + + switch step { + case TerminalState: + // Finished parsing. Push what should be the last + // statement to the stack. If there is anything left + // on the stack, an error in parsing has occurred. + if k.Kind != ASTKindStart { + stack.MarkComplete(k) + } + break loop + case SkipTokenState: + // When skipping a token, the previous state was popped off the stack. + // To maintain the correct state, the previous state will be pushed + // onto the stack. + stack.Push(k) + case StatementState: + if k.Kind != ASTKindStart { + stack.MarkComplete(k) + } + expr := newExpression(tok) + stack.Push(expr) + case StatementPrimeState: + if tok.Type() != TokenOp { + stack.MarkComplete(k) + continue + } + + if k.Kind != ASTKindExpr { + return nil, NewParseError( + fmt.Sprintf("invalid expression: expected Expr type, but found %T type", k), + ) + } + + k = trimSpaces(k) + expr := newEqualExpr(k, tok) + stack.Push(expr) + case ValueState: + // ValueState requires the previous state to either be an equal expression + // or an expression statement. + // + // This grammar occurs when the RHS is a number, word, or quoted string. + // equal_expr -> lit op equal_expr' + // equal_expr' -> number | string | quoted_string + // quoted_string -> " quoted_string' + // quoted_string' -> string quoted_string_end + // quoted_string_end -> " + // + // otherwise + // expr_stmt -> equal_expr (expr_stmt')* + // expr_stmt' -> ws S | op S | MarkComplete + // S -> equal_expr' expr_stmt' + switch k.Kind { + case ASTKindEqualExpr: + // assiging a value to some key + k.AppendChild(newExpression(tok)) + stack.Push(newExprStatement(k)) + case ASTKindExpr: + k.Root.raw = append(k.Root.raw, tok.Raw()...) + stack.Push(k) + case ASTKindExprStatement: + root := k.GetRoot() + children := root.GetChildren() + if len(children) == 0 { + return nil, NewParseError( + fmt.Sprintf("invalid expression: AST contains no children %s", k.Kind), + ) + } + + rhs := children[len(children)-1] + + if rhs.Root.ValueType != QuotedStringType { + rhs.Root.ValueType = StringType + rhs.Root.raw = append(rhs.Root.raw, tok.Raw()...) + + } + + children[len(children)-1] = rhs + k.SetChildren(children) + + stack.Push(k) + } + case OpenScopeState: + if !runeCompare(tok.Raw(), openBrace) { + return nil, NewParseError("expected '['") + } + + stmt := newStatement() + stack.Push(stmt) + case CloseScopeState: + if !runeCompare(tok.Raw(), closeBrace) { + return nil, NewParseError("expected ']'") + } + + k = trimSpaces(k) + stack.Push(newCompletedSectionStatement(k)) + case SectionState: + var stmt AST + + switch k.Kind { + case ASTKindStatement: + // If there are multiple literals inside of a scope declaration, + // then the current token's raw value will be appended to the Name. + // + // This handles cases like [ profile default ] + // + // k will represent a SectionStatement with the children representing + // the label of the section + stmt = newSectionStatement(tok) + case ASTKindSectionStatement: + k.Root.raw = append(k.Root.raw, tok.Raw()...) + stmt = k + default: + return nil, NewParseError( + fmt.Sprintf("invalid statement: expected statement: %v", k.Kind), + ) + } + + stack.Push(stmt) + case MarkCompleteState: + if k.Kind != ASTKindStart { + stack.MarkComplete(k) + } + + if stack.Len() == 0 { + stack.Push(start) + } + case SkipState: + stack.Push(newSkipStatement(k)) + s.Skip() + case CommentState: + if k.Kind == ASTKindStart { + stack.Push(k) + } else { + stack.MarkComplete(k) + } + + stmt := newCommentStatement(tok) + stack.Push(stmt) + default: + return nil, NewParseError( + fmt.Sprintf("invalid state with ASTKind %v and TokenType %v", + k, tok.Type())) + } + + if len(tokens) > 0 { + tokens = tokens[1:] + } + } + + // this occurs when a statement has not been completed + if stack.top > 1 { + return nil, NewParseError(fmt.Sprintf("incomplete ini expression")) + } + + // returns a sublist which excludes the start symbol + return stack.List(), nil +} + +// trimSpaces will trim spaces on the left and right hand side of +// the literal. +func trimSpaces(k AST) AST { + // trim left hand side of spaces + for i := 0; i < len(k.Root.raw); i++ { + if !isWhitespace(k.Root.raw[i]) { + break + } + + k.Root.raw = k.Root.raw[1:] + i-- + } + + // trim right hand side of spaces + for i := len(k.Root.raw) - 1; i >= 0; i-- { + if !isWhitespace(k.Root.raw[i]) { + break + } + + k.Root.raw = k.Root.raw[:len(k.Root.raw)-1] + } + + return k +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go new file mode 100644 index 000000000..24df543d3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go @@ -0,0 +1,324 @@ +package ini + +import ( + "fmt" + "strconv" + "strings" +) + +var ( + runesTrue = []rune("true") + runesFalse = []rune("false") +) + +var literalValues = [][]rune{ + runesTrue, + runesFalse, +} + +func isBoolValue(b []rune) bool { + for _, lv := range literalValues { + if isLitValue(lv, b) { + return true + } + } + return false +} + +func isLitValue(want, have []rune) bool { + if len(have) < len(want) { + return false + } + + for i := 0; i < len(want); i++ { + if want[i] != have[i] { + return false + } + } + + return true +} + +// isNumberValue will return whether not the leading characters in +// a byte slice is a number. A number is delimited by whitespace or +// the newline token. +// +// A number is defined to be in a binary, octal, decimal (int | float), hex format, +// or in scientific notation. +func isNumberValue(b []rune) bool { + negativeIndex := 0 + helper := numberHelper{} + needDigit := false + + for i := 0; i < len(b); i++ { + negativeIndex++ + + switch b[i] { + case '-': + if helper.IsNegative() || negativeIndex != 1 { + return false + } + helper.Determine(b[i]) + needDigit = true + continue + case 'e', 'E': + if err := helper.Determine(b[i]); err != nil { + return false + } + negativeIndex = 0 + needDigit = true + continue + case 'b': + if helper.numberFormat == hex { + break + } + fallthrough + case 'o', 'x': + needDigit = true + if i == 0 { + return false + } + + fallthrough + case '.': + if err := helper.Determine(b[i]); err != nil { + return false + } + needDigit = true + continue + } + + if i > 0 && (isNewline(b[i:]) || isWhitespace(b[i])) { + return !needDigit + } + + if !helper.CorrectByte(b[i]) { + return false + } + needDigit = false + } + + return !needDigit +} + +func isValid(b []rune) (bool, int, error) { + if len(b) == 0 { + // TODO: should probably return an error + return false, 0, nil + } + + return isValidRune(b[0]), 1, nil +} + +func isValidRune(r rune) bool { + return r != ':' && r != '=' && r != '[' && r != ']' && r != ' ' && r != '\n' +} + +// ValueType is an enum that will signify what type +// the Value is +type ValueType int + +func (v ValueType) String() string { + switch v { + case NoneType: + return "NONE" + case DecimalType: + return "FLOAT" + case IntegerType: + return "INT" + case StringType: + return "STRING" + case BoolType: + return "BOOL" + } + + return "" +} + +// ValueType enums +const ( + NoneType = ValueType(iota) + DecimalType + IntegerType + StringType + QuotedStringType + BoolType +) + +// Value is a union container +type Value struct { + Type ValueType + raw []rune + + integer int64 + decimal float64 + boolean bool + str string +} + +func newValue(t ValueType, base int, raw []rune) (Value, error) { + v := Value{ + Type: t, + raw: raw, + } + var err error + + switch t { + case DecimalType: + v.decimal, err = strconv.ParseFloat(string(raw), 64) + case IntegerType: + if base != 10 { + raw = raw[2:] + } + + v.integer, err = strconv.ParseInt(string(raw), base, 64) + case StringType: + v.str = string(raw) + case QuotedStringType: + v.str = string(raw[1 : len(raw)-1]) + case BoolType: + v.boolean = runeCompare(v.raw, runesTrue) + } + + // issue 2253 + // + // if the value trying to be parsed is too large, then we will use + // the 'StringType' and raw value instead. + if nerr, ok := err.(*strconv.NumError); ok && nerr.Err == strconv.ErrRange { + v.Type = StringType + v.str = string(raw) + err = nil + } + + return v, err +} + +// Append will append values and change the type to a string +// type. +func (v *Value) Append(tok Token) { + r := tok.Raw() + if v.Type != QuotedStringType { + v.Type = StringType + r = tok.raw[1 : len(tok.raw)-1] + } + if tok.Type() != TokenLit { + v.raw = append(v.raw, tok.Raw()...) + } else { + v.raw = append(v.raw, r...) + } +} + +func (v Value) String() string { + switch v.Type { + case DecimalType: + return fmt.Sprintf("decimal: %f", v.decimal) + case IntegerType: + return fmt.Sprintf("integer: %d", v.integer) + case StringType: + return fmt.Sprintf("string: %s", string(v.raw)) + case QuotedStringType: + return fmt.Sprintf("quoted string: %s", string(v.raw)) + case BoolType: + return fmt.Sprintf("bool: %t", v.boolean) + default: + return "union not set" + } +} + +func newLitToken(b []rune) (Token, int, error) { + n := 0 + var err error + + token := Token{} + if b[0] == '"' { + n, err = getStringValue(b) + if err != nil { + return token, n, err + } + + token = newToken(TokenLit, b[:n], QuotedStringType) + } else if isNumberValue(b) { + var base int + base, n, err = getNumericalValue(b) + if err != nil { + return token, 0, err + } + + value := b[:n] + vType := IntegerType + if contains(value, '.') || hasExponent(value) { + vType = DecimalType + } + token = newToken(TokenLit, value, vType) + token.base = base + } else if isBoolValue(b) { + n, err = getBoolValue(b) + + token = newToken(TokenLit, b[:n], BoolType) + } else { + n, err = getValue(b) + token = newToken(TokenLit, b[:n], StringType) + } + + return token, n, err +} + +// IntValue returns an integer value +func (v Value) IntValue() int64 { + return v.integer +} + +// FloatValue returns a float value +func (v Value) FloatValue() float64 { + return v.decimal +} + +// BoolValue returns a bool value +func (v Value) BoolValue() bool { + return v.boolean +} + +func isTrimmable(r rune) bool { + switch r { + case '\n', ' ': + return true + } + return false +} + +// StringValue returns the string value +func (v Value) StringValue() string { + switch v.Type { + case StringType: + return strings.TrimFunc(string(v.raw), isTrimmable) + case QuotedStringType: + // preserve all characters in the quotes + return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1])) + default: + return strings.TrimFunc(string(v.raw), isTrimmable) + } +} + +func contains(runes []rune, c rune) bool { + for i := 0; i < len(runes); i++ { + if runes[i] == c { + return true + } + } + + return false +} + +func runeCompare(v1 []rune, v2 []rune) bool { + if len(v1) != len(v2) { + return false + } + + for i := 0; i < len(v1); i++ { + if v1[i] != v2[i] { + return false + } + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go new file mode 100644 index 000000000..e52ac399f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go @@ -0,0 +1,30 @@ +package ini + +func isNewline(b []rune) bool { + if len(b) == 0 { + return false + } + + if b[0] == '\n' { + return true + } + + if len(b) < 2 { + return false + } + + return b[0] == '\r' && b[1] == '\n' +} + +func newNewlineToken(b []rune) (Token, int, error) { + i := 1 + if b[0] == '\r' && isNewline(b[1:]) { + i++ + } + + if !isNewline([]rune(b[:i])) { + return emptyToken, 0, NewParseError("invalid new line token") + } + + return newToken(TokenNL, b[:i], NoneType), i, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go new file mode 100644 index 000000000..a45c0bc56 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go @@ -0,0 +1,152 @@ +package ini + +import ( + "bytes" + "fmt" + "strconv" +) + +const ( + none = numberFormat(iota) + binary + octal + decimal + hex + exponent +) + +type numberFormat int + +// numberHelper is used to dictate what format a number is in +// and what to do for negative values. Since -1e-4 is a valid +// number, we cannot just simply check for duplicate negatives. +type numberHelper struct { + numberFormat numberFormat + + negative bool + negativeExponent bool +} + +func (b numberHelper) Exists() bool { + return b.numberFormat != none +} + +func (b numberHelper) IsNegative() bool { + return b.negative || b.negativeExponent +} + +func (b *numberHelper) Determine(c rune) error { + if b.Exists() { + return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c))) + } + + switch c { + case 'b': + b.numberFormat = binary + case 'o': + b.numberFormat = octal + case 'x': + b.numberFormat = hex + case 'e', 'E': + b.numberFormat = exponent + case '-': + if b.numberFormat != exponent { + b.negative = true + } else { + b.negativeExponent = true + } + case '.': + b.numberFormat = decimal + default: + return NewParseError(fmt.Sprintf("invalid number character: %v", string(c))) + } + + return nil +} + +func (b numberHelper) CorrectByte(c rune) bool { + switch { + case b.numberFormat == binary: + if !isBinaryByte(c) { + return false + } + case b.numberFormat == octal: + if !isOctalByte(c) { + return false + } + case b.numberFormat == hex: + if !isHexByte(c) { + return false + } + case b.numberFormat == decimal: + if !isDigit(c) { + return false + } + case b.numberFormat == exponent: + if !isDigit(c) { + return false + } + case b.negativeExponent: + if !isDigit(c) { + return false + } + case b.negative: + if !isDigit(c) { + return false + } + default: + if !isDigit(c) { + return false + } + } + + return true +} + +func (b numberHelper) Base() int { + switch b.numberFormat { + case binary: + return 2 + case octal: + return 8 + case hex: + return 16 + default: + return 10 + } +} + +func (b numberHelper) String() string { + buf := bytes.Buffer{} + i := 0 + + switch b.numberFormat { + case binary: + i++ + buf.WriteString(strconv.Itoa(i) + ": binary format\n") + case octal: + i++ + buf.WriteString(strconv.Itoa(i) + ": octal format\n") + case hex: + i++ + buf.WriteString(strconv.Itoa(i) + ": hex format\n") + case exponent: + i++ + buf.WriteString(strconv.Itoa(i) + ": exponent format\n") + default: + i++ + buf.WriteString(strconv.Itoa(i) + ": integer format\n") + } + + if b.negative { + i++ + buf.WriteString(strconv.Itoa(i) + ": negative format\n") + } + + if b.negativeExponent { + i++ + buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n") + } + + return buf.String() +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go new file mode 100644 index 000000000..8a84c7cbe --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go @@ -0,0 +1,39 @@ +package ini + +import ( + "fmt" +) + +var ( + equalOp = []rune("=") + equalColonOp = []rune(":") +) + +func isOp(b []rune) bool { + if len(b) == 0 { + return false + } + + switch b[0] { + case '=': + return true + case ':': + return true + default: + return false + } +} + +func newOpToken(b []rune) (Token, int, error) { + tok := Token{} + + switch b[0] { + case '=': + tok = newToken(TokenOp, equalOp, NoneType) + case ':': + tok = newToken(TokenOp, equalColonOp, NoneType) + default: + return tok, 0, NewParseError(fmt.Sprintf("unexpected op type, %v", b[0])) + } + return tok, 1, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go new file mode 100644 index 000000000..457287019 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go @@ -0,0 +1,43 @@ +package ini + +import "fmt" + +const ( + // ErrCodeParseError is returned when a parsing error + // has occurred. + ErrCodeParseError = "INIParseError" +) + +// ParseError is an error which is returned during any part of +// the parsing process. +type ParseError struct { + msg string +} + +// NewParseError will return a new ParseError where message +// is the description of the error. +func NewParseError(message string) *ParseError { + return &ParseError{ + msg: message, + } +} + +// Code will return the ErrCodeParseError +func (err *ParseError) Code() string { + return ErrCodeParseError +} + +// Message returns the error's message +func (err *ParseError) Message() string { + return err.msg +} + +// OrigError return nothing since there will never be any +// original error. +func (err *ParseError) OrigError() error { + return nil +} + +func (err *ParseError) Error() string { + return fmt.Sprintf("%s: %s", err.Code(), err.Message()) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go new file mode 100644 index 000000000..7f01cf7c7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go @@ -0,0 +1,60 @@ +package ini + +import ( + "bytes" + "fmt" +) + +// ParseStack is a stack that contains a container, the stack portion, +// and the list which is the list of ASTs that have been successfully +// parsed. +type ParseStack struct { + top int + container []AST + list []AST + index int +} + +func newParseStack(sizeContainer, sizeList int) ParseStack { + return ParseStack{ + container: make([]AST, sizeContainer), + list: make([]AST, sizeList), + } +} + +// Pop will return and truncate the last container element. +func (s *ParseStack) Pop() AST { + s.top-- + return s.container[s.top] +} + +// Push will add the new AST to the container +func (s *ParseStack) Push(ast AST) { + s.container[s.top] = ast + s.top++ +} + +// MarkComplete will append the AST to the list of completed statements +func (s *ParseStack) MarkComplete(ast AST) { + s.list[s.index] = ast + s.index++ +} + +// List will return the completed statements +func (s ParseStack) List() []AST { + return s.list[:s.index] +} + +// Len will return the length of the container +func (s *ParseStack) Len() int { + return s.top +} + +func (s ParseStack) String() string { + buf := bytes.Buffer{} + for i, node := range s.list { + buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node)) + } + + return buf.String() +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go new file mode 100644 index 000000000..f82095ba2 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go @@ -0,0 +1,41 @@ +package ini + +import ( + "fmt" +) + +var ( + emptyRunes = []rune{} +) + +func isSep(b []rune) bool { + if len(b) == 0 { + return false + } + + switch b[0] { + case '[', ']': + return true + default: + return false + } +} + +var ( + openBrace = []rune("[") + closeBrace = []rune("]") +) + +func newSepToken(b []rune) (Token, int, error) { + tok := Token{} + + switch b[0] { + case '[': + tok = newToken(TokenSep, openBrace, NoneType) + case ']': + tok = newToken(TokenSep, closeBrace, NoneType) + default: + return tok, 0, NewParseError(fmt.Sprintf("unexpected sep type, %v", b[0])) + } + return tok, 1, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go new file mode 100644 index 000000000..6bb696447 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go @@ -0,0 +1,45 @@ +package ini + +// skipper is used to skip certain blocks of an ini file. +// Currently skipper is used to skip nested blocks of ini +// files. See example below +// +// [ foo ] +// nested = ; this section will be skipped +// a=b +// c=d +// bar=baz ; this will be included +type skipper struct { + shouldSkip bool + TokenSet bool + prevTok Token +} + +func newSkipper() skipper { + return skipper{ + prevTok: emptyToken, + } +} + +func (s *skipper) ShouldSkip(tok Token) bool { + if s.shouldSkip && + s.prevTok.Type() == TokenNL && + tok.Type() != TokenWS { + + s.Continue() + return false + } + s.prevTok = tok + + return s.shouldSkip +} + +func (s *skipper) Skip() { + s.shouldSkip = true + s.prevTok = emptyToken +} + +func (s *skipper) Continue() { + s.shouldSkip = false + s.prevTok = emptyToken +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go new file mode 100644 index 000000000..18f3fe893 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go @@ -0,0 +1,35 @@ +package ini + +// Statement is an empty AST mostly used for transitioning states. +func newStatement() AST { + return newAST(ASTKindStatement, AST{}) +} + +// SectionStatement represents a section AST +func newSectionStatement(tok Token) AST { + return newASTWithRootToken(ASTKindSectionStatement, tok) +} + +// ExprStatement represents a completed expression AST +func newExprStatement(ast AST) AST { + return newAST(ASTKindExprStatement, ast) +} + +// CommentStatement represents a comment in the ini definition. +// +// grammar: +// comment -> #comment' | ;comment' +// comment' -> epsilon | value +func newCommentStatement(tok Token) AST { + return newAST(ASTKindCommentStatement, newExpression(tok)) +} + +// CompletedSectionStatement represents a completed section +func newCompletedSectionStatement(ast AST) AST { + return newAST(ASTKindCompletedSectionStatement, ast) +} + +// SkipStatement is used to skip whole statements +func newSkipStatement(ast AST) AST { + return newAST(ASTKindSkipStatement, ast) +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go new file mode 100644 index 000000000..305999d29 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go @@ -0,0 +1,284 @@ +package ini + +import ( + "fmt" +) + +// getStringValue will return a quoted string and the amount +// of bytes read +// +// an error will be returned if the string is not properly formatted +func getStringValue(b []rune) (int, error) { + if b[0] != '"' { + return 0, NewParseError("strings must start with '\"'") + } + + endQuote := false + i := 1 + + for ; i < len(b) && !endQuote; i++ { + if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped { + endQuote = true + break + } else if escaped { + /*c, err := getEscapedByte(b[i]) + if err != nil { + return 0, err + } + + b[i-1] = c + b = append(b[:i], b[i+1:]...) + i--*/ + + continue + } + } + + if !endQuote { + return 0, NewParseError("missing '\"' in string value") + } + + return i + 1, nil +} + +// getBoolValue will return a boolean and the amount +// of bytes read +// +// an error will be returned if the boolean is not of a correct +// value +func getBoolValue(b []rune) (int, error) { + if len(b) < 4 { + return 0, NewParseError("invalid boolean value") + } + + n := 0 + for _, lv := range literalValues { + if len(lv) > len(b) { + continue + } + + if isLitValue(lv, b) { + n = len(lv) + } + } + + if n == 0 { + return 0, NewParseError("invalid boolean value") + } + + return n, nil +} + +// getNumericalValue will return a numerical string, the amount +// of bytes read, and the base of the number +// +// an error will be returned if the number is not of a correct +// value +func getNumericalValue(b []rune) (int, int, error) { + if !isDigit(b[0]) { + return 0, 0, NewParseError("invalid digit value") + } + + i := 0 + helper := numberHelper{} + +loop: + for negativeIndex := 0; i < len(b); i++ { + negativeIndex++ + + if !isDigit(b[i]) { + switch b[i] { + case '-': + if helper.IsNegative() || negativeIndex != 1 { + return 0, 0, NewParseError("parse error '-'") + } + + n := getNegativeNumber(b[i:]) + i += (n - 1) + helper.Determine(b[i]) + continue + case '.': + if err := helper.Determine(b[i]); err != nil { + return 0, 0, err + } + case 'e', 'E': + if err := helper.Determine(b[i]); err != nil { + return 0, 0, err + } + + negativeIndex = 0 + case 'b': + if helper.numberFormat == hex { + break + } + fallthrough + case 'o', 'x': + if i == 0 && b[i] != '0' { + return 0, 0, NewParseError("incorrect base format, expected leading '0'") + } + + if i != 1 { + return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i)) + } + + if err := helper.Determine(b[i]); err != nil { + return 0, 0, err + } + default: + if isWhitespace(b[i]) { + break loop + } + + if isNewline(b[i:]) { + break loop + } + + if !(helper.numberFormat == hex && isHexByte(b[i])) { + if i+2 < len(b) && !isNewline(b[i:i+2]) { + return 0, 0, NewParseError("invalid numerical character") + } else if !isNewline([]rune{b[i]}) { + return 0, 0, NewParseError("invalid numerical character") + } + + break loop + } + } + } + } + + return helper.Base(), i, nil +} + +// isDigit will return whether or not something is an integer +func isDigit(b rune) bool { + return b >= '0' && b <= '9' +} + +func hasExponent(v []rune) bool { + return contains(v, 'e') || contains(v, 'E') +} + +func isBinaryByte(b rune) bool { + switch b { + case '0', '1': + return true + default: + return false + } +} + +func isOctalByte(b rune) bool { + switch b { + case '0', '1', '2', '3', '4', '5', '6', '7': + return true + default: + return false + } +} + +func isHexByte(b rune) bool { + if isDigit(b) { + return true + } + return (b >= 'A' && b <= 'F') || + (b >= 'a' && b <= 'f') +} + +func getValue(b []rune) (int, error) { + i := 0 + + for i < len(b) { + if isNewline(b[i:]) { + break + } + + if isOp(b[i:]) { + break + } + + valid, n, err := isValid(b[i:]) + if err != nil { + return 0, err + } + + if !valid { + break + } + + i += n + } + + return i, nil +} + +// getNegativeNumber will return a negative number from a +// byte slice. This will iterate through all characters until +// a non-digit has been found. +func getNegativeNumber(b []rune) int { + if b[0] != '-' { + return 0 + } + + i := 1 + for ; i < len(b); i++ { + if !isDigit(b[i]) { + return i + } + } + + return i +} + +// isEscaped will return whether or not the character is an escaped +// character. +func isEscaped(value []rune, b rune) bool { + if len(value) == 0 { + return false + } + + switch b { + case '\'': // single quote + case '"': // quote + case 'n': // newline + case 't': // tab + case '\\': // backslash + default: + return false + } + + return value[len(value)-1] == '\\' +} + +func getEscapedByte(b rune) (rune, error) { + switch b { + case '\'': // single quote + return '\'', nil + case '"': // quote + return '"', nil + case 'n': // newline + return '\n', nil + case 't': // table + return '\t', nil + case '\\': // backslash + return '\\', nil + default: + return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b)) + } +} + +func removeEscapedCharacters(b []rune) []rune { + for i := 0; i < len(b); i++ { + if isEscaped(b[:i], b[i]) { + c, err := getEscapedByte(b[i]) + if err != nil { + return b + } + + b[i-1] = c + b = append(b[:i], b[i+1:]...) + i-- + } + } + + return b +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go new file mode 100644 index 000000000..94841c324 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go @@ -0,0 +1,166 @@ +package ini + +import ( + "fmt" + "sort" +) + +// Visitor is an interface used by walkers that will +// traverse an array of ASTs. +type Visitor interface { + VisitExpr(AST) error + VisitStatement(AST) error +} + +// DefaultVisitor is used to visit statements and expressions +// and ensure that they are both of the correct format. +// In addition, upon visiting this will build sections and populate +// the Sections field which can be used to retrieve profile +// configuration. +type DefaultVisitor struct { + scope string + Sections Sections +} + +// NewDefaultVisitor return a DefaultVisitor +func NewDefaultVisitor() *DefaultVisitor { + return &DefaultVisitor{ + Sections: Sections{ + container: map[string]Section{}, + }, + } +} + +// VisitExpr visits expressions... +func (v *DefaultVisitor) VisitExpr(expr AST) error { + t := v.Sections.container[v.scope] + if t.values == nil { + t.values = values{} + } + + switch expr.Kind { + case ASTKindExprStatement: + opExpr := expr.GetRoot() + switch opExpr.Kind { + case ASTKindEqualExpr: + children := opExpr.GetChildren() + if len(children) <= 1 { + return NewParseError("unexpected token type") + } + + rhs := children[1] + + if rhs.Root.Type() != TokenLit { + return NewParseError("unexpected token type") + } + + key := EqualExprKey(opExpr) + v, err := newValue(rhs.Root.ValueType, rhs.Root.base, rhs.Root.Raw()) + if err != nil { + return err + } + + t.values[key] = v + default: + return NewParseError(fmt.Sprintf("unsupported expression %v", expr)) + } + default: + return NewParseError(fmt.Sprintf("unsupported expression %v", expr)) + } + + v.Sections.container[v.scope] = t + return nil +} + +// VisitStatement visits statements... +func (v *DefaultVisitor) VisitStatement(stmt AST) error { + switch stmt.Kind { + case ASTKindCompletedSectionStatement: + child := stmt.GetRoot() + if child.Kind != ASTKindSectionStatement { + return NewParseError(fmt.Sprintf("unsupported child statement: %T", child)) + } + + name := string(child.Root.Raw()) + v.Sections.container[name] = Section{} + v.scope = name + default: + return NewParseError(fmt.Sprintf("unsupported statement: %s", stmt.Kind)) + } + + return nil +} + +// Sections is a map of Section structures that represent +// a configuration. +type Sections struct { + container map[string]Section +} + +// GetSection will return section p. If section p does not exist, +// false will be returned in the second parameter. +func (t Sections) GetSection(p string) (Section, bool) { + v, ok := t.container[p] + return v, ok +} + +// values represents a map of union values. +type values map[string]Value + +// List will return a list of all sections that were successfully +// parsed. +func (t Sections) List() []string { + keys := make([]string, len(t.container)) + i := 0 + for k := range t.container { + keys[i] = k + i++ + } + + sort.Strings(keys) + return keys +} + +// Section contains a name and values. This represent +// a sectioned entry in a configuration file. +type Section struct { + Name string + values values +} + +// Has will return whether or not an entry exists in a given section +func (t Section) Has(k string) bool { + _, ok := t.values[k] + return ok +} + +// ValueType will returned what type the union is set to. If +// k was not found, the NoneType will be returned. +func (t Section) ValueType(k string) (ValueType, bool) { + v, ok := t.values[k] + return v.Type, ok +} + +// Bool returns a bool value at k +func (t Section) Bool(k string) bool { + return t.values[k].BoolValue() +} + +// Int returns an integer value at k +func (t Section) Int(k string) int64 { + return t.values[k].IntValue() +} + +// Float64 returns a float value at k +func (t Section) Float64(k string) float64 { + return t.values[k].FloatValue() +} + +// String returns the string value at k +func (t Section) String(k string) string { + _, ok := t.values[k] + if !ok { + return "" + } + return t.values[k].StringValue() +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go new file mode 100644 index 000000000..99915f7f7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go @@ -0,0 +1,25 @@ +package ini + +// Walk will traverse the AST using the v, the Visitor. +func Walk(tree []AST, v Visitor) error { + for _, node := range tree { + switch node.Kind { + case ASTKindExpr, + ASTKindExprStatement: + + if err := v.VisitExpr(node); err != nil { + return err + } + case ASTKindStatement, + ASTKindCompletedSectionStatement, + ASTKindNestedSectionStatement, + ASTKindCompletedNestedSectionStatement: + + if err := v.VisitStatement(node); err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go b/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go new file mode 100644 index 000000000..7ffb4ae06 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go @@ -0,0 +1,24 @@ +package ini + +import ( + "unicode" +) + +// isWhitespace will return whether or not the character is +// a whitespace character. +// +// Whitespace is defined as a space or tab. +func isWhitespace(c rune) bool { + return unicode.IsSpace(c) && c != '\n' && c != '\r' +} + +func newWSToken(b []rune) (Token, int, error) { + i := 0 + for ; i < len(b); i++ { + if !isWhitespace(b[i]) { + break + } + } + + return newToken(TokenWS, b[:i], NoneType), i, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go new file mode 100644 index 000000000..5aa9137e0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go @@ -0,0 +1,10 @@ +// +build !go1.7 + +package sdkio + +// Copy of Go 1.7 io package's Seeker constants. +const ( + SeekStart = 0 // seek relative to the origin of the file + SeekCurrent = 1 // seek relative to the current offset + SeekEnd = 2 // seek relative to the end +) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go new file mode 100644 index 000000000..e5f005613 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go @@ -0,0 +1,12 @@ +// +build go1.7 + +package sdkio + +import "io" + +// Alias for Go 1.7 io package Seeker constants +const ( + SeekStart = io.SeekStart // seek relative to the origin of the file + SeekCurrent = io.SeekCurrent // seek relative to the current offset + SeekEnd = io.SeekEnd // seek relative to the end +) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go new file mode 100644 index 000000000..0c9802d87 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go @@ -0,0 +1,29 @@ +package sdkrand + +import ( + "math/rand" + "sync" + "time" +) + +// lockedSource is a thread-safe implementation of rand.Source +type lockedSource struct { + lk sync.Mutex + src rand.Source +} + +func (r *lockedSource) Int63() (n int64) { + r.lk.Lock() + n = r.src.Int63() + r.lk.Unlock() + return +} + +func (r *lockedSource) Seed(seed int64) { + r.lk.Lock() + r.src.Seed(seed) + r.lk.Unlock() +} + +// SeededRand is a new RNG using a thread safe implementation of rand.Source +var SeededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())}) diff --git a/vendor/github.com/aws/aws-sdk-go/internal/sdkuri/path.go b/vendor/github.com/aws/aws-sdk-go/internal/sdkuri/path.go new file mode 100644 index 000000000..38ea61afe --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/sdkuri/path.go @@ -0,0 +1,23 @@ +package sdkuri + +import ( + "path" + "strings" +) + +// PathJoin will join the elements of the path delimited by the "/" +// character. Similar to path.Join with the exception the trailing "/" +// character is preserved if present. +func PathJoin(elems ...string) string { + if len(elems) == 0 { + return "" + } + + hasTrailing := strings.HasSuffix(elems[len(elems)-1], "/") + str := path.Join(elems...) + if hasTrailing && str != "/" { + str += "/" + } + + return str +} diff --git a/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go new file mode 100644 index 000000000..7da8a49ce --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go @@ -0,0 +1,12 @@ +package shareddefaults + +const ( + // ECSCredsProviderEnvVar is an environmental variable key used to + // determine which path needs to be hit. + ECSCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" +) + +// ECSContainerCredentialsURI is the endpoint to retrieve container +// credentials. This can be overridden to test to ensure the credential process +// is behaving correctly. +var ECSContainerCredentialsURI = "http://169.254.170.2" diff --git a/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go new file mode 100644 index 000000000..ebcbc2b40 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go @@ -0,0 +1,40 @@ +package shareddefaults + +import ( + "os" + "path/filepath" + "runtime" +) + +// SharedCredentialsFilename returns the SDK's default file path +// for the shared credentials file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/credentials +// - Windows: %USERPROFILE%\.aws\credentials +func SharedCredentialsFilename() string { + return filepath.Join(UserHomeDir(), ".aws", "credentials") +} + +// SharedConfigFilename returns the SDK's default file path for +// the shared config file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/config +// - Windows: %USERPROFILE%\.aws\config +func SharedConfigFilename() string { + return filepath.Join(UserHomeDir(), ".aws", "config") +} + +// UserHomeDir returns the home directory for the user the process is +// running under. +func UserHomeDir() string { + if runtime.GOOS == "windows" { // Windows + return os.Getenv("USERPROFILE") + } + + // *nix + return os.Getenv("HOME") +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go new file mode 100644 index 000000000..d7d42db0a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go @@ -0,0 +1,68 @@ +package protocol + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// ValidateEndpointHostHandler is a request handler that will validate the +// request endpoint's hosts is a valid RFC 3986 host. +var ValidateEndpointHostHandler = request.NamedHandler{ + Name: "awssdk.protocol.ValidateEndpointHostHandler", + Fn: func(r *request.Request) { + err := ValidateEndpointHost(r.Operation.Name, r.HTTPRequest.URL.Host) + if err != nil { + r.Error = err + } + }, +} + +// ValidateEndpointHost validates that the host string passed in is a valid RFC +// 3986 host. Returns error if the host is not valid. +func ValidateEndpointHost(opName, host string) error { + paramErrs := request.ErrInvalidParams{Context: opName} + labels := strings.Split(host, ".") + + for i, label := range labels { + if i == len(labels)-1 && len(label) == 0 { + // Allow trailing dot for FQDN hosts. + continue + } + + if !ValidHostLabel(label) { + paramErrs.Add(request.NewErrParamFormat( + "endpoint host label", "[a-zA-Z0-9-]{1,63}", label)) + } + } + + if len(host) > 255 { + paramErrs.Add(request.NewErrParamMaxLen( + "endpoint host", 255, host, + )) + } + + if paramErrs.Len() > 0 { + return paramErrs + } + return nil +} + +// ValidHostLabel returns if the label is a valid RFC 3986 host label. +func ValidHostLabel(label string) bool { + if l := len(label); l == 0 || l > 63 { + return false + } + for _, r := range label { + switch { + case r >= '0' && r <= '9': + case r >= 'A' && r <= 'Z': + case r >= 'a' && r <= 'z': + case r == '-': + default: + return false + } + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go new file mode 100644 index 000000000..915b0fcaf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go @@ -0,0 +1,54 @@ +package protocol + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +// HostPrefixHandlerName is the handler name for the host prefix request +// handler. +const HostPrefixHandlerName = "awssdk.endpoint.HostPrefixHandler" + +// NewHostPrefixHandler constructs a build handler +func NewHostPrefixHandler(prefix string, labelsFn func() map[string]string) request.NamedHandler { + builder := HostPrefixBuilder{ + Prefix: prefix, + LabelsFn: labelsFn, + } + + return request.NamedHandler{ + Name: HostPrefixHandlerName, + Fn: builder.Build, + } +} + +// HostPrefixBuilder provides the request handler to expand and prepend +// the host prefix into the operation's request endpoint host. +type HostPrefixBuilder struct { + Prefix string + LabelsFn func() map[string]string +} + +// Build updates the passed in Request with the HostPrefix template expanded. +func (h HostPrefixBuilder) Build(r *request.Request) { + if aws.BoolValue(r.Config.DisableEndpointHostPrefix) { + return + } + + var labels map[string]string + if h.LabelsFn != nil { + labels = h.LabelsFn() + } + + prefix := h.Prefix + for name, value := range labels { + prefix = strings.Replace(prefix, "{"+name+"}", value, -1) + } + + r.HTTPRequest.URL.Host = prefix + r.HTTPRequest.URL.Host + if len(r.HTTPRequest.Host) > 0 { + r.HTTPRequest.Host = prefix + r.HTTPRequest.Host + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go new file mode 100644 index 000000000..53831dff9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go @@ -0,0 +1,75 @@ +package protocol + +import ( + "crypto/rand" + "fmt" + "reflect" +) + +// RandReader is the random reader the protocol package will use to read +// random bytes from. This is exported for testing, and should not be used. +var RandReader = rand.Reader + +const idempotencyTokenFillTag = `idempotencyToken` + +// CanSetIdempotencyToken returns true if the struct field should be +// automatically populated with a Idempotency token. +// +// Only *string and string type fields that are tagged with idempotencyToken +// which are not already set can be auto filled. +func CanSetIdempotencyToken(v reflect.Value, f reflect.StructField) bool { + switch u := v.Interface().(type) { + // To auto fill an Idempotency token the field must be a string, + // tagged for auto fill, and have a zero value. + case *string: + return u == nil && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + case string: + return len(u) == 0 && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + } + + return false +} + +// GetIdempotencyToken returns a randomly generated idempotency token. +func GetIdempotencyToken() string { + b := make([]byte, 16) + RandReader.Read(b) + + return UUIDVersion4(b) +} + +// SetIdempotencyToken will set the value provided with a Idempotency Token. +// Given that the value can be set. Will panic if value is not setable. +func SetIdempotencyToken(v reflect.Value) { + if v.Kind() == reflect.Ptr { + if v.IsNil() && v.CanSet() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + v = reflect.Indirect(v) + + if !v.CanSet() { + panic(fmt.Sprintf("unable to set idempotnecy token %v", v)) + } + + b := make([]byte, 16) + _, err := rand.Read(b) + if err != nil { + // TODO handle error + return + } + + v.Set(reflect.ValueOf(UUIDVersion4(b))) +} + +// UUIDVersion4 returns a Version 4 random UUID from the byte slice provided +func UUIDVersion4(u []byte) string { + // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 + // 13th character is "4" + u[6] = (u[6] | 0x40) & 0x4F + // 17th character is "8", "9", "a", or "b" + u[8] = (u[8] | 0x80) & 0xBF + + return fmt.Sprintf(`%X-%X-%X-%X-%X`, u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go new file mode 100644 index 000000000..864fb6704 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go @@ -0,0 +1,296 @@ +// Package jsonutil provides JSON serialization of AWS requests and responses. +package jsonutil + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/private/protocol" +) + +var timeType = reflect.ValueOf(time.Time{}).Type() +var byteSliceType = reflect.ValueOf([]byte{}).Type() + +// BuildJSON builds a JSON string for a given object v. +func BuildJSON(v interface{}) ([]byte, error) { + var buf bytes.Buffer + + err := buildAny(reflect.ValueOf(v), &buf, "") + return buf.Bytes(), err +} + +func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + origVal := value + value = reflect.Indirect(value) + if !value.IsValid() { + return nil + } + + vtype := value.Type() + + t := tag.Get("type") + if t == "" { + switch vtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if value.Type() != timeType { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := value.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } + } + } + + switch t { + case "structure": + if field, ok := vtype.FieldByName("_"); ok { + tag = field.Tag + } + return buildStruct(value, buf, tag) + case "list": + return buildList(value, buf, tag) + case "map": + return buildMap(value, buf, tag) + default: + return buildScalar(origVal, buf, tag) + } +} + +func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + if !value.IsValid() { + return nil + } + + // unwrap payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := value.Type().FieldByName(payload) + tag = field.Tag + value = elemOf(value.FieldByName(payload)) + + if !value.IsValid() { + return nil + } + } + + buf.WriteByte('{') + + t := value.Type() + first := true + for i := 0; i < t.NumField(); i++ { + member := value.Field(i) + + // This allocates the most memory. + // Additionally, we cannot skip nil fields due to + // idempotency auto filling. + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("json") == "-" { + continue + } + if field.Tag.Get("location") != "" { + continue // ignore non-body elements + } + if field.Tag.Get("ignore") != "" { + continue + } + + if protocol.CanSetIdempotencyToken(member, field) { + token := protocol.GetIdempotencyToken() + member = reflect.ValueOf(&token) + } + + if (member.Kind() == reflect.Ptr || member.Kind() == reflect.Slice || member.Kind() == reflect.Map) && member.IsNil() { + continue // ignore unset fields + } + + if first { + first = false + } else { + buf.WriteByte(',') + } + + // figure out what this field is called + name := field.Name + if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + writeString(name, buf) + buf.WriteString(`:`) + + err := buildAny(member, buf, field.Tag) + if err != nil { + return err + } + + } + + buf.WriteString("}") + + return nil +} + +func buildList(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + buf.WriteString("[") + + for i := 0; i < value.Len(); i++ { + buildAny(value.Index(i), buf, "") + + if i < value.Len()-1 { + buf.WriteString(",") + } + } + + buf.WriteString("]") + + return nil +} + +type sortedValues []reflect.Value + +func (sv sortedValues) Len() int { return len(sv) } +func (sv sortedValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv sortedValues) Less(i, j int) bool { return sv[i].String() < sv[j].String() } + +func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + buf.WriteString("{") + + sv := sortedValues(value.MapKeys()) + sort.Sort(sv) + + for i, k := range sv { + if i > 0 { + buf.WriteByte(',') + } + + writeString(k.String(), buf) + buf.WriteString(`:`) + + buildAny(value.MapIndex(k), buf, "") + } + + buf.WriteString("}") + + return nil +} + +func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + // prevents allocation on the heap. + scratch := [64]byte{} + switch value := reflect.Indirect(v); value.Kind() { + case reflect.String: + writeString(value.String(), buf) + case reflect.Bool: + if value.Bool() { + buf.WriteString("true") + } else { + buf.WriteString("false") + } + case reflect.Int64: + buf.Write(strconv.AppendInt(scratch[:0], value.Int(), 10)) + case reflect.Float64: + f := value.Float() + if math.IsInf(f, 0) || math.IsNaN(f) { + return &json.UnsupportedValueError{Value: v, Str: strconv.FormatFloat(f, 'f', -1, 64)} + } + buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)) + default: + switch converted := value.Interface().(type) { + case time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.UnixTimeFormatName + } + + ts := protocol.FormatTime(format, converted) + if format != protocol.UnixTimeFormatName { + ts = `"` + ts + `"` + } + + buf.WriteString(ts) + case []byte: + if !value.IsNil() { + buf.WriteByte('"') + if len(converted) < 1024 { + // for small buffers, using Encode directly is much faster. + dst := make([]byte, base64.StdEncoding.EncodedLen(len(converted))) + base64.StdEncoding.Encode(dst, converted) + buf.Write(dst) + } else { + // for large buffers, avoid unnecessary extra temporary + // buffer space. + enc := base64.NewEncoder(base64.StdEncoding, buf) + enc.Write(converted) + enc.Close() + } + buf.WriteByte('"') + } + case aws.JSONValue: + str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape) + if err != nil { + return fmt.Errorf("unable to encode JSONValue, %v", err) + } + buf.WriteString(str) + default: + return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type()) + } + } + return nil +} + +var hex = "0123456789abcdef" + +func writeString(s string, buf *bytes.Buffer) { + buf.WriteByte('"') + for i := 0; i < len(s); i++ { + if s[i] == '"' { + buf.WriteString(`\"`) + } else if s[i] == '\\' { + buf.WriteString(`\\`) + } else if s[i] == '\b' { + buf.WriteString(`\b`) + } else if s[i] == '\f' { + buf.WriteString(`\f`) + } else if s[i] == '\r' { + buf.WriteString(`\r`) + } else if s[i] == '\t' { + buf.WriteString(`\t`) + } else if s[i] == '\n' { + buf.WriteString(`\n`) + } else if s[i] < 32 { + buf.WriteString("\\u00") + buf.WriteByte(hex[s[i]>>4]) + buf.WriteByte(hex[s[i]&0xF]) + } else { + buf.WriteByte(s[i]) + } + } + buf.WriteByte('"') +} + +// Returns the reflection element of a value, if it is a pointer. +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go new file mode 100644 index 000000000..ea0da79a5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go @@ -0,0 +1,250 @@ +package jsonutil + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "reflect" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// UnmarshalJSONError unmarshal's the reader's JSON document into the passed in +// type. The value to unmarshal the json document into must be a pointer to the +// type. +func UnmarshalJSONError(v interface{}, stream io.Reader) error { + var errBuf bytes.Buffer + body := io.TeeReader(stream, &errBuf) + + err := json.NewDecoder(body).Decode(v) + if err != nil { + msg := "failed decoding error message" + if err == io.EOF { + msg = "error message missing" + err = nil + } + return awserr.NewUnmarshalError(err, msg, errBuf.Bytes()) + } + + return nil +} + +// UnmarshalJSON reads a stream and unmarshals the results in object v. +func UnmarshalJSON(v interface{}, stream io.Reader) error { + var out interface{} + + err := json.NewDecoder(stream).Decode(&out) + if err == io.EOF { + return nil + } else if err != nil { + return err + } + + return unmarshalAny(reflect.ValueOf(v), out, "") +} + +func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) error { + vtype := value.Type() + if vtype.Kind() == reflect.Ptr { + vtype = vtype.Elem() // check kind of actual element type + } + + t := tag.Get("type") + if t == "" { + switch vtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if _, ok := value.Interface().(*time.Time); !ok { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := value.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } + } + } + + switch t { + case "structure": + if field, ok := vtype.FieldByName("_"); ok { + tag = field.Tag + } + return unmarshalStruct(value, data, tag) + case "list": + return unmarshalList(value, data, tag) + case "map": + return unmarshalMap(value, data, tag) + default: + return unmarshalScalar(value, data, tag) + } +} + +func unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + mapData, ok := data.(map[string]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a structure (%#v)", data) + } + + t := value.Type() + if value.Kind() == reflect.Ptr { + if value.IsNil() { // create the structure if it's nil + s := reflect.New(value.Type().Elem()) + value.Set(s) + value = s + } + + value = value.Elem() + t = t.Elem() + } + + // unwrap any payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := t.FieldByName(payload) + return unmarshalAny(value.FieldByName(payload), data, field.Tag) + } + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if field.PkgPath != "" { + continue // ignore unexported fields + } + + // figure out what this field is called + name := field.Name + if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + member := value.FieldByIndex(field.Index) + err := unmarshalAny(member, mapData[name], field.Tag) + if err != nil { + return err + } + } + return nil +} + +func unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + listData, ok := data.([]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a list (%#v)", data) + } + + if value.IsNil() { + l := len(listData) + value.Set(reflect.MakeSlice(value.Type(), l, l)) + } + + for i, c := range listData { + err := unmarshalAny(value.Index(i), c, "") + if err != nil { + return err + } + } + + return nil +} + +func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + mapData, ok := data.(map[string]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a map (%#v)", data) + } + + if value.IsNil() { + value.Set(reflect.MakeMap(value.Type())) + } + + for k, v := range mapData { + kvalue := reflect.ValueOf(k) + vvalue := reflect.New(value.Type().Elem()).Elem() + + unmarshalAny(vvalue, v, "") + value.SetMapIndex(kvalue, vvalue) + } + + return nil +} + +func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTag) error { + + switch d := data.(type) { + case nil: + return nil // nothing to do here + case string: + switch value.Interface().(type) { + case *string: + value.Set(reflect.ValueOf(&d)) + case []byte: + b, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return err + } + value.Set(reflect.ValueOf(b)) + case *time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + t, err := protocol.ParseTime(format, d) + if err != nil { + return err + } + value.Set(reflect.ValueOf(&t)) + case aws.JSONValue: + // No need to use escaping as the value is a non-quoted string. + v, err := protocol.DecodeJSONValue(d, protocol.NoEscape) + if err != nil { + return err + } + value.Set(reflect.ValueOf(v)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + case float64: + switch value.Interface().(type) { + case *int64: + di := int64(d) + value.Set(reflect.ValueOf(&di)) + case *float64: + value.Set(reflect.ValueOf(&d)) + case *time.Time: + // Time unmarshaled from a float64 can only be epoch seconds + t := time.Unix(int64(d), 0).UTC() + value.Set(reflect.ValueOf(&t)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + case bool: + switch value.Interface().(type) { + case *bool: + value.Set(reflect.ValueOf(&d)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + default: + return fmt.Errorf("unsupported JSON value (%v)", data) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go new file mode 100644 index 000000000..bfedc9fd4 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go @@ -0,0 +1,110 @@ +// Package jsonrpc provides JSON RPC utilities for serialization of AWS +// requests and responses. +package jsonrpc + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/json.json build_test.go +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" + "github.com/aws/aws-sdk-go/private/protocol/rest" +) + +var emptyJSON = []byte("{}") + +// BuildHandler is a named request handler for building jsonrpc protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Build", Fn: Build} + +// UnmarshalHandler is a named request handler for unmarshaling jsonrpc protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalError", Fn: UnmarshalError} + +// Build builds a JSON payload for a JSON RPC request. +func Build(req *request.Request) { + var buf []byte + var err error + if req.ParamsFilled() { + buf, err = jsonutil.BuildJSON(req.Params) + if err != nil { + req.Error = awserr.New(request.ErrCodeSerialization, "failed encoding JSON RPC request", err) + return + } + } else { + buf = emptyJSON + } + + if req.ClientInfo.TargetPrefix != "" || string(buf) != "{}" { + req.SetBufferBody(buf) + } + + if req.ClientInfo.TargetPrefix != "" { + target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name + req.HTTPRequest.Header.Add("X-Amz-Target", target) + } + + // Only set the content type if one is not already specified and an + // JSONVersion is specified. + if ct, v := req.HTTPRequest.Header.Get("Content-Type"), req.ClientInfo.JSONVersion; len(ct) == 0 && len(v) != 0 { + jsonVersion := req.ClientInfo.JSONVersion + req.HTTPRequest.Header.Set("Content-Type", "application/x-amz-json-"+jsonVersion) + } +} + +// Unmarshal unmarshals a response for a JSON RPC service. +func Unmarshal(req *request.Request) { + defer req.HTTPResponse.Body.Close() + if req.DataFilled() { + err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body) + if err != nil { + req.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, "failed decoding JSON RPC response", err), + req.HTTPResponse.StatusCode, + req.RequestID, + ) + } + } + return +} + +// UnmarshalMeta unmarshals headers from a response for a JSON RPC service. +func UnmarshalMeta(req *request.Request) { + rest.UnmarshalMeta(req) +} + +// UnmarshalError unmarshals an error response for a JSON RPC service. +func UnmarshalError(req *request.Request) { + defer req.HTTPResponse.Body.Close() + + var jsonErr jsonErrorResponse + err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body) + if err != nil { + req.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to unmarshal error message", err), + req.HTTPResponse.StatusCode, + req.RequestID, + ) + return + } + + codes := strings.SplitN(jsonErr.Code, "#", 2) + req.Error = awserr.NewRequestFailure( + awserr.New(codes[len(codes)-1], jsonErr.Message, nil), + req.HTTPResponse.StatusCode, + req.RequestID, + ) +} + +type jsonErrorResponse struct { + Code string `json:"__type"` + Message string `json:"message"` +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go new file mode 100644 index 000000000..776d11018 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go @@ -0,0 +1,76 @@ +package protocol + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/aws/aws-sdk-go/aws" +) + +// EscapeMode is the mode that should be use for escaping a value +type EscapeMode uint + +// The modes for escaping a value before it is marshaled, and unmarshaled. +const ( + NoEscape EscapeMode = iota + Base64Escape + QuotedEscape +) + +// EncodeJSONValue marshals the value into a JSON string, and optionally base64 +// encodes the string before returning it. +// +// Will panic if the escape mode is unknown. +func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) { + b, err := json.Marshal(v) + if err != nil { + return "", err + } + + switch escape { + case NoEscape: + return string(b), nil + case Base64Escape: + return base64.StdEncoding.EncodeToString(b), nil + case QuotedEscape: + return strconv.Quote(string(b)), nil + } + + panic(fmt.Sprintf("EncodeJSONValue called with unknown EscapeMode, %v", escape)) +} + +// DecodeJSONValue will attempt to decode the string input as a JSONValue. +// Optionally decoding base64 the value first before JSON unmarshaling. +// +// Will panic if the escape mode is unknown. +func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) { + var b []byte + var err error + + switch escape { + case NoEscape: + b = []byte(v) + case Base64Escape: + b, err = base64.StdEncoding.DecodeString(v) + case QuotedEscape: + var u string + u, err = strconv.Unquote(v) + b = []byte(u) + default: + panic(fmt.Sprintf("DecodeJSONValue called with unknown EscapeMode, %v", escape)) + } + + if err != nil { + return nil, err + } + + m := aws.JSONValue{} + err = json.Unmarshal(b, &m) + if err != nil { + return nil, err + } + + return m, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go new file mode 100644 index 000000000..e21614a12 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go @@ -0,0 +1,81 @@ +package protocol + +import ( + "io" + "io/ioutil" + "net/http" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +// PayloadUnmarshaler provides the interface for unmarshaling a payload's +// reader into a SDK shape. +type PayloadUnmarshaler interface { + UnmarshalPayload(io.Reader, interface{}) error +} + +// HandlerPayloadUnmarshal implements the PayloadUnmarshaler from a +// HandlerList. This provides the support for unmarshaling a payload reader to +// a shape without needing a SDK request first. +type HandlerPayloadUnmarshal struct { + Unmarshalers request.HandlerList +} + +// UnmarshalPayload unmarshals the io.Reader payload into the SDK shape using +// the Unmarshalers HandlerList provided. Returns an error if unable +// unmarshaling fails. +func (h HandlerPayloadUnmarshal) UnmarshalPayload(r io.Reader, v interface{}) error { + req := &request.Request{ + HTTPRequest: &http.Request{}, + HTTPResponse: &http.Response{ + StatusCode: 200, + Header: http.Header{}, + Body: ioutil.NopCloser(r), + }, + Data: v, + } + + h.Unmarshalers.Run(req) + + return req.Error +} + +// PayloadMarshaler provides the interface for marshaling a SDK shape into and +// io.Writer. +type PayloadMarshaler interface { + MarshalPayload(io.Writer, interface{}) error +} + +// HandlerPayloadMarshal implements the PayloadMarshaler from a HandlerList. +// This provides support for marshaling a SDK shape into an io.Writer without +// needing a SDK request first. +type HandlerPayloadMarshal struct { + Marshalers request.HandlerList +} + +// MarshalPayload marshals the SDK shape into the io.Writer using the +// Marshalers HandlerList provided. Returns an error if unable if marshal +// fails. +func (h HandlerPayloadMarshal) MarshalPayload(w io.Writer, v interface{}) error { + req := request.New( + aws.Config{}, + metadata.ClientInfo{}, + request.Handlers{}, + nil, + &request.Operation{HTTPMethod: "GET"}, + v, + nil, + ) + + h.Marshalers.Run(req) + + if req.Error != nil { + return req.Error + } + + io.Copy(w, req.GetBody()) + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go new file mode 100644 index 000000000..0cb99eb57 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go @@ -0,0 +1,36 @@ +// Package query provides serialization of AWS query requests, and responses. +package query + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go + +import ( + "net/url" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/query/queryutil" +) + +// BuildHandler is a named request handler for building query protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.query.Build", Fn: Build} + +// Build builds a request for an AWS Query service. +func Build(r *request.Request) { + body := url.Values{ + "Action": {r.Operation.Name}, + "Version": {r.ClientInfo.APIVersion}, + } + if err := queryutil.Parse(body, r.Params, false); err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed encoding Query request", err) + return + } + + if !r.IsPresigned() { + r.HTTPRequest.Method = "POST" + r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + r.SetBufferBody([]byte(body.Encode())) + } else { // This is a pre-signed request + r.HTTPRequest.Method = "GET" + r.HTTPRequest.URL.RawQuery = body.Encode() + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go new file mode 100644 index 000000000..75866d012 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go @@ -0,0 +1,246 @@ +package queryutil + +import ( + "encoding/base64" + "fmt" + "net/url" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/private/protocol" +) + +// Parse parses an object i and fills a url.Values object. The isEC2 flag +// indicates if this is the EC2 Query sub-protocol. +func Parse(body url.Values, i interface{}, isEC2 bool) error { + q := queryParser{isEC2: isEC2} + return q.parseValue(body, reflect.ValueOf(i), "", "") +} + +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} + +type queryParser struct { + isEC2 bool +} + +func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + value = elemOf(value) + + // no need to handle zero values + if !value.IsValid() { + return nil + } + + t := tag.Get("type") + if t == "" { + switch value.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + return q.parseStruct(v, value, prefix) + case "list": + return q.parseList(v, value, prefix, tag) + case "map": + return q.parseMap(v, value, prefix, tag) + default: + return q.parseScalar(v, value, prefix, tag) + } +} + +func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error { + if !value.IsValid() { + return nil + } + + t := value.Type() + for i := 0; i < value.NumField(); i++ { + elemValue := elemOf(value.Field(i)) + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("ignore") != "" { + continue + } + + if protocol.CanSetIdempotencyToken(value.Field(i), field) { + token := protocol.GetIdempotencyToken() + elemValue = reflect.ValueOf(token) + } + + var name string + if q.isEC2 { + name = field.Tag.Get("queryName") + } + if name == "" { + if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { + name = field.Tag.Get("locationNameList") + } else if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + if name != "" && q.isEC2 { + name = strings.ToUpper(name[0:1]) + name[1:] + } + } + if name == "" { + name = field.Name + } + + if prefix != "" { + name = prefix + "." + name + } + + if err := q.parseValue(v, elemValue, name, field.Tag); err != nil { + return err + } + } + return nil +} + +func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + // If it's empty, generate an empty value + if !value.IsNil() && value.Len() == 0 { + v.Set(prefix, "") + return nil + } + + if _, ok := value.Interface().([]byte); ok { + return q.parseScalar(v, value, prefix, tag) + } + + // check for unflattened list member + if !q.isEC2 && tag.Get("flattened") == "" { + if listName := tag.Get("locationNameList"); listName == "" { + prefix += ".member" + } else { + prefix += "." + listName + } + } + + for i := 0; i < value.Len(); i++ { + slicePrefix := prefix + if slicePrefix == "" { + slicePrefix = strconv.Itoa(i + 1) + } else { + slicePrefix = slicePrefix + "." + strconv.Itoa(i+1) + } + if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil { + return err + } + } + return nil +} + +func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + // If it's empty, generate an empty value + if !value.IsNil() && value.Len() == 0 { + v.Set(prefix, "") + return nil + } + + // check for unflattened list member + if !q.isEC2 && tag.Get("flattened") == "" { + prefix += ".entry" + } + + // sort keys for improved serialization consistency. + // this is not strictly necessary for protocol support. + mapKeyValues := value.MapKeys() + mapKeys := map[string]reflect.Value{} + mapKeyNames := make([]string, len(mapKeyValues)) + for i, mapKey := range mapKeyValues { + name := mapKey.String() + mapKeys[name] = mapKey + mapKeyNames[i] = name + } + sort.Strings(mapKeyNames) + + for i, mapKeyName := range mapKeyNames { + mapKey := mapKeys[mapKeyName] + mapValue := value.MapIndex(mapKey) + + kname := tag.Get("locationNameKey") + if kname == "" { + kname = "key" + } + vname := tag.Get("locationNameValue") + if vname == "" { + vname = "value" + } + + // serialize key + var keyName string + if prefix == "" { + keyName = strconv.Itoa(i+1) + "." + kname + } else { + keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname + } + + if err := q.parseValue(v, mapKey, keyName, ""); err != nil { + return err + } + + // serialize value + var valueName string + if prefix == "" { + valueName = strconv.Itoa(i+1) + "." + vname + } else { + valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname + } + + if err := q.parseValue(v, mapValue, valueName, ""); err != nil { + return err + } + } + + return nil +} + +func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error { + switch value := r.Interface().(type) { + case string: + v.Set(name, value) + case []byte: + if !r.IsNil() { + v.Set(name, base64.StdEncoding.EncodeToString(value)) + } + case bool: + v.Set(name, strconv.FormatBool(value)) + case int64: + v.Set(name, strconv.FormatInt(value, 10)) + case int: + v.Set(name, strconv.Itoa(value)) + case float64: + v.Set(name, strconv.FormatFloat(value, 'f', -1, 64)) + case float32: + v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32)) + case time.Time: + const ISO8601UTC = "2006-01-02T15:04:05Z" + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + v.Set(name, protocol.FormatTime(format, value)) + default: + return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name()) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go new file mode 100644 index 000000000..f69c1efc9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go @@ -0,0 +1,39 @@ +package query + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go + +import ( + "encoding/xml" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +// UnmarshalHandler is a named request handler for unmarshaling query protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.query.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling query protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals a response for an AWS Query service. +func Unmarshal(r *request.Request) { + defer r.HTTPResponse.Body.Close() + if r.DataFilled() { + decoder := xml.NewDecoder(r.HTTPResponse.Body) + err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result") + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, "failed decoding Query response", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + } +} + +// UnmarshalMeta unmarshals header response values for an AWS Query service. +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go new file mode 100644 index 000000000..831b0110c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go @@ -0,0 +1,69 @@ +package query + +import ( + "encoding/xml" + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +// UnmarshalErrorHandler is a name request handler to unmarshal request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError} + +type xmlErrorResponse struct { + Code string `xml:"Error>Code"` + Message string `xml:"Error>Message"` + RequestID string `xml:"RequestId"` +} + +type xmlResponseError struct { + xmlErrorResponse +} + +func (e *xmlResponseError) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + const svcUnavailableTagName = "ServiceUnavailableException" + const errorResponseTagName = "ErrorResponse" + + switch start.Name.Local { + case svcUnavailableTagName: + e.Code = svcUnavailableTagName + e.Message = "service is unavailable" + return d.Skip() + + case errorResponseTagName: + return d.DecodeElement(&e.xmlErrorResponse, &start) + + default: + return fmt.Errorf("unknown error response tag, %v", start) + } +} + +// UnmarshalError unmarshals an error response for an AWS Query service. +func UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + var respErr xmlResponseError + err := xmlutil.UnmarshalXMLError(&respErr, r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to unmarshal error message", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + + reqID := respErr.RequestID + if len(reqID) == 0 { + reqID = r.RequestID + } + + r.Error = awserr.NewRequestFailure( + awserr.New(respErr.Code, respErr.Message, nil), + r.HTTPResponse.StatusCode, + reqID, + ) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go new file mode 100644 index 000000000..1301b149d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go @@ -0,0 +1,310 @@ +// Package rest provides RESTful serialization of AWS requests and responses. +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "net/http" + "net/url" + "path" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// Whether the byte value can be sent without escaping in AWS URLs +var noEscape [256]bool + +var errValueNotSet = fmt.Errorf("value not set") + +var byteSliceType = reflect.TypeOf([]byte{}) + +func init() { + for i := 0; i < len(noEscape); i++ { + // AWS expects every character except these to be escaped + noEscape[i] = (i >= 'A' && i <= 'Z') || + (i >= 'a' && i <= 'z') || + (i >= '0' && i <= '9') || + i == '-' || + i == '.' || + i == '_' || + i == '~' + } +} + +// BuildHandler is a named request handler for building rest protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.rest.Build", Fn: Build} + +// Build builds the REST component of a service request. +func Build(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v, false) + buildBody(r, v) + } +} + +// BuildAsGET builds the REST component of a service request with the ability to hoist +// data from the body. +func BuildAsGET(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v, true) + buildBody(r, v) + } +} + +func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bool) { + query := r.HTTPRequest.URL.Query() + + // Setup the raw path to match the base path pattern. This is needed + // so that when the path is mutated a custom escaped version can be + // stored in RawPath that will be used by the Go client. + r.HTTPRequest.URL.RawPath = r.HTTPRequest.URL.Path + + for i := 0; i < v.NumField(); i++ { + m := v.Field(i) + if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + field := v.Type().Field(i) + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + if kind := m.Kind(); kind == reflect.Ptr { + m = m.Elem() + } else if kind == reflect.Interface { + if !m.Elem().IsValid() { + continue + } + } + if !m.IsValid() { + continue + } + if field.Tag.Get("ignore") != "" { + continue + } + + // Support the ability to customize values to be marshaled as a + // blob even though they were modeled as a string. Required for S3 + // API operations like SSECustomerKey is modeled as stirng but + // required to be base64 encoded in request. + if field.Tag.Get("marshal-as") == "blob" { + m = m.Convert(byteSliceType) + } + + var err error + switch field.Tag.Get("location") { + case "headers": // header maps + err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag) + case "header": + err = buildHeader(&r.HTTPRequest.Header, m, name, field.Tag) + case "uri": + err = buildURI(r.HTTPRequest.URL, m, name, field.Tag) + case "querystring": + err = buildQueryString(query, m, name, field.Tag) + default: + if buildGETQuery { + err = buildQueryString(query, m, name, field.Tag) + } + } + r.Error = err + } + if r.Error != nil { + return + } + } + + r.HTTPRequest.URL.RawQuery = query.Encode() + if !aws.BoolValue(r.Config.DisableRestProtocolURICleaning) { + cleanPath(r.HTTPRequest.URL) + } +} + +func buildBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := reflect.Indirect(v.FieldByName(payloadName)) + if payload.IsValid() && payload.Interface() != nil { + switch reader := payload.Interface().(type) { + case io.ReadSeeker: + r.SetReaderBody(reader) + case []byte: + r.SetBufferBody(reader) + case string: + r.SetStringBody(reader) + default: + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to encode REST request", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } +} + +func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.StructTag) error { + str, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + + name = strings.TrimSpace(name) + str = strings.TrimSpace(str) + + header.Add(name, str) + + return nil +} + +func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag) error { + prefix := tag.Get("locationName") + for _, key := range v.MapKeys() { + str, err := convertType(v.MapIndex(key), tag) + if err == errValueNotSet { + continue + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + + } + keyStr := strings.TrimSpace(key.String()) + str = strings.TrimSpace(str) + + header.Add(prefix+keyStr, str) + } + return nil +} + +func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) error { + value, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + + u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1) + u.Path = strings.Replace(u.Path, "{"+name+"+}", value, -1) + + u.RawPath = strings.Replace(u.RawPath, "{"+name+"}", EscapePath(value, true), -1) + u.RawPath = strings.Replace(u.RawPath, "{"+name+"+}", EscapePath(value, false), -1) + + return nil +} + +func buildQueryString(query url.Values, v reflect.Value, name string, tag reflect.StructTag) error { + switch value := v.Interface().(type) { + case []*string: + for _, item := range value { + query.Add(name, *item) + } + case map[string]*string: + for key, item := range value { + query.Add(key, *item) + } + case map[string][]*string: + for key, items := range value { + for _, item := range items { + query.Add(key, *item) + } + } + default: + str, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + query.Set(name, str) + } + + return nil +} + +func cleanPath(u *url.URL) { + hasSlash := strings.HasSuffix(u.Path, "/") + + // clean up path, removing duplicate `/` + u.Path = path.Clean(u.Path) + u.RawPath = path.Clean(u.RawPath) + + if hasSlash && !strings.HasSuffix(u.Path, "/") { + u.Path += "/" + u.RawPath += "/" + } +} + +// EscapePath escapes part of a URL path in Amazon style +func EscapePath(path string, encodeSep bool) string { + var buf bytes.Buffer + for i := 0; i < len(path); i++ { + c := path[i] + if noEscape[c] || (c == '/' && !encodeSep) { + buf.WriteByte(c) + } else { + fmt.Fprintf(&buf, "%%%02X", c) + } + } + return buf.String() +} + +func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) { + v = reflect.Indirect(v) + if !v.IsValid() { + return "", errValueNotSet + } + + switch value := v.Interface().(type) { + case string: + str = value + case []byte: + str = base64.StdEncoding.EncodeToString(value) + case bool: + str = strconv.FormatBool(value) + case int64: + str = strconv.FormatInt(value, 10) + case float64: + str = strconv.FormatFloat(value, 'f', -1, 64) + case time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.RFC822TimeFormatName + if tag.Get("location") == "querystring" { + format = protocol.ISO8601TimeFormatName + } + } + str = protocol.FormatTime(format, value) + case aws.JSONValue: + if len(value) == 0 { + return "", errValueNotSet + } + escaping := protocol.NoEscape + if tag.Get("location") == "header" { + escaping = protocol.Base64Escape + } + str, err = protocol.EncodeJSONValue(value, escaping) + if err != nil { + return "", fmt.Errorf("unable to encode JSONValue, %v", err) + } + default: + err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type()) + return "", err + } + return str, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go new file mode 100644 index 000000000..4366de2e1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go @@ -0,0 +1,45 @@ +package rest + +import "reflect" + +// PayloadMember returns the payload field member of i if there is one, or nil. +func PayloadMember(i interface{}) interface{} { + if i == nil { + return nil + } + + v := reflect.ValueOf(i).Elem() + if !v.IsValid() { + return nil + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + field, _ := v.Type().FieldByName(payloadName) + if field.Tag.Get("type") != "structure" { + return nil + } + + payload := v.FieldByName(payloadName) + if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) { + return payload.Interface() + } + } + } + return nil +} + +// PayloadType returns the type of a payload field member of i if there is one, or "". +func PayloadType(i interface{}) string { + v := reflect.Indirect(reflect.ValueOf(i)) + if !v.IsValid() { + return "" + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + if member, ok := v.Type().FieldByName(payloadName); ok { + return member.Tag.Get("type") + } + } + } + return "" +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go new file mode 100644 index 000000000..de021367d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go @@ -0,0 +1,225 @@ +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "io/ioutil" + "net/http" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// UnmarshalHandler is a named request handler for unmarshaling rest protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.rest.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling rest protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.rest.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals the REST component of a response in a REST service. +func Unmarshal(r *request.Request) { + if r.DataFilled() { + v := reflect.Indirect(reflect.ValueOf(r.Data)) + unmarshalBody(r, v) + } +} + +// UnmarshalMeta unmarshals the REST metadata of a response in a REST service +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") + if r.RequestID == "" { + // Alternative version of request id in the header + r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id") + } + if r.DataFilled() { + v := reflect.Indirect(reflect.ValueOf(r.Data)) + unmarshalLocationElements(r, v) + } +} + +func unmarshalBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := v.FieldByName(payloadName) + if payload.IsValid() { + switch payload.Interface().(type) { + case []byte: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + } else { + payload.Set(reflect.ValueOf(b)) + } + case *string: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + } else { + str := string(b) + payload.Set(reflect.ValueOf(&str)) + } + default: + switch payload.Type().String() { + case "io.ReadCloser": + payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) + case "io.ReadSeeker": + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to read response body", err) + return + } + payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b)))) + default: + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + defer r.HTTPResponse.Body.Close() + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to decode REST response", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } + } +} + +func unmarshalLocationElements(r *request.Request, v reflect.Value) { + for i := 0; i < v.NumField(); i++ { + m, field := v.Field(i), v.Type().Field(i) + if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + + switch field.Tag.Get("location") { + case "statusCode": + unmarshalStatusCode(m, r.HTTPResponse.StatusCode) + case "header": + err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + break + } + case "headers": + prefix := field.Tag.Get("locationName") + err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + break + } + } + } + if r.Error != nil { + return + } + } +} + +func unmarshalStatusCode(v reflect.Value, statusCode int) { + if !v.IsValid() { + return + } + + switch v.Interface().(type) { + case *int64: + s := int64(statusCode) + v.Set(reflect.ValueOf(&s)) + } +} + +func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error { + switch r.Interface().(type) { + case map[string]*string: // we only support string map value types + out := map[string]*string{} + for k, v := range headers { + k = http.CanonicalHeaderKey(k) + if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) { + out[k[len(prefix):]] = &v[0] + } + } + r.Set(reflect.ValueOf(out)) + } + return nil +} + +func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) error { + isJSONValue := tag.Get("type") == "jsonvalue" + if isJSONValue { + if len(header) == 0 { + return nil + } + } else if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) { + return nil + } + + switch v.Interface().(type) { + case *string: + v.Set(reflect.ValueOf(&header)) + case []byte: + b, err := base64.StdEncoding.DecodeString(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case *bool: + b, err := strconv.ParseBool(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case *int64: + i, err := strconv.ParseInt(header, 10, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&i)) + case *float64: + f, err := strconv.ParseFloat(header, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&f)) + case *time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.RFC822TimeFormatName + } + t, err := protocol.ParseTime(format, header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&t)) + case aws.JSONValue: + escaping := protocol.NoEscape + if tag.Get("location") == "header" { + escaping = protocol.Base64Escape + } + m, err := protocol.DecodeJSONValue(header, escaping) + if err != nil { + return err + } + v.Set(reflect.ValueOf(m)) + default: + err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go new file mode 100644 index 000000000..cf569645d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go @@ -0,0 +1,79 @@ +// Package restxml provides RESTful XML serialization of AWS +// requests and responses. +package restxml + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-xml.json build_test.go +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-xml.json unmarshal_test.go + +import ( + "bytes" + "encoding/xml" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/query" + "github.com/aws/aws-sdk-go/private/protocol/rest" + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +// BuildHandler is a named request handler for building restxml protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.restxml.Build", Fn: Build} + +// UnmarshalHandler is a named request handler for unmarshaling restxml protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.restxml.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling restxml protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.restxml.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling restxml protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.restxml.UnmarshalError", Fn: UnmarshalError} + +// Build builds a request payload for the REST XML protocol. +func Build(r *request.Request) { + rest.Build(r) + + if t := rest.PayloadType(r.Params); t == "structure" || t == "" { + var buf bytes.Buffer + err := xmlutil.BuildXML(r.Params, xml.NewEncoder(&buf)) + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to encode rest XML request", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + r.SetBufferBody(buf.Bytes()) + } +} + +// Unmarshal unmarshals a payload response for the REST XML protocol. +func Unmarshal(r *request.Request) { + if t := rest.PayloadType(r.Data); t == "structure" || t == "" { + defer r.HTTPResponse.Body.Close() + decoder := xml.NewDecoder(r.HTTPResponse.Body) + err := xmlutil.UnmarshalXML(r.Data, decoder, "") + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to decode REST XML response", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + } else { + rest.Unmarshal(r) + } +} + +// UnmarshalMeta unmarshals response headers for the REST XML protocol. +func UnmarshalMeta(r *request.Request) { + rest.UnmarshalMeta(r) +} + +// UnmarshalError unmarshals a response error for the REST XML protocol. +func UnmarshalError(r *request.Request) { + query.UnmarshalError(r) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go new file mode 100644 index 000000000..b7ed6c6f8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go @@ -0,0 +1,72 @@ +package protocol + +import ( + "strconv" + "time" +) + +// Names of time formats supported by the SDK +const ( + RFC822TimeFormatName = "rfc822" + ISO8601TimeFormatName = "iso8601" + UnixTimeFormatName = "unixTimestamp" +) + +// Time formats supported by the SDK +const ( + // RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT + RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT" + + // RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z + ISO8601TimeFormat = "2006-01-02T15:04:05Z" +) + +// IsKnownTimestampFormat returns if the timestamp format name +// is know to the SDK's protocols. +func IsKnownTimestampFormat(name string) bool { + switch name { + case RFC822TimeFormatName: + fallthrough + case ISO8601TimeFormatName: + fallthrough + case UnixTimeFormatName: + return true + default: + return false + } +} + +// FormatTime returns a string value of the time. +func FormatTime(name string, t time.Time) string { + t = t.UTC() + + switch name { + case RFC822TimeFormatName: + return t.Format(RFC822TimeFormat) + case ISO8601TimeFormatName: + return t.Format(ISO8601TimeFormat) + case UnixTimeFormatName: + return strconv.FormatInt(t.Unix(), 10) + default: + panic("unknown timestamp format name, " + name) + } +} + +// ParseTime attempts to parse the time given the format. Returns +// the time if it was able to be parsed, and fails otherwise. +func ParseTime(formatName, value string) (time.Time, error) { + switch formatName { + case RFC822TimeFormatName: + return time.Parse(RFC822TimeFormat, value) + case ISO8601TimeFormatName: + return time.Parse(ISO8601TimeFormat, value) + case UnixTimeFormatName: + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return time.Time{}, err + } + return time.Unix(int64(v), 0), nil + default: + panic("unknown timestamp format name, " + formatName) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go new file mode 100644 index 000000000..da1a68111 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go @@ -0,0 +1,21 @@ +package protocol + +import ( + "io" + "io/ioutil" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// UnmarshalDiscardBodyHandler is a named request handler to empty and close a response's body +var UnmarshalDiscardBodyHandler = request.NamedHandler{Name: "awssdk.shared.UnmarshalDiscardBody", Fn: UnmarshalDiscardBody} + +// UnmarshalDiscardBody is a request handler to empty a response's body and closing it. +func UnmarshalDiscardBody(r *request.Request) { + if r.HTTPResponse == nil || r.HTTPResponse.Body == nil { + return + } + + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + r.HTTPResponse.Body.Close() +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go new file mode 100644 index 000000000..cf981fe95 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go @@ -0,0 +1,306 @@ +// Package xmlutil provides XML serialization of AWS requests and responses. +package xmlutil + +import ( + "encoding/base64" + "encoding/xml" + "fmt" + "reflect" + "sort" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/private/protocol" +) + +// BuildXML will serialize params into an xml.Encoder. Error will be returned +// if the serialization of any of the params or nested values fails. +func BuildXML(params interface{}, e *xml.Encoder) error { + return buildXML(params, e, false) +} + +func buildXML(params interface{}, e *xml.Encoder, sorted bool) error { + b := xmlBuilder{encoder: e, namespaces: map[string]string{}} + root := NewXMLElement(xml.Name{}) + if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil { + return err + } + for _, c := range root.Children { + for _, v := range c { + return StructToXML(e, v, sorted) + } + } + return nil +} + +// Returns the reflection element of a value, if it is a pointer. +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} + +// A xmlBuilder serializes values from Go code to XML +type xmlBuilder struct { + encoder *xml.Encoder + namespaces map[string]string +} + +// buildValue generic XMLNode builder for any type. Will build value for their specific type +// struct, list, map, scalar. +// +// Also takes a "type" tag value to set what type a value should be converted to XMLNode as. If +// type is not provided reflect will be used to determine the value's type. +func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + value = elemOf(value) + if !value.IsValid() { // no need to handle zero values + return nil + } else if tag.Get("location") != "" { // don't handle non-body location values + return nil + } + + t := tag.Get("type") + if t == "" { + switch value.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + if field, ok := value.Type().FieldByName("_"); ok { + tag = tag + reflect.StructTag(" ") + field.Tag + } + return b.buildStruct(value, current, tag) + case "list": + return b.buildList(value, current, tag) + case "map": + return b.buildMap(value, current, tag) + default: + return b.buildScalar(value, current, tag) + } +} + +// buildStruct adds a struct and its fields to the current XMLNode. All fields and any nested +// types are converted to XMLNodes also. +func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if !value.IsValid() { + return nil + } + + // unwrap payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := value.Type().FieldByName(payload) + tag = field.Tag + value = elemOf(value.FieldByName(payload)) + + if !value.IsValid() { + return nil + } + } + + child := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) + + // there is an xmlNamespace associated with this struct + if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" { + ns := xml.Attr{ + Name: xml.Name{Local: "xmlns"}, + Value: uri, + } + if prefix != "" { + b.namespaces[prefix] = uri // register the namespace + ns.Name.Local = "xmlns:" + prefix + } + + child.Attr = append(child.Attr, ns) + } + + var payloadFields, nonPayloadFields int + + t := value.Type() + for i := 0; i < value.NumField(); i++ { + member := elemOf(value.Field(i)) + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("ignore") != "" { + continue + } + + mTag := field.Tag + if mTag.Get("location") != "" { // skip non-body members + nonPayloadFields++ + continue + } + payloadFields++ + + if protocol.CanSetIdempotencyToken(value.Field(i), field) { + token := protocol.GetIdempotencyToken() + member = reflect.ValueOf(token) + } + + memberName := mTag.Get("locationName") + if memberName == "" { + memberName = field.Name + mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`) + } + if err := b.buildValue(member, child, mTag); err != nil { + return err + } + } + + // Only case where the child shape is not added is if the shape only contains + // non-payload fields, e.g headers/query. + if !(payloadFields == 0 && nonPayloadFields > 0) { + current.AddChild(child) + } + + return nil +} + +// buildList adds the value's list items to the current XMLNode as children nodes. All +// nested values in the list are converted to XMLNodes also. +func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if value.IsNil() { // don't build omitted lists + return nil + } + + // check for unflattened list member + flattened := tag.Get("flattened") != "" + + xname := xml.Name{Local: tag.Get("locationName")} + if flattened { + for i := 0; i < value.Len(); i++ { + child := NewXMLElement(xname) + current.AddChild(child) + if err := b.buildValue(value.Index(i), child, ""); err != nil { + return err + } + } + } else { + list := NewXMLElement(xname) + current.AddChild(list) + + for i := 0; i < value.Len(); i++ { + iname := tag.Get("locationNameList") + if iname == "" { + iname = "member" + } + + child := NewXMLElement(xml.Name{Local: iname}) + list.AddChild(child) + if err := b.buildValue(value.Index(i), child, ""); err != nil { + return err + } + } + } + + return nil +} + +// buildMap adds the value's key/value pairs to the current XMLNode as children nodes. All +// nested values in the map are converted to XMLNodes also. +// +// Error will be returned if it is unable to build the map's values into XMLNodes +func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if value.IsNil() { // don't build omitted maps + return nil + } + + maproot := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) + current.AddChild(maproot) + current = maproot + + kname, vname := "key", "value" + if n := tag.Get("locationNameKey"); n != "" { + kname = n + } + if n := tag.Get("locationNameValue"); n != "" { + vname = n + } + + // sorting is not required for compliance, but it makes testing easier + keys := make([]string, value.Len()) + for i, k := range value.MapKeys() { + keys[i] = k.String() + } + sort.Strings(keys) + + for _, k := range keys { + v := value.MapIndex(reflect.ValueOf(k)) + + mapcur := current + if tag.Get("flattened") == "" { // add "entry" tag to non-flat maps + child := NewXMLElement(xml.Name{Local: "entry"}) + mapcur.AddChild(child) + mapcur = child + } + + kchild := NewXMLElement(xml.Name{Local: kname}) + kchild.Text = k + vchild := NewXMLElement(xml.Name{Local: vname}) + mapcur.AddChild(kchild) + mapcur.AddChild(vchild) + + if err := b.buildValue(v, vchild, ""); err != nil { + return err + } + } + + return nil +} + +// buildScalar will convert the value into a string and append it as a attribute or child +// of the current XMLNode. +// +// The value will be added as an attribute if tag contains a "xmlAttribute" attribute value. +// +// Error will be returned if the value type is unsupported. +func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + var str string + switch converted := value.Interface().(type) { + case string: + str = converted + case []byte: + if !value.IsNil() { + str = base64.StdEncoding.EncodeToString(converted) + } + case bool: + str = strconv.FormatBool(converted) + case int64: + str = strconv.FormatInt(converted, 10) + case int: + str = strconv.Itoa(converted) + case float64: + str = strconv.FormatFloat(converted, 'f', -1, 64) + case float32: + str = strconv.FormatFloat(float64(converted), 'f', -1, 32) + case time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + str = protocol.FormatTime(format, converted) + default: + return fmt.Errorf("unsupported value for param %s: %v (%s)", + tag.Get("locationName"), value.Interface(), value.Type().Name()) + } + + xname := xml.Name{Local: tag.Get("locationName")} + if tag.Get("xmlAttribute") != "" { // put into current node's attribute list + attr := xml.Attr{Name: xname, Value: str} + current.Attr = append(current.Attr, attr) + } else { // regular text node + current.AddChild(&XMLNode{Name: xname, Text: str}) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go new file mode 100644 index 000000000..7108d3800 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go @@ -0,0 +1,291 @@ +package xmlutil + +import ( + "bytes" + "encoding/base64" + "encoding/xml" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// UnmarshalXMLError unmarshals the XML error from the stream into the value +// type specified. The value must be a pointer. If the message fails to +// unmarshal, the message content will be included in the returned error as a +// awserr.UnmarshalError. +func UnmarshalXMLError(v interface{}, stream io.Reader) error { + var errBuf bytes.Buffer + body := io.TeeReader(stream, &errBuf) + + err := xml.NewDecoder(body).Decode(v) + if err != nil && err != io.EOF { + return awserr.NewUnmarshalError(err, + "failed to unmarshal error message", errBuf.Bytes()) + } + + return nil +} + +// UnmarshalXML deserializes an xml.Decoder into the container v. V +// needs to match the shape of the XML expected to be decoded. +// If the shape doesn't match unmarshaling will fail. +func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error { + n, err := XMLToStruct(d, nil) + if err != nil { + return err + } + if n.Children != nil { + for _, root := range n.Children { + for _, c := range root { + if wrappedChild, ok := c.Children[wrapper]; ok { + c = wrappedChild[0] // pull out wrapped element + } + + err = parse(reflect.ValueOf(v), c, "") + if err != nil { + if err == io.EOF { + return nil + } + return err + } + } + } + return nil + } + return nil +} + +// parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect +// will be used to determine the type from r. +func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + rtype := r.Type() + if rtype.Kind() == reflect.Ptr { + rtype = rtype.Elem() // check kind of actual element type + } + + t := tag.Get("type") + if t == "" { + switch rtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if _, ok := r.Interface().(*time.Time); !ok { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := r.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + if field, ok := rtype.FieldByName("_"); ok { + tag = field.Tag + } + return parseStruct(r, node, tag) + case "list": + return parseList(r, node, tag) + case "map": + return parseMap(r, node, tag) + default: + return parseScalar(r, node, tag) + } +} + +// parseStruct deserializes a structure and its fields from an XMLNode. Any nested +// types in the structure will also be deserialized. +func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + t := r.Type() + if r.Kind() == reflect.Ptr { + if r.IsNil() { // create the structure if it's nil + s := reflect.New(r.Type().Elem()) + r.Set(s) + r = s + } + + r = r.Elem() + t = t.Elem() + } + + // unwrap any payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := t.FieldByName(payload) + return parseStruct(r.FieldByName(payload), node, field.Tag) + } + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if c := field.Name[0:1]; strings.ToLower(c) == c { + continue // ignore unexported fields + } + + // figure out what this field is called + name := field.Name + if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { + name = field.Tag.Get("locationNameList") + } else if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + // try to find the field by name in elements + elems := node.Children[name] + + if elems == nil { // try to find the field in attributes + if val, ok := node.findElem(name); ok { + elems = []*XMLNode{{Text: val}} + } + } + + member := r.FieldByName(field.Name) + for _, elem := range elems { + err := parse(member, elem, field.Tag) + if err != nil { + return err + } + } + } + return nil +} + +// parseList deserializes a list of values from an XML node. Each list entry +// will also be deserialized. +func parseList(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + t := r.Type() + + if tag.Get("flattened") == "" { // look at all item entries + mname := "member" + if name := tag.Get("locationNameList"); name != "" { + mname = name + } + + if Children, ok := node.Children[mname]; ok { + if r.IsNil() { + r.Set(reflect.MakeSlice(t, len(Children), len(Children))) + } + + for i, c := range Children { + err := parse(r.Index(i), c, "") + if err != nil { + return err + } + } + } + } else { // flattened list means this is a single element + if r.IsNil() { + r.Set(reflect.MakeSlice(t, 0, 0)) + } + + childR := reflect.Zero(t.Elem()) + r.Set(reflect.Append(r, childR)) + err := parse(r.Index(r.Len()-1), node, "") + if err != nil { + return err + } + } + + return nil +} + +// parseMap deserializes a map from an XMLNode. The direct children of the XMLNode +// will also be deserialized as map entries. +func parseMap(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + if r.IsNil() { + r.Set(reflect.MakeMap(r.Type())) + } + + if tag.Get("flattened") == "" { // look at all child entries + for _, entry := range node.Children["entry"] { + parseMapEntry(r, entry, tag) + } + } else { // this element is itself an entry + parseMapEntry(r, node, tag) + } + + return nil +} + +// parseMapEntry deserializes a map entry from a XML node. +func parseMapEntry(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + kname, vname := "key", "value" + if n := tag.Get("locationNameKey"); n != "" { + kname = n + } + if n := tag.Get("locationNameValue"); n != "" { + vname = n + } + + keys, ok := node.Children[kname] + values := node.Children[vname] + if ok { + for i, key := range keys { + keyR := reflect.ValueOf(key.Text) + value := values[i] + valueR := reflect.New(r.Type().Elem()).Elem() + + parse(valueR, value, "") + r.SetMapIndex(keyR, valueR) + } + } + return nil +} + +// parseScaller deserializes an XMLNode value into a concrete type based on the +// interface type of r. +// +// Error is returned if the deserialization fails due to invalid type conversion, +// or unsupported interface type. +func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + switch r.Interface().(type) { + case *string: + r.Set(reflect.ValueOf(&node.Text)) + return nil + case []byte: + b, err := base64.StdEncoding.DecodeString(node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(b)) + case *bool: + v, err := strconv.ParseBool(node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *int64: + v, err := strconv.ParseInt(node.Text, 10, 64) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *float64: + v, err := strconv.ParseFloat(node.Text, 64) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + t, err := protocol.ParseTime(format, node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&t)) + default: + return fmt.Errorf("unsupported value: %v (%s)", r.Interface(), r.Type()) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go new file mode 100644 index 000000000..515ce1521 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go @@ -0,0 +1,148 @@ +package xmlutil + +import ( + "encoding/xml" + "fmt" + "io" + "sort" +) + +// A XMLNode contains the values to be encoded or decoded. +type XMLNode struct { + Name xml.Name `json:",omitempty"` + Children map[string][]*XMLNode `json:",omitempty"` + Text string `json:",omitempty"` + Attr []xml.Attr `json:",omitempty"` + + namespaces map[string]string + parent *XMLNode +} + +// NewXMLElement returns a pointer to a new XMLNode initialized to default values. +func NewXMLElement(name xml.Name) *XMLNode { + return &XMLNode{ + Name: name, + Children: map[string][]*XMLNode{}, + Attr: []xml.Attr{}, + } +} + +// AddChild adds child to the XMLNode. +func (n *XMLNode) AddChild(child *XMLNode) { + child.parent = n + if _, ok := n.Children[child.Name.Local]; !ok { + n.Children[child.Name.Local] = []*XMLNode{} + } + n.Children[child.Name.Local] = append(n.Children[child.Name.Local], child) +} + +// XMLToStruct converts a xml.Decoder stream to XMLNode with nested values. +func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) { + out := &XMLNode{} + for { + tok, err := d.Token() + if err != nil { + if err == io.EOF { + break + } else { + return out, err + } + } + + if tok == nil { + break + } + + switch typed := tok.(type) { + case xml.CharData: + out.Text = string(typed.Copy()) + case xml.StartElement: + el := typed.Copy() + out.Attr = el.Attr + if out.Children == nil { + out.Children = map[string][]*XMLNode{} + } + + name := typed.Name.Local + slice := out.Children[name] + if slice == nil { + slice = []*XMLNode{} + } + node, e := XMLToStruct(d, &el) + out.findNamespaces() + if e != nil { + return out, e + } + node.Name = typed.Name + node.findNamespaces() + tempOut := *out + // Save into a temp variable, simply because out gets squashed during + // loop iterations + node.parent = &tempOut + slice = append(slice, node) + out.Children[name] = slice + case xml.EndElement: + if s != nil && s.Name.Local == typed.Name.Local { // matching end token + return out, nil + } + out = &XMLNode{} + } + } + return out, nil +} + +func (n *XMLNode) findNamespaces() { + ns := map[string]string{} + for _, a := range n.Attr { + if a.Name.Space == "xmlns" { + ns[a.Value] = a.Name.Local + } + } + + n.namespaces = ns +} + +func (n *XMLNode) findElem(name string) (string, bool) { + for node := n; node != nil; node = node.parent { + for _, a := range node.Attr { + namespace := a.Name.Space + if v, ok := node.namespaces[namespace]; ok { + namespace = v + } + if name == fmt.Sprintf("%s:%s", namespace, a.Name.Local) { + return a.Value, true + } + } + } + return "", false +} + +// StructToXML writes an XMLNode to a xml.Encoder as tokens. +func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error { + e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr}) + + if node.Text != "" { + e.EncodeToken(xml.CharData([]byte(node.Text))) + } else if sorted { + sortedNames := []string{} + for k := range node.Children { + sortedNames = append(sortedNames, k) + } + sort.Strings(sortedNames) + + for _, k := range sortedNames { + for _, v := range node.Children[k] { + StructToXML(e, v, sorted) + } + } + } else { + for _, c := range node.Children { + for _, v := range c { + StructToXML(e, v, sorted) + } + } + } + + e.EncodeToken(xml.EndElement{Name: node.Name}) + return e.Flush() +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/lightsail/api.go b/vendor/github.com/aws/aws-sdk-go/service/lightsail/api.go new file mode 100644 index 000000000..5d7c5a33f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/lightsail/api.go @@ -0,0 +1,24271 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package lightsail + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" +) + +const opAllocateStaticIp = "AllocateStaticIp" + +// AllocateStaticIpRequest generates a "aws/request.Request" representing the +// client's request for the AllocateStaticIp operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AllocateStaticIp for more information on using the AllocateStaticIp +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AllocateStaticIpRequest method. +// req, resp := client.AllocateStaticIpRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AllocateStaticIp +func (c *Lightsail) AllocateStaticIpRequest(input *AllocateStaticIpInput) (req *request.Request, output *AllocateStaticIpOutput) { + op := &request.Operation{ + Name: opAllocateStaticIp, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AllocateStaticIpInput{} + } + + output = &AllocateStaticIpOutput{} + req = c.newRequest(op, input, output) + return +} + +// AllocateStaticIp API operation for Amazon Lightsail. +// +// Allocates a static IP address. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation AllocateStaticIp for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AllocateStaticIp +func (c *Lightsail) AllocateStaticIp(input *AllocateStaticIpInput) (*AllocateStaticIpOutput, error) { + req, out := c.AllocateStaticIpRequest(input) + return out, req.Send() +} + +// AllocateStaticIpWithContext is the same as AllocateStaticIp with the addition of +// the ability to pass a context and additional request options. +// +// See AllocateStaticIp for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) AllocateStaticIpWithContext(ctx aws.Context, input *AllocateStaticIpInput, opts ...request.Option) (*AllocateStaticIpOutput, error) { + req, out := c.AllocateStaticIpRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAttachDisk = "AttachDisk" + +// AttachDiskRequest generates a "aws/request.Request" representing the +// client's request for the AttachDisk operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AttachDisk for more information on using the AttachDisk +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AttachDiskRequest method. +// req, resp := client.AttachDiskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AttachDisk +func (c *Lightsail) AttachDiskRequest(input *AttachDiskInput) (req *request.Request, output *AttachDiskOutput) { + op := &request.Operation{ + Name: opAttachDisk, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachDiskInput{} + } + + output = &AttachDiskOutput{} + req = c.newRequest(op, input, output) + return +} + +// AttachDisk API operation for Amazon Lightsail. +// +// Attaches a block storage disk to a running or stopped Lightsail instance +// and exposes it to the instance with the specified disk name. +// +// The attach disk operation supports tag-based access control via resource +// tags applied to the resource identified by diskName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation AttachDisk for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AttachDisk +func (c *Lightsail) AttachDisk(input *AttachDiskInput) (*AttachDiskOutput, error) { + req, out := c.AttachDiskRequest(input) + return out, req.Send() +} + +// AttachDiskWithContext is the same as AttachDisk with the addition of +// the ability to pass a context and additional request options. +// +// See AttachDisk for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) AttachDiskWithContext(ctx aws.Context, input *AttachDiskInput, opts ...request.Option) (*AttachDiskOutput, error) { + req, out := c.AttachDiskRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAttachInstancesToLoadBalancer = "AttachInstancesToLoadBalancer" + +// AttachInstancesToLoadBalancerRequest generates a "aws/request.Request" representing the +// client's request for the AttachInstancesToLoadBalancer operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AttachInstancesToLoadBalancer for more information on using the AttachInstancesToLoadBalancer +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AttachInstancesToLoadBalancerRequest method. +// req, resp := client.AttachInstancesToLoadBalancerRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AttachInstancesToLoadBalancer +func (c *Lightsail) AttachInstancesToLoadBalancerRequest(input *AttachInstancesToLoadBalancerInput) (req *request.Request, output *AttachInstancesToLoadBalancerOutput) { + op := &request.Operation{ + Name: opAttachInstancesToLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachInstancesToLoadBalancerInput{} + } + + output = &AttachInstancesToLoadBalancerOutput{} + req = c.newRequest(op, input, output) + return +} + +// AttachInstancesToLoadBalancer API operation for Amazon Lightsail. +// +// Attaches one or more Lightsail instances to a load balancer. +// +// After some time, the instances are attached to the load balancer and the +// health check status is available. +// +// The attach instances to load balancer operation supports tag-based access +// control via resource tags applied to the resource identified by loadBalancerName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation AttachInstancesToLoadBalancer for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AttachInstancesToLoadBalancer +func (c *Lightsail) AttachInstancesToLoadBalancer(input *AttachInstancesToLoadBalancerInput) (*AttachInstancesToLoadBalancerOutput, error) { + req, out := c.AttachInstancesToLoadBalancerRequest(input) + return out, req.Send() +} + +// AttachInstancesToLoadBalancerWithContext is the same as AttachInstancesToLoadBalancer with the addition of +// the ability to pass a context and additional request options. +// +// See AttachInstancesToLoadBalancer for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) AttachInstancesToLoadBalancerWithContext(ctx aws.Context, input *AttachInstancesToLoadBalancerInput, opts ...request.Option) (*AttachInstancesToLoadBalancerOutput, error) { + req, out := c.AttachInstancesToLoadBalancerRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAttachLoadBalancerTlsCertificate = "AttachLoadBalancerTlsCertificate" + +// AttachLoadBalancerTlsCertificateRequest generates a "aws/request.Request" representing the +// client's request for the AttachLoadBalancerTlsCertificate operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AttachLoadBalancerTlsCertificate for more information on using the AttachLoadBalancerTlsCertificate +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AttachLoadBalancerTlsCertificateRequest method. +// req, resp := client.AttachLoadBalancerTlsCertificateRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AttachLoadBalancerTlsCertificate +func (c *Lightsail) AttachLoadBalancerTlsCertificateRequest(input *AttachLoadBalancerTlsCertificateInput) (req *request.Request, output *AttachLoadBalancerTlsCertificateOutput) { + op := &request.Operation{ + Name: opAttachLoadBalancerTlsCertificate, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachLoadBalancerTlsCertificateInput{} + } + + output = &AttachLoadBalancerTlsCertificateOutput{} + req = c.newRequest(op, input, output) + return +} + +// AttachLoadBalancerTlsCertificate API operation for Amazon Lightsail. +// +// Attaches a Transport Layer Security (TLS) certificate to your load balancer. +// TLS is just an updated, more secure version of Secure Socket Layer (SSL). +// +// Once you create and validate your certificate, you can attach it to your +// load balancer. You can also use this API to rotate the certificates on your +// account. Use the AttachLoadBalancerTlsCertificate operation with the non-attached +// certificate, and it will replace the existing one and become the attached +// certificate. +// +// The attach load balancer tls certificate operation supports tag-based access +// control via resource tags applied to the resource identified by loadBalancerName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation AttachLoadBalancerTlsCertificate for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AttachLoadBalancerTlsCertificate +func (c *Lightsail) AttachLoadBalancerTlsCertificate(input *AttachLoadBalancerTlsCertificateInput) (*AttachLoadBalancerTlsCertificateOutput, error) { + req, out := c.AttachLoadBalancerTlsCertificateRequest(input) + return out, req.Send() +} + +// AttachLoadBalancerTlsCertificateWithContext is the same as AttachLoadBalancerTlsCertificate with the addition of +// the ability to pass a context and additional request options. +// +// See AttachLoadBalancerTlsCertificate for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) AttachLoadBalancerTlsCertificateWithContext(ctx aws.Context, input *AttachLoadBalancerTlsCertificateInput, opts ...request.Option) (*AttachLoadBalancerTlsCertificateOutput, error) { + req, out := c.AttachLoadBalancerTlsCertificateRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAttachStaticIp = "AttachStaticIp" + +// AttachStaticIpRequest generates a "aws/request.Request" representing the +// client's request for the AttachStaticIp operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AttachStaticIp for more information on using the AttachStaticIp +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AttachStaticIpRequest method. +// req, resp := client.AttachStaticIpRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AttachStaticIp +func (c *Lightsail) AttachStaticIpRequest(input *AttachStaticIpInput) (req *request.Request, output *AttachStaticIpOutput) { + op := &request.Operation{ + Name: opAttachStaticIp, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AttachStaticIpInput{} + } + + output = &AttachStaticIpOutput{} + req = c.newRequest(op, input, output) + return +} + +// AttachStaticIp API operation for Amazon Lightsail. +// +// Attaches a static IP address to a specific Amazon Lightsail instance. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation AttachStaticIp for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/AttachStaticIp +func (c *Lightsail) AttachStaticIp(input *AttachStaticIpInput) (*AttachStaticIpOutput, error) { + req, out := c.AttachStaticIpRequest(input) + return out, req.Send() +} + +// AttachStaticIpWithContext is the same as AttachStaticIp with the addition of +// the ability to pass a context and additional request options. +// +// See AttachStaticIp for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) AttachStaticIpWithContext(ctx aws.Context, input *AttachStaticIpInput, opts ...request.Option) (*AttachStaticIpOutput, error) { + req, out := c.AttachStaticIpRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCloseInstancePublicPorts = "CloseInstancePublicPorts" + +// CloseInstancePublicPortsRequest generates a "aws/request.Request" representing the +// client's request for the CloseInstancePublicPorts operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CloseInstancePublicPorts for more information on using the CloseInstancePublicPorts +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CloseInstancePublicPortsRequest method. +// req, resp := client.CloseInstancePublicPortsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CloseInstancePublicPorts +func (c *Lightsail) CloseInstancePublicPortsRequest(input *CloseInstancePublicPortsInput) (req *request.Request, output *CloseInstancePublicPortsOutput) { + op := &request.Operation{ + Name: opCloseInstancePublicPorts, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CloseInstancePublicPortsInput{} + } + + output = &CloseInstancePublicPortsOutput{} + req = c.newRequest(op, input, output) + return +} + +// CloseInstancePublicPorts API operation for Amazon Lightsail. +// +// Closes the public ports on a specific Amazon Lightsail instance. +// +// The close instance public ports operation supports tag-based access control +// via resource tags applied to the resource identified by instanceName. For +// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CloseInstancePublicPorts for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CloseInstancePublicPorts +func (c *Lightsail) CloseInstancePublicPorts(input *CloseInstancePublicPortsInput) (*CloseInstancePublicPortsOutput, error) { + req, out := c.CloseInstancePublicPortsRequest(input) + return out, req.Send() +} + +// CloseInstancePublicPortsWithContext is the same as CloseInstancePublicPorts with the addition of +// the ability to pass a context and additional request options. +// +// See CloseInstancePublicPorts for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CloseInstancePublicPortsWithContext(ctx aws.Context, input *CloseInstancePublicPortsInput, opts ...request.Option) (*CloseInstancePublicPortsOutput, error) { + req, out := c.CloseInstancePublicPortsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCopySnapshot = "CopySnapshot" + +// CopySnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CopySnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CopySnapshot for more information on using the CopySnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CopySnapshotRequest method. +// req, resp := client.CopySnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CopySnapshot +func (c *Lightsail) CopySnapshotRequest(input *CopySnapshotInput) (req *request.Request, output *CopySnapshotOutput) { + op := &request.Operation{ + Name: opCopySnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CopySnapshotInput{} + } + + output = &CopySnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// CopySnapshot API operation for Amazon Lightsail. +// +// Copies an instance or disk snapshot from one AWS Region to another in Amazon +// Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CopySnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CopySnapshot +func (c *Lightsail) CopySnapshot(input *CopySnapshotInput) (*CopySnapshotOutput, error) { + req, out := c.CopySnapshotRequest(input) + return out, req.Send() +} + +// CopySnapshotWithContext is the same as CopySnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See CopySnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CopySnapshotWithContext(ctx aws.Context, input *CopySnapshotInput, opts ...request.Option) (*CopySnapshotOutput, error) { + req, out := c.CopySnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateCloudFormationStack = "CreateCloudFormationStack" + +// CreateCloudFormationStackRequest generates a "aws/request.Request" representing the +// client's request for the CreateCloudFormationStack operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateCloudFormationStack for more information on using the CreateCloudFormationStack +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateCloudFormationStackRequest method. +// req, resp := client.CreateCloudFormationStackRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateCloudFormationStack +func (c *Lightsail) CreateCloudFormationStackRequest(input *CreateCloudFormationStackInput) (req *request.Request, output *CreateCloudFormationStackOutput) { + op := &request.Operation{ + Name: opCreateCloudFormationStack, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateCloudFormationStackInput{} + } + + output = &CreateCloudFormationStackOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateCloudFormationStack API operation for Amazon Lightsail. +// +// Creates an AWS CloudFormation stack, which creates a new Amazon EC2 instance +// from an exported Amazon Lightsail snapshot. This operation results in a CloudFormation +// stack record that can be used to track the AWS CloudFormation stack created. +// Use the get cloud formation stack records operation to get a list of the +// CloudFormation stacks created. +// +// Wait until after your new Amazon EC2 instance is created before running the +// create cloud formation stack operation again with the same export snapshot +// record. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateCloudFormationStack for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateCloudFormationStack +func (c *Lightsail) CreateCloudFormationStack(input *CreateCloudFormationStackInput) (*CreateCloudFormationStackOutput, error) { + req, out := c.CreateCloudFormationStackRequest(input) + return out, req.Send() +} + +// CreateCloudFormationStackWithContext is the same as CreateCloudFormationStack with the addition of +// the ability to pass a context and additional request options. +// +// See CreateCloudFormationStack for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateCloudFormationStackWithContext(ctx aws.Context, input *CreateCloudFormationStackInput, opts ...request.Option) (*CreateCloudFormationStackOutput, error) { + req, out := c.CreateCloudFormationStackRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateDisk = "CreateDisk" + +// CreateDiskRequest generates a "aws/request.Request" representing the +// client's request for the CreateDisk operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateDisk for more information on using the CreateDisk +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateDiskRequest method. +// req, resp := client.CreateDiskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDisk +func (c *Lightsail) CreateDiskRequest(input *CreateDiskInput) (req *request.Request, output *CreateDiskOutput) { + op := &request.Operation{ + Name: opCreateDisk, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDiskInput{} + } + + output = &CreateDiskOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDisk API operation for Amazon Lightsail. +// +// Creates a block storage disk that can be attached to a Lightsail instance +// in the same Availability Zone (e.g., us-east-2a). The disk is created in +// the regional endpoint that you send the HTTP request to. For more information, +// see Regions and Availability Zones in Lightsail (https://lightsail.aws.amazon.com/ls/docs/overview/article/understanding-regions-and-availability-zones-in-amazon-lightsail). +// +// The create disk operation supports tag-based access control via request tags. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateDisk for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDisk +func (c *Lightsail) CreateDisk(input *CreateDiskInput) (*CreateDiskOutput, error) { + req, out := c.CreateDiskRequest(input) + return out, req.Send() +} + +// CreateDiskWithContext is the same as CreateDisk with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDisk for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateDiskWithContext(ctx aws.Context, input *CreateDiskInput, opts ...request.Option) (*CreateDiskOutput, error) { + req, out := c.CreateDiskRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateDiskFromSnapshot = "CreateDiskFromSnapshot" + +// CreateDiskFromSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CreateDiskFromSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateDiskFromSnapshot for more information on using the CreateDiskFromSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateDiskFromSnapshotRequest method. +// req, resp := client.CreateDiskFromSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDiskFromSnapshot +func (c *Lightsail) CreateDiskFromSnapshotRequest(input *CreateDiskFromSnapshotInput) (req *request.Request, output *CreateDiskFromSnapshotOutput) { + op := &request.Operation{ + Name: opCreateDiskFromSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDiskFromSnapshotInput{} + } + + output = &CreateDiskFromSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDiskFromSnapshot API operation for Amazon Lightsail. +// +// Creates a block storage disk from a disk snapshot that can be attached to +// a Lightsail instance in the same Availability Zone (e.g., us-east-2a). The +// disk is created in the regional endpoint that you send the HTTP request to. +// For more information, see Regions and Availability Zones in Lightsail (https://lightsail.aws.amazon.com/ls/docs/overview/article/understanding-regions-and-availability-zones-in-amazon-lightsail). +// +// The create disk from snapshot operation supports tag-based access control +// via request tags and resource tags applied to the resource identified by +// diskSnapshotName. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateDiskFromSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDiskFromSnapshot +func (c *Lightsail) CreateDiskFromSnapshot(input *CreateDiskFromSnapshotInput) (*CreateDiskFromSnapshotOutput, error) { + req, out := c.CreateDiskFromSnapshotRequest(input) + return out, req.Send() +} + +// CreateDiskFromSnapshotWithContext is the same as CreateDiskFromSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDiskFromSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateDiskFromSnapshotWithContext(ctx aws.Context, input *CreateDiskFromSnapshotInput, opts ...request.Option) (*CreateDiskFromSnapshotOutput, error) { + req, out := c.CreateDiskFromSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateDiskSnapshot = "CreateDiskSnapshot" + +// CreateDiskSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CreateDiskSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateDiskSnapshot for more information on using the CreateDiskSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateDiskSnapshotRequest method. +// req, resp := client.CreateDiskSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDiskSnapshot +func (c *Lightsail) CreateDiskSnapshotRequest(input *CreateDiskSnapshotInput) (req *request.Request, output *CreateDiskSnapshotOutput) { + op := &request.Operation{ + Name: opCreateDiskSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDiskSnapshotInput{} + } + + output = &CreateDiskSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDiskSnapshot API operation for Amazon Lightsail. +// +// Creates a snapshot of a block storage disk. You can use snapshots for backups, +// to make copies of disks, and to save data before shutting down a Lightsail +// instance. +// +// You can take a snapshot of an attached disk that is in use; however, snapshots +// only capture data that has been written to your disk at the time the snapshot +// command is issued. This may exclude any data that has been cached by any +// applications or the operating system. If you can pause any file systems on +// the disk long enough to take a snapshot, your snapshot should be complete. +// Nevertheless, if you cannot pause all file writes to the disk, you should +// unmount the disk from within the Lightsail instance, issue the create disk +// snapshot command, and then remount the disk to ensure a consistent and complete +// snapshot. You may remount and use your disk while the snapshot status is +// pending. +// +// You can also use this operation to create a snapshot of an instance's system +// volume. You might want to do this, for example, to recover data from the +// system volume of a botched instance or to create a backup of the system volume +// like you would for a block storage disk. To create a snapshot of a system +// volume, just define the instance name parameter when issuing the snapshot +// command, and a snapshot of the defined instance's system volume will be created. +// After the snapshot is available, you can create a block storage disk from +// the snapshot and attach it to a running instance to access the data on the +// disk. +// +// The create disk snapshot operation supports tag-based access control via +// request tags. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateDiskSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDiskSnapshot +func (c *Lightsail) CreateDiskSnapshot(input *CreateDiskSnapshotInput) (*CreateDiskSnapshotOutput, error) { + req, out := c.CreateDiskSnapshotRequest(input) + return out, req.Send() +} + +// CreateDiskSnapshotWithContext is the same as CreateDiskSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDiskSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateDiskSnapshotWithContext(ctx aws.Context, input *CreateDiskSnapshotInput, opts ...request.Option) (*CreateDiskSnapshotOutput, error) { + req, out := c.CreateDiskSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateDomain = "CreateDomain" + +// CreateDomainRequest generates a "aws/request.Request" representing the +// client's request for the CreateDomain operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateDomain for more information on using the CreateDomain +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateDomainRequest method. +// req, resp := client.CreateDomainRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDomain +func (c *Lightsail) CreateDomainRequest(input *CreateDomainInput) (req *request.Request, output *CreateDomainOutput) { + op := &request.Operation{ + Name: opCreateDomain, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDomainInput{} + } + + output = &CreateDomainOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDomain API operation for Amazon Lightsail. +// +// Creates a domain resource for the specified domain (e.g., example.com). +// +// The create domain operation supports tag-based access control via request +// tags. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateDomain for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDomain +func (c *Lightsail) CreateDomain(input *CreateDomainInput) (*CreateDomainOutput, error) { + req, out := c.CreateDomainRequest(input) + return out, req.Send() +} + +// CreateDomainWithContext is the same as CreateDomain with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDomain for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateDomainWithContext(ctx aws.Context, input *CreateDomainInput, opts ...request.Option) (*CreateDomainOutput, error) { + req, out := c.CreateDomainRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateDomainEntry = "CreateDomainEntry" + +// CreateDomainEntryRequest generates a "aws/request.Request" representing the +// client's request for the CreateDomainEntry operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateDomainEntry for more information on using the CreateDomainEntry +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateDomainEntryRequest method. +// req, resp := client.CreateDomainEntryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDomainEntry +func (c *Lightsail) CreateDomainEntryRequest(input *CreateDomainEntryInput) (req *request.Request, output *CreateDomainEntryOutput) { + op := &request.Operation{ + Name: opCreateDomainEntry, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateDomainEntryInput{} + } + + output = &CreateDomainEntryOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateDomainEntry API operation for Amazon Lightsail. +// +// Creates one of the following entry records associated with the domain: Address +// (A), canonical name (CNAME), mail exchanger (MX), name server (NS), start +// of authority (SOA), service locator (SRV), or text (TXT). +// +// The create domain entry operation supports tag-based access control via resource +// tags applied to the resource identified by domainName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateDomainEntry for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateDomainEntry +func (c *Lightsail) CreateDomainEntry(input *CreateDomainEntryInput) (*CreateDomainEntryOutput, error) { + req, out := c.CreateDomainEntryRequest(input) + return out, req.Send() +} + +// CreateDomainEntryWithContext is the same as CreateDomainEntry with the addition of +// the ability to pass a context and additional request options. +// +// See CreateDomainEntry for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateDomainEntryWithContext(ctx aws.Context, input *CreateDomainEntryInput, opts ...request.Option) (*CreateDomainEntryOutput, error) { + req, out := c.CreateDomainEntryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateInstanceSnapshot = "CreateInstanceSnapshot" + +// CreateInstanceSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CreateInstanceSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateInstanceSnapshot for more information on using the CreateInstanceSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateInstanceSnapshotRequest method. +// req, resp := client.CreateInstanceSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateInstanceSnapshot +func (c *Lightsail) CreateInstanceSnapshotRequest(input *CreateInstanceSnapshotInput) (req *request.Request, output *CreateInstanceSnapshotOutput) { + op := &request.Operation{ + Name: opCreateInstanceSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateInstanceSnapshotInput{} + } + + output = &CreateInstanceSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateInstanceSnapshot API operation for Amazon Lightsail. +// +// Creates a snapshot of a specific virtual private server, or instance. You +// can use a snapshot to create a new instance that is based on that snapshot. +// +// The create instance snapshot operation supports tag-based access control +// via request tags. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateInstanceSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateInstanceSnapshot +func (c *Lightsail) CreateInstanceSnapshot(input *CreateInstanceSnapshotInput) (*CreateInstanceSnapshotOutput, error) { + req, out := c.CreateInstanceSnapshotRequest(input) + return out, req.Send() +} + +// CreateInstanceSnapshotWithContext is the same as CreateInstanceSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See CreateInstanceSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateInstanceSnapshotWithContext(ctx aws.Context, input *CreateInstanceSnapshotInput, opts ...request.Option) (*CreateInstanceSnapshotOutput, error) { + req, out := c.CreateInstanceSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateInstances = "CreateInstances" + +// CreateInstancesRequest generates a "aws/request.Request" representing the +// client's request for the CreateInstances operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateInstances for more information on using the CreateInstances +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateInstancesRequest method. +// req, resp := client.CreateInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateInstances +func (c *Lightsail) CreateInstancesRequest(input *CreateInstancesInput) (req *request.Request, output *CreateInstancesOutput) { + op := &request.Operation{ + Name: opCreateInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateInstancesInput{} + } + + output = &CreateInstancesOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateInstances API operation for Amazon Lightsail. +// +// Creates one or more Amazon Lightsail virtual private servers, or instances. +// Create instances using active blueprints. Inactive blueprints are listed +// to support customers with existing instances but are not necessarily available +// for launch of new instances. Blueprints are marked inactive when they become +// outdated due to operating system updates or new application releases. Use +// the get blueprints operation to return a list of available blueprints. +// +// The create instances operation supports tag-based access control via request +// tags. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateInstances for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateInstances +func (c *Lightsail) CreateInstances(input *CreateInstancesInput) (*CreateInstancesOutput, error) { + req, out := c.CreateInstancesRequest(input) + return out, req.Send() +} + +// CreateInstancesWithContext is the same as CreateInstances with the addition of +// the ability to pass a context and additional request options. +// +// See CreateInstances for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateInstancesWithContext(ctx aws.Context, input *CreateInstancesInput, opts ...request.Option) (*CreateInstancesOutput, error) { + req, out := c.CreateInstancesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateInstancesFromSnapshot = "CreateInstancesFromSnapshot" + +// CreateInstancesFromSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CreateInstancesFromSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateInstancesFromSnapshot for more information on using the CreateInstancesFromSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateInstancesFromSnapshotRequest method. +// req, resp := client.CreateInstancesFromSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateInstancesFromSnapshot +func (c *Lightsail) CreateInstancesFromSnapshotRequest(input *CreateInstancesFromSnapshotInput) (req *request.Request, output *CreateInstancesFromSnapshotOutput) { + op := &request.Operation{ + Name: opCreateInstancesFromSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateInstancesFromSnapshotInput{} + } + + output = &CreateInstancesFromSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateInstancesFromSnapshot API operation for Amazon Lightsail. +// +// Uses a specific snapshot as a blueprint for creating one or more new instances +// that are based on that identical configuration. +// +// The create instances from snapshot operation supports tag-based access control +// via request tags and resource tags applied to the resource identified by +// instanceSnapshotName. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateInstancesFromSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateInstancesFromSnapshot +func (c *Lightsail) CreateInstancesFromSnapshot(input *CreateInstancesFromSnapshotInput) (*CreateInstancesFromSnapshotOutput, error) { + req, out := c.CreateInstancesFromSnapshotRequest(input) + return out, req.Send() +} + +// CreateInstancesFromSnapshotWithContext is the same as CreateInstancesFromSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See CreateInstancesFromSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateInstancesFromSnapshotWithContext(ctx aws.Context, input *CreateInstancesFromSnapshotInput, opts ...request.Option) (*CreateInstancesFromSnapshotOutput, error) { + req, out := c.CreateInstancesFromSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateKeyPair = "CreateKeyPair" + +// CreateKeyPairRequest generates a "aws/request.Request" representing the +// client's request for the CreateKeyPair operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateKeyPair for more information on using the CreateKeyPair +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateKeyPairRequest method. +// req, resp := client.CreateKeyPairRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateKeyPair +func (c *Lightsail) CreateKeyPairRequest(input *CreateKeyPairInput) (req *request.Request, output *CreateKeyPairOutput) { + op := &request.Operation{ + Name: opCreateKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateKeyPairInput{} + } + + output = &CreateKeyPairOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateKeyPair API operation for Amazon Lightsail. +// +// Creates an SSH key pair. +// +// The create key pair operation supports tag-based access control via request +// tags. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateKeyPair for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateKeyPair +func (c *Lightsail) CreateKeyPair(input *CreateKeyPairInput) (*CreateKeyPairOutput, error) { + req, out := c.CreateKeyPairRequest(input) + return out, req.Send() +} + +// CreateKeyPairWithContext is the same as CreateKeyPair with the addition of +// the ability to pass a context and additional request options. +// +// See CreateKeyPair for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateKeyPairWithContext(ctx aws.Context, input *CreateKeyPairInput, opts ...request.Option) (*CreateKeyPairOutput, error) { + req, out := c.CreateKeyPairRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateLoadBalancer = "CreateLoadBalancer" + +// CreateLoadBalancerRequest generates a "aws/request.Request" representing the +// client's request for the CreateLoadBalancer operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateLoadBalancer for more information on using the CreateLoadBalancer +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateLoadBalancerRequest method. +// req, resp := client.CreateLoadBalancerRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateLoadBalancer +func (c *Lightsail) CreateLoadBalancerRequest(input *CreateLoadBalancerInput) (req *request.Request, output *CreateLoadBalancerOutput) { + op := &request.Operation{ + Name: opCreateLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateLoadBalancerInput{} + } + + output = &CreateLoadBalancerOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateLoadBalancer API operation for Amazon Lightsail. +// +// Creates a Lightsail load balancer. To learn more about deciding whether to +// load balance your application, see Configure your Lightsail instances for +// load balancing (https://lightsail.aws.amazon.com/ls/docs/how-to/article/configure-lightsail-instances-for-load-balancing). +// You can create up to 5 load balancers per AWS Region in your account. +// +// When you create a load balancer, you can specify a unique name and port settings. +// To change additional load balancer settings, use the UpdateLoadBalancerAttribute +// operation. +// +// The create load balancer operation supports tag-based access control via +// request tags. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateLoadBalancer for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateLoadBalancer +func (c *Lightsail) CreateLoadBalancer(input *CreateLoadBalancerInput) (*CreateLoadBalancerOutput, error) { + req, out := c.CreateLoadBalancerRequest(input) + return out, req.Send() +} + +// CreateLoadBalancerWithContext is the same as CreateLoadBalancer with the addition of +// the ability to pass a context and additional request options. +// +// See CreateLoadBalancer for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateLoadBalancerWithContext(ctx aws.Context, input *CreateLoadBalancerInput, opts ...request.Option) (*CreateLoadBalancerOutput, error) { + req, out := c.CreateLoadBalancerRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateLoadBalancerTlsCertificate = "CreateLoadBalancerTlsCertificate" + +// CreateLoadBalancerTlsCertificateRequest generates a "aws/request.Request" representing the +// client's request for the CreateLoadBalancerTlsCertificate operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateLoadBalancerTlsCertificate for more information on using the CreateLoadBalancerTlsCertificate +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateLoadBalancerTlsCertificateRequest method. +// req, resp := client.CreateLoadBalancerTlsCertificateRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateLoadBalancerTlsCertificate +func (c *Lightsail) CreateLoadBalancerTlsCertificateRequest(input *CreateLoadBalancerTlsCertificateInput) (req *request.Request, output *CreateLoadBalancerTlsCertificateOutput) { + op := &request.Operation{ + Name: opCreateLoadBalancerTlsCertificate, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateLoadBalancerTlsCertificateInput{} + } + + output = &CreateLoadBalancerTlsCertificateOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateLoadBalancerTlsCertificate API operation for Amazon Lightsail. +// +// Creates a Lightsail load balancer TLS certificate. +// +// TLS is just an updated, more secure version of Secure Socket Layer (SSL). +// +// The create load balancer tls certificate operation supports tag-based access +// control via resource tags applied to the resource identified by loadBalancerName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateLoadBalancerTlsCertificate for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateLoadBalancerTlsCertificate +func (c *Lightsail) CreateLoadBalancerTlsCertificate(input *CreateLoadBalancerTlsCertificateInput) (*CreateLoadBalancerTlsCertificateOutput, error) { + req, out := c.CreateLoadBalancerTlsCertificateRequest(input) + return out, req.Send() +} + +// CreateLoadBalancerTlsCertificateWithContext is the same as CreateLoadBalancerTlsCertificate with the addition of +// the ability to pass a context and additional request options. +// +// See CreateLoadBalancerTlsCertificate for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateLoadBalancerTlsCertificateWithContext(ctx aws.Context, input *CreateLoadBalancerTlsCertificateInput, opts ...request.Option) (*CreateLoadBalancerTlsCertificateOutput, error) { + req, out := c.CreateLoadBalancerTlsCertificateRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateRelationalDatabase = "CreateRelationalDatabase" + +// CreateRelationalDatabaseRequest generates a "aws/request.Request" representing the +// client's request for the CreateRelationalDatabase operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateRelationalDatabase for more information on using the CreateRelationalDatabase +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateRelationalDatabaseRequest method. +// req, resp := client.CreateRelationalDatabaseRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateRelationalDatabase +func (c *Lightsail) CreateRelationalDatabaseRequest(input *CreateRelationalDatabaseInput) (req *request.Request, output *CreateRelationalDatabaseOutput) { + op := &request.Operation{ + Name: opCreateRelationalDatabase, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateRelationalDatabaseInput{} + } + + output = &CreateRelationalDatabaseOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateRelationalDatabase API operation for Amazon Lightsail. +// +// Creates a new database in Amazon Lightsail. +// +// The create relational database operation supports tag-based access control +// via request tags. For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateRelationalDatabase for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateRelationalDatabase +func (c *Lightsail) CreateRelationalDatabase(input *CreateRelationalDatabaseInput) (*CreateRelationalDatabaseOutput, error) { + req, out := c.CreateRelationalDatabaseRequest(input) + return out, req.Send() +} + +// CreateRelationalDatabaseWithContext is the same as CreateRelationalDatabase with the addition of +// the ability to pass a context and additional request options. +// +// See CreateRelationalDatabase for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateRelationalDatabaseWithContext(ctx aws.Context, input *CreateRelationalDatabaseInput, opts ...request.Option) (*CreateRelationalDatabaseOutput, error) { + req, out := c.CreateRelationalDatabaseRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateRelationalDatabaseFromSnapshot = "CreateRelationalDatabaseFromSnapshot" + +// CreateRelationalDatabaseFromSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CreateRelationalDatabaseFromSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateRelationalDatabaseFromSnapshot for more information on using the CreateRelationalDatabaseFromSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateRelationalDatabaseFromSnapshotRequest method. +// req, resp := client.CreateRelationalDatabaseFromSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateRelationalDatabaseFromSnapshot +func (c *Lightsail) CreateRelationalDatabaseFromSnapshotRequest(input *CreateRelationalDatabaseFromSnapshotInput) (req *request.Request, output *CreateRelationalDatabaseFromSnapshotOutput) { + op := &request.Operation{ + Name: opCreateRelationalDatabaseFromSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateRelationalDatabaseFromSnapshotInput{} + } + + output = &CreateRelationalDatabaseFromSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateRelationalDatabaseFromSnapshot API operation for Amazon Lightsail. +// +// Creates a new database from an existing database snapshot in Amazon Lightsail. +// +// You can create a new database from a snapshot in if something goes wrong +// with your original database, or to change it to a different plan, such as +// a high availability or standard plan. +// +// The create relational database from snapshot operation supports tag-based +// access control via request tags and resource tags applied to the resource +// identified by relationalDatabaseSnapshotName. For more information, see the +// Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateRelationalDatabaseFromSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateRelationalDatabaseFromSnapshot +func (c *Lightsail) CreateRelationalDatabaseFromSnapshot(input *CreateRelationalDatabaseFromSnapshotInput) (*CreateRelationalDatabaseFromSnapshotOutput, error) { + req, out := c.CreateRelationalDatabaseFromSnapshotRequest(input) + return out, req.Send() +} + +// CreateRelationalDatabaseFromSnapshotWithContext is the same as CreateRelationalDatabaseFromSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See CreateRelationalDatabaseFromSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateRelationalDatabaseFromSnapshotWithContext(ctx aws.Context, input *CreateRelationalDatabaseFromSnapshotInput, opts ...request.Option) (*CreateRelationalDatabaseFromSnapshotOutput, error) { + req, out := c.CreateRelationalDatabaseFromSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateRelationalDatabaseSnapshot = "CreateRelationalDatabaseSnapshot" + +// CreateRelationalDatabaseSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the CreateRelationalDatabaseSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateRelationalDatabaseSnapshot for more information on using the CreateRelationalDatabaseSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateRelationalDatabaseSnapshotRequest method. +// req, resp := client.CreateRelationalDatabaseSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateRelationalDatabaseSnapshot +func (c *Lightsail) CreateRelationalDatabaseSnapshotRequest(input *CreateRelationalDatabaseSnapshotInput) (req *request.Request, output *CreateRelationalDatabaseSnapshotOutput) { + op := &request.Operation{ + Name: opCreateRelationalDatabaseSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &CreateRelationalDatabaseSnapshotInput{} + } + + output = &CreateRelationalDatabaseSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateRelationalDatabaseSnapshot API operation for Amazon Lightsail. +// +// Creates a snapshot of your database in Amazon Lightsail. You can use snapshots +// for backups, to make copies of a database, and to save data before deleting +// a database. +// +// The create relational database snapshot operation supports tag-based access +// control via request tags. For more information, see the Lightsail Dev Guide +// (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation CreateRelationalDatabaseSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/CreateRelationalDatabaseSnapshot +func (c *Lightsail) CreateRelationalDatabaseSnapshot(input *CreateRelationalDatabaseSnapshotInput) (*CreateRelationalDatabaseSnapshotOutput, error) { + req, out := c.CreateRelationalDatabaseSnapshotRequest(input) + return out, req.Send() +} + +// CreateRelationalDatabaseSnapshotWithContext is the same as CreateRelationalDatabaseSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See CreateRelationalDatabaseSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) CreateRelationalDatabaseSnapshotWithContext(ctx aws.Context, input *CreateRelationalDatabaseSnapshotInput, opts ...request.Option) (*CreateRelationalDatabaseSnapshotOutput, error) { + req, out := c.CreateRelationalDatabaseSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteDisk = "DeleteDisk" + +// DeleteDiskRequest generates a "aws/request.Request" representing the +// client's request for the DeleteDisk operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteDisk for more information on using the DeleteDisk +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteDiskRequest method. +// req, resp := client.DeleteDiskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteDisk +func (c *Lightsail) DeleteDiskRequest(input *DeleteDiskInput) (req *request.Request, output *DeleteDiskOutput) { + op := &request.Operation{ + Name: opDeleteDisk, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteDiskInput{} + } + + output = &DeleteDiskOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteDisk API operation for Amazon Lightsail. +// +// Deletes the specified block storage disk. The disk must be in the available +// state (not attached to a Lightsail instance). +// +// The disk may remain in the deleting state for several minutes. +// +// The delete disk operation supports tag-based access control via resource +// tags applied to the resource identified by diskName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteDisk for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteDisk +func (c *Lightsail) DeleteDisk(input *DeleteDiskInput) (*DeleteDiskOutput, error) { + req, out := c.DeleteDiskRequest(input) + return out, req.Send() +} + +// DeleteDiskWithContext is the same as DeleteDisk with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteDisk for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteDiskWithContext(ctx aws.Context, input *DeleteDiskInput, opts ...request.Option) (*DeleteDiskOutput, error) { + req, out := c.DeleteDiskRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteDiskSnapshot = "DeleteDiskSnapshot" + +// DeleteDiskSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the DeleteDiskSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteDiskSnapshot for more information on using the DeleteDiskSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteDiskSnapshotRequest method. +// req, resp := client.DeleteDiskSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteDiskSnapshot +func (c *Lightsail) DeleteDiskSnapshotRequest(input *DeleteDiskSnapshotInput) (req *request.Request, output *DeleteDiskSnapshotOutput) { + op := &request.Operation{ + Name: opDeleteDiskSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteDiskSnapshotInput{} + } + + output = &DeleteDiskSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteDiskSnapshot API operation for Amazon Lightsail. +// +// Deletes the specified disk snapshot. +// +// When you make periodic snapshots of a disk, the snapshots are incremental, +// and only the blocks on the device that have changed since your last snapshot +// are saved in the new snapshot. When you delete a snapshot, only the data +// not needed for any other snapshot is removed. So regardless of which prior +// snapshots have been deleted, all active snapshots will have access to all +// the information needed to restore the disk. +// +// The delete disk snapshot operation supports tag-based access control via +// resource tags applied to the resource identified by diskSnapshotName. For +// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteDiskSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteDiskSnapshot +func (c *Lightsail) DeleteDiskSnapshot(input *DeleteDiskSnapshotInput) (*DeleteDiskSnapshotOutput, error) { + req, out := c.DeleteDiskSnapshotRequest(input) + return out, req.Send() +} + +// DeleteDiskSnapshotWithContext is the same as DeleteDiskSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteDiskSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteDiskSnapshotWithContext(ctx aws.Context, input *DeleteDiskSnapshotInput, opts ...request.Option) (*DeleteDiskSnapshotOutput, error) { + req, out := c.DeleteDiskSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteDomain = "DeleteDomain" + +// DeleteDomainRequest generates a "aws/request.Request" representing the +// client's request for the DeleteDomain operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteDomain for more information on using the DeleteDomain +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteDomainRequest method. +// req, resp := client.DeleteDomainRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteDomain +func (c *Lightsail) DeleteDomainRequest(input *DeleteDomainInput) (req *request.Request, output *DeleteDomainOutput) { + op := &request.Operation{ + Name: opDeleteDomain, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteDomainInput{} + } + + output = &DeleteDomainOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteDomain API operation for Amazon Lightsail. +// +// Deletes the specified domain recordset and all of its domain records. +// +// The delete domain operation supports tag-based access control via resource +// tags applied to the resource identified by domainName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteDomain for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteDomain +func (c *Lightsail) DeleteDomain(input *DeleteDomainInput) (*DeleteDomainOutput, error) { + req, out := c.DeleteDomainRequest(input) + return out, req.Send() +} + +// DeleteDomainWithContext is the same as DeleteDomain with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteDomain for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteDomainWithContext(ctx aws.Context, input *DeleteDomainInput, opts ...request.Option) (*DeleteDomainOutput, error) { + req, out := c.DeleteDomainRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteDomainEntry = "DeleteDomainEntry" + +// DeleteDomainEntryRequest generates a "aws/request.Request" representing the +// client's request for the DeleteDomainEntry operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteDomainEntry for more information on using the DeleteDomainEntry +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteDomainEntryRequest method. +// req, resp := client.DeleteDomainEntryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteDomainEntry +func (c *Lightsail) DeleteDomainEntryRequest(input *DeleteDomainEntryInput) (req *request.Request, output *DeleteDomainEntryOutput) { + op := &request.Operation{ + Name: opDeleteDomainEntry, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteDomainEntryInput{} + } + + output = &DeleteDomainEntryOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteDomainEntry API operation for Amazon Lightsail. +// +// Deletes a specific domain entry. +// +// The delete domain entry operation supports tag-based access control via resource +// tags applied to the resource identified by domainName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteDomainEntry for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteDomainEntry +func (c *Lightsail) DeleteDomainEntry(input *DeleteDomainEntryInput) (*DeleteDomainEntryOutput, error) { + req, out := c.DeleteDomainEntryRequest(input) + return out, req.Send() +} + +// DeleteDomainEntryWithContext is the same as DeleteDomainEntry with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteDomainEntry for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteDomainEntryWithContext(ctx aws.Context, input *DeleteDomainEntryInput, opts ...request.Option) (*DeleteDomainEntryOutput, error) { + req, out := c.DeleteDomainEntryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteInstance = "DeleteInstance" + +// DeleteInstanceRequest generates a "aws/request.Request" representing the +// client's request for the DeleteInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteInstance for more information on using the DeleteInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteInstanceRequest method. +// req, resp := client.DeleteInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteInstance +func (c *Lightsail) DeleteInstanceRequest(input *DeleteInstanceInput) (req *request.Request, output *DeleteInstanceOutput) { + op := &request.Operation{ + Name: opDeleteInstance, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteInstanceInput{} + } + + output = &DeleteInstanceOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteInstance API operation for Amazon Lightsail. +// +// Deletes a specific Amazon Lightsail virtual private server, or instance. +// +// The delete instance operation supports tag-based access control via resource +// tags applied to the resource identified by instanceName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteInstance +func (c *Lightsail) DeleteInstance(input *DeleteInstanceInput) (*DeleteInstanceOutput, error) { + req, out := c.DeleteInstanceRequest(input) + return out, req.Send() +} + +// DeleteInstanceWithContext is the same as DeleteInstance with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteInstanceWithContext(ctx aws.Context, input *DeleteInstanceInput, opts ...request.Option) (*DeleteInstanceOutput, error) { + req, out := c.DeleteInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteInstanceSnapshot = "DeleteInstanceSnapshot" + +// DeleteInstanceSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the DeleteInstanceSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteInstanceSnapshot for more information on using the DeleteInstanceSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteInstanceSnapshotRequest method. +// req, resp := client.DeleteInstanceSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteInstanceSnapshot +func (c *Lightsail) DeleteInstanceSnapshotRequest(input *DeleteInstanceSnapshotInput) (req *request.Request, output *DeleteInstanceSnapshotOutput) { + op := &request.Operation{ + Name: opDeleteInstanceSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteInstanceSnapshotInput{} + } + + output = &DeleteInstanceSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteInstanceSnapshot API operation for Amazon Lightsail. +// +// Deletes a specific snapshot of a virtual private server (or instance). +// +// The delete instance snapshot operation supports tag-based access control +// via resource tags applied to the resource identified by instanceSnapshotName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteInstanceSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteInstanceSnapshot +func (c *Lightsail) DeleteInstanceSnapshot(input *DeleteInstanceSnapshotInput) (*DeleteInstanceSnapshotOutput, error) { + req, out := c.DeleteInstanceSnapshotRequest(input) + return out, req.Send() +} + +// DeleteInstanceSnapshotWithContext is the same as DeleteInstanceSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteInstanceSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteInstanceSnapshotWithContext(ctx aws.Context, input *DeleteInstanceSnapshotInput, opts ...request.Option) (*DeleteInstanceSnapshotOutput, error) { + req, out := c.DeleteInstanceSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteKeyPair = "DeleteKeyPair" + +// DeleteKeyPairRequest generates a "aws/request.Request" representing the +// client's request for the DeleteKeyPair operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteKeyPair for more information on using the DeleteKeyPair +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteKeyPairRequest method. +// req, resp := client.DeleteKeyPairRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteKeyPair +func (c *Lightsail) DeleteKeyPairRequest(input *DeleteKeyPairInput) (req *request.Request, output *DeleteKeyPairOutput) { + op := &request.Operation{ + Name: opDeleteKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteKeyPairInput{} + } + + output = &DeleteKeyPairOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteKeyPair API operation for Amazon Lightsail. +// +// Deletes a specific SSH key pair. +// +// The delete key pair operation supports tag-based access control via resource +// tags applied to the resource identified by keyPairName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteKeyPair for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteKeyPair +func (c *Lightsail) DeleteKeyPair(input *DeleteKeyPairInput) (*DeleteKeyPairOutput, error) { + req, out := c.DeleteKeyPairRequest(input) + return out, req.Send() +} + +// DeleteKeyPairWithContext is the same as DeleteKeyPair with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteKeyPair for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteKeyPairWithContext(ctx aws.Context, input *DeleteKeyPairInput, opts ...request.Option) (*DeleteKeyPairOutput, error) { + req, out := c.DeleteKeyPairRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteKnownHostKeys = "DeleteKnownHostKeys" + +// DeleteKnownHostKeysRequest generates a "aws/request.Request" representing the +// client's request for the DeleteKnownHostKeys operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteKnownHostKeys for more information on using the DeleteKnownHostKeys +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteKnownHostKeysRequest method. +// req, resp := client.DeleteKnownHostKeysRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteKnownHostKeys +func (c *Lightsail) DeleteKnownHostKeysRequest(input *DeleteKnownHostKeysInput) (req *request.Request, output *DeleteKnownHostKeysOutput) { + op := &request.Operation{ + Name: opDeleteKnownHostKeys, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteKnownHostKeysInput{} + } + + output = &DeleteKnownHostKeysOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteKnownHostKeys API operation for Amazon Lightsail. +// +// Deletes the known host key or certificate used by the Amazon Lightsail browser-based +// SSH or RDP clients to authenticate an instance. This operation enables the +// Lightsail browser-based SSH or RDP clients to connect to the instance after +// a host key mismatch. +// +// Perform this operation only if you were expecting the host key or certificate +// mismatch or if you are familiar with the new host key or certificate on the +// instance. For more information, see Troubleshooting connection issues when +// using the Amazon Lightsail browser-based SSH or RDP client (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-troubleshooting-browser-based-ssh-rdp-client-connection). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteKnownHostKeys for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteKnownHostKeys +func (c *Lightsail) DeleteKnownHostKeys(input *DeleteKnownHostKeysInput) (*DeleteKnownHostKeysOutput, error) { + req, out := c.DeleteKnownHostKeysRequest(input) + return out, req.Send() +} + +// DeleteKnownHostKeysWithContext is the same as DeleteKnownHostKeys with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteKnownHostKeys for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteKnownHostKeysWithContext(ctx aws.Context, input *DeleteKnownHostKeysInput, opts ...request.Option) (*DeleteKnownHostKeysOutput, error) { + req, out := c.DeleteKnownHostKeysRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteLoadBalancer = "DeleteLoadBalancer" + +// DeleteLoadBalancerRequest generates a "aws/request.Request" representing the +// client's request for the DeleteLoadBalancer operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteLoadBalancer for more information on using the DeleteLoadBalancer +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteLoadBalancerRequest method. +// req, resp := client.DeleteLoadBalancerRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteLoadBalancer +func (c *Lightsail) DeleteLoadBalancerRequest(input *DeleteLoadBalancerInput) (req *request.Request, output *DeleteLoadBalancerOutput) { + op := &request.Operation{ + Name: opDeleteLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteLoadBalancerInput{} + } + + output = &DeleteLoadBalancerOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteLoadBalancer API operation for Amazon Lightsail. +// +// Deletes a Lightsail load balancer and all its associated SSL/TLS certificates. +// Once the load balancer is deleted, you will need to create a new load balancer, +// create a new certificate, and verify domain ownership again. +// +// The delete load balancer operation supports tag-based access control via +// resource tags applied to the resource identified by loadBalancerName. For +// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteLoadBalancer for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteLoadBalancer +func (c *Lightsail) DeleteLoadBalancer(input *DeleteLoadBalancerInput) (*DeleteLoadBalancerOutput, error) { + req, out := c.DeleteLoadBalancerRequest(input) + return out, req.Send() +} + +// DeleteLoadBalancerWithContext is the same as DeleteLoadBalancer with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteLoadBalancer for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteLoadBalancerWithContext(ctx aws.Context, input *DeleteLoadBalancerInput, opts ...request.Option) (*DeleteLoadBalancerOutput, error) { + req, out := c.DeleteLoadBalancerRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteLoadBalancerTlsCertificate = "DeleteLoadBalancerTlsCertificate" + +// DeleteLoadBalancerTlsCertificateRequest generates a "aws/request.Request" representing the +// client's request for the DeleteLoadBalancerTlsCertificate operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteLoadBalancerTlsCertificate for more information on using the DeleteLoadBalancerTlsCertificate +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteLoadBalancerTlsCertificateRequest method. +// req, resp := client.DeleteLoadBalancerTlsCertificateRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteLoadBalancerTlsCertificate +func (c *Lightsail) DeleteLoadBalancerTlsCertificateRequest(input *DeleteLoadBalancerTlsCertificateInput) (req *request.Request, output *DeleteLoadBalancerTlsCertificateOutput) { + op := &request.Operation{ + Name: opDeleteLoadBalancerTlsCertificate, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteLoadBalancerTlsCertificateInput{} + } + + output = &DeleteLoadBalancerTlsCertificateOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteLoadBalancerTlsCertificate API operation for Amazon Lightsail. +// +// Deletes an SSL/TLS certificate associated with a Lightsail load balancer. +// +// The delete load balancer tls certificate operation supports tag-based access +// control via resource tags applied to the resource identified by loadBalancerName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteLoadBalancerTlsCertificate for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteLoadBalancerTlsCertificate +func (c *Lightsail) DeleteLoadBalancerTlsCertificate(input *DeleteLoadBalancerTlsCertificateInput) (*DeleteLoadBalancerTlsCertificateOutput, error) { + req, out := c.DeleteLoadBalancerTlsCertificateRequest(input) + return out, req.Send() +} + +// DeleteLoadBalancerTlsCertificateWithContext is the same as DeleteLoadBalancerTlsCertificate with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteLoadBalancerTlsCertificate for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteLoadBalancerTlsCertificateWithContext(ctx aws.Context, input *DeleteLoadBalancerTlsCertificateInput, opts ...request.Option) (*DeleteLoadBalancerTlsCertificateOutput, error) { + req, out := c.DeleteLoadBalancerTlsCertificateRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteRelationalDatabase = "DeleteRelationalDatabase" + +// DeleteRelationalDatabaseRequest generates a "aws/request.Request" representing the +// client's request for the DeleteRelationalDatabase operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteRelationalDatabase for more information on using the DeleteRelationalDatabase +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteRelationalDatabaseRequest method. +// req, resp := client.DeleteRelationalDatabaseRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteRelationalDatabase +func (c *Lightsail) DeleteRelationalDatabaseRequest(input *DeleteRelationalDatabaseInput) (req *request.Request, output *DeleteRelationalDatabaseOutput) { + op := &request.Operation{ + Name: opDeleteRelationalDatabase, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteRelationalDatabaseInput{} + } + + output = &DeleteRelationalDatabaseOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteRelationalDatabase API operation for Amazon Lightsail. +// +// Deletes a database in Amazon Lightsail. +// +// The delete relational database operation supports tag-based access control +// via resource tags applied to the resource identified by relationalDatabaseName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteRelationalDatabase for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteRelationalDatabase +func (c *Lightsail) DeleteRelationalDatabase(input *DeleteRelationalDatabaseInput) (*DeleteRelationalDatabaseOutput, error) { + req, out := c.DeleteRelationalDatabaseRequest(input) + return out, req.Send() +} + +// DeleteRelationalDatabaseWithContext is the same as DeleteRelationalDatabase with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteRelationalDatabase for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteRelationalDatabaseWithContext(ctx aws.Context, input *DeleteRelationalDatabaseInput, opts ...request.Option) (*DeleteRelationalDatabaseOutput, error) { + req, out := c.DeleteRelationalDatabaseRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteRelationalDatabaseSnapshot = "DeleteRelationalDatabaseSnapshot" + +// DeleteRelationalDatabaseSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the DeleteRelationalDatabaseSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteRelationalDatabaseSnapshot for more information on using the DeleteRelationalDatabaseSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteRelationalDatabaseSnapshotRequest method. +// req, resp := client.DeleteRelationalDatabaseSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteRelationalDatabaseSnapshot +func (c *Lightsail) DeleteRelationalDatabaseSnapshotRequest(input *DeleteRelationalDatabaseSnapshotInput) (req *request.Request, output *DeleteRelationalDatabaseSnapshotOutput) { + op := &request.Operation{ + Name: opDeleteRelationalDatabaseSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DeleteRelationalDatabaseSnapshotInput{} + } + + output = &DeleteRelationalDatabaseSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteRelationalDatabaseSnapshot API operation for Amazon Lightsail. +// +// Deletes a database snapshot in Amazon Lightsail. +// +// The delete relational database snapshot operation supports tag-based access +// control via resource tags applied to the resource identified by relationalDatabaseName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DeleteRelationalDatabaseSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DeleteRelationalDatabaseSnapshot +func (c *Lightsail) DeleteRelationalDatabaseSnapshot(input *DeleteRelationalDatabaseSnapshotInput) (*DeleteRelationalDatabaseSnapshotOutput, error) { + req, out := c.DeleteRelationalDatabaseSnapshotRequest(input) + return out, req.Send() +} + +// DeleteRelationalDatabaseSnapshotWithContext is the same as DeleteRelationalDatabaseSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteRelationalDatabaseSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DeleteRelationalDatabaseSnapshotWithContext(ctx aws.Context, input *DeleteRelationalDatabaseSnapshotInput, opts ...request.Option) (*DeleteRelationalDatabaseSnapshotOutput, error) { + req, out := c.DeleteRelationalDatabaseSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDetachDisk = "DetachDisk" + +// DetachDiskRequest generates a "aws/request.Request" representing the +// client's request for the DetachDisk operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DetachDisk for more information on using the DetachDisk +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DetachDiskRequest method. +// req, resp := client.DetachDiskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DetachDisk +func (c *Lightsail) DetachDiskRequest(input *DetachDiskInput) (req *request.Request, output *DetachDiskOutput) { + op := &request.Operation{ + Name: opDetachDisk, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachDiskInput{} + } + + output = &DetachDiskOutput{} + req = c.newRequest(op, input, output) + return +} + +// DetachDisk API operation for Amazon Lightsail. +// +// Detaches a stopped block storage disk from a Lightsail instance. Make sure +// to unmount any file systems on the device within your operating system before +// stopping the instance and detaching the disk. +// +// The detach disk operation supports tag-based access control via resource +// tags applied to the resource identified by diskName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DetachDisk for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DetachDisk +func (c *Lightsail) DetachDisk(input *DetachDiskInput) (*DetachDiskOutput, error) { + req, out := c.DetachDiskRequest(input) + return out, req.Send() +} + +// DetachDiskWithContext is the same as DetachDisk with the addition of +// the ability to pass a context and additional request options. +// +// See DetachDisk for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DetachDiskWithContext(ctx aws.Context, input *DetachDiskInput, opts ...request.Option) (*DetachDiskOutput, error) { + req, out := c.DetachDiskRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDetachInstancesFromLoadBalancer = "DetachInstancesFromLoadBalancer" + +// DetachInstancesFromLoadBalancerRequest generates a "aws/request.Request" representing the +// client's request for the DetachInstancesFromLoadBalancer operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DetachInstancesFromLoadBalancer for more information on using the DetachInstancesFromLoadBalancer +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DetachInstancesFromLoadBalancerRequest method. +// req, resp := client.DetachInstancesFromLoadBalancerRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DetachInstancesFromLoadBalancer +func (c *Lightsail) DetachInstancesFromLoadBalancerRequest(input *DetachInstancesFromLoadBalancerInput) (req *request.Request, output *DetachInstancesFromLoadBalancerOutput) { + op := &request.Operation{ + Name: opDetachInstancesFromLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachInstancesFromLoadBalancerInput{} + } + + output = &DetachInstancesFromLoadBalancerOutput{} + req = c.newRequest(op, input, output) + return +} + +// DetachInstancesFromLoadBalancer API operation for Amazon Lightsail. +// +// Detaches the specified instances from a Lightsail load balancer. +// +// This operation waits until the instances are no longer needed before they +// are detached from the load balancer. +// +// The detach instances from load balancer operation supports tag-based access +// control via resource tags applied to the resource identified by loadBalancerName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DetachInstancesFromLoadBalancer for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DetachInstancesFromLoadBalancer +func (c *Lightsail) DetachInstancesFromLoadBalancer(input *DetachInstancesFromLoadBalancerInput) (*DetachInstancesFromLoadBalancerOutput, error) { + req, out := c.DetachInstancesFromLoadBalancerRequest(input) + return out, req.Send() +} + +// DetachInstancesFromLoadBalancerWithContext is the same as DetachInstancesFromLoadBalancer with the addition of +// the ability to pass a context and additional request options. +// +// See DetachInstancesFromLoadBalancer for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DetachInstancesFromLoadBalancerWithContext(ctx aws.Context, input *DetachInstancesFromLoadBalancerInput, opts ...request.Option) (*DetachInstancesFromLoadBalancerOutput, error) { + req, out := c.DetachInstancesFromLoadBalancerRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDetachStaticIp = "DetachStaticIp" + +// DetachStaticIpRequest generates a "aws/request.Request" representing the +// client's request for the DetachStaticIp operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DetachStaticIp for more information on using the DetachStaticIp +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DetachStaticIpRequest method. +// req, resp := client.DetachStaticIpRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DetachStaticIp +func (c *Lightsail) DetachStaticIpRequest(input *DetachStaticIpInput) (req *request.Request, output *DetachStaticIpOutput) { + op := &request.Operation{ + Name: opDetachStaticIp, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DetachStaticIpInput{} + } + + output = &DetachStaticIpOutput{} + req = c.newRequest(op, input, output) + return +} + +// DetachStaticIp API operation for Amazon Lightsail. +// +// Detaches a static IP from the Amazon Lightsail instance to which it is attached. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DetachStaticIp for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DetachStaticIp +func (c *Lightsail) DetachStaticIp(input *DetachStaticIpInput) (*DetachStaticIpOutput, error) { + req, out := c.DetachStaticIpRequest(input) + return out, req.Send() +} + +// DetachStaticIpWithContext is the same as DetachStaticIp with the addition of +// the ability to pass a context and additional request options. +// +// See DetachStaticIp for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DetachStaticIpWithContext(ctx aws.Context, input *DetachStaticIpInput, opts ...request.Option) (*DetachStaticIpOutput, error) { + req, out := c.DetachStaticIpRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDownloadDefaultKeyPair = "DownloadDefaultKeyPair" + +// DownloadDefaultKeyPairRequest generates a "aws/request.Request" representing the +// client's request for the DownloadDefaultKeyPair operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DownloadDefaultKeyPair for more information on using the DownloadDefaultKeyPair +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DownloadDefaultKeyPairRequest method. +// req, resp := client.DownloadDefaultKeyPairRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DownloadDefaultKeyPair +func (c *Lightsail) DownloadDefaultKeyPairRequest(input *DownloadDefaultKeyPairInput) (req *request.Request, output *DownloadDefaultKeyPairOutput) { + op := &request.Operation{ + Name: opDownloadDefaultKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DownloadDefaultKeyPairInput{} + } + + output = &DownloadDefaultKeyPairOutput{} + req = c.newRequest(op, input, output) + return +} + +// DownloadDefaultKeyPair API operation for Amazon Lightsail. +// +// Downloads the default SSH key pair from the user's account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation DownloadDefaultKeyPair for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/DownloadDefaultKeyPair +func (c *Lightsail) DownloadDefaultKeyPair(input *DownloadDefaultKeyPairInput) (*DownloadDefaultKeyPairOutput, error) { + req, out := c.DownloadDefaultKeyPairRequest(input) + return out, req.Send() +} + +// DownloadDefaultKeyPairWithContext is the same as DownloadDefaultKeyPair with the addition of +// the ability to pass a context and additional request options. +// +// See DownloadDefaultKeyPair for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) DownloadDefaultKeyPairWithContext(ctx aws.Context, input *DownloadDefaultKeyPairInput, opts ...request.Option) (*DownloadDefaultKeyPairOutput, error) { + req, out := c.DownloadDefaultKeyPairRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opExportSnapshot = "ExportSnapshot" + +// ExportSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the ExportSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ExportSnapshot for more information on using the ExportSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ExportSnapshotRequest method. +// req, resp := client.ExportSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/ExportSnapshot +func (c *Lightsail) ExportSnapshotRequest(input *ExportSnapshotInput) (req *request.Request, output *ExportSnapshotOutput) { + op := &request.Operation{ + Name: opExportSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ExportSnapshotInput{} + } + + output = &ExportSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// ExportSnapshot API operation for Amazon Lightsail. +// +// Exports an Amazon Lightsail instance or block storage disk snapshot to Amazon +// Elastic Compute Cloud (Amazon EC2). This operation results in an export snapshot +// record that can be used with the create cloud formation stack operation to +// create new Amazon EC2 instances. +// +// Exported instance snapshots appear in Amazon EC2 as Amazon Machine Images +// (AMIs), and the instance system disk appears as an Amazon Elastic Block Store +// (Amazon EBS) volume. Exported disk snapshots appear in Amazon EC2 as Amazon +// EBS volumes. Snapshots are exported to the same Amazon Web Services Region +// in Amazon EC2 as the source Lightsail snapshot. +// +// The export snapshot operation supports tag-based access control via resource +// tags applied to the resource identified by sourceSnapshotName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Use the get instance snapshots or get disk snapshots operations to get a +// list of snapshots that you can export to Amazon EC2. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation ExportSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/ExportSnapshot +func (c *Lightsail) ExportSnapshot(input *ExportSnapshotInput) (*ExportSnapshotOutput, error) { + req, out := c.ExportSnapshotRequest(input) + return out, req.Send() +} + +// ExportSnapshotWithContext is the same as ExportSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See ExportSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) ExportSnapshotWithContext(ctx aws.Context, input *ExportSnapshotInput, opts ...request.Option) (*ExportSnapshotOutput, error) { + req, out := c.ExportSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetActiveNames = "GetActiveNames" + +// GetActiveNamesRequest generates a "aws/request.Request" representing the +// client's request for the GetActiveNames operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetActiveNames for more information on using the GetActiveNames +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetActiveNamesRequest method. +// req, resp := client.GetActiveNamesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetActiveNames +func (c *Lightsail) GetActiveNamesRequest(input *GetActiveNamesInput) (req *request.Request, output *GetActiveNamesOutput) { + op := &request.Operation{ + Name: opGetActiveNames, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetActiveNamesInput{} + } + + output = &GetActiveNamesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetActiveNames API operation for Amazon Lightsail. +// +// Returns the names of all active (not deleted) resources. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetActiveNames for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetActiveNames +func (c *Lightsail) GetActiveNames(input *GetActiveNamesInput) (*GetActiveNamesOutput, error) { + req, out := c.GetActiveNamesRequest(input) + return out, req.Send() +} + +// GetActiveNamesWithContext is the same as GetActiveNames with the addition of +// the ability to pass a context and additional request options. +// +// See GetActiveNames for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetActiveNamesWithContext(ctx aws.Context, input *GetActiveNamesInput, opts ...request.Option) (*GetActiveNamesOutput, error) { + req, out := c.GetActiveNamesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetBlueprints = "GetBlueprints" + +// GetBlueprintsRequest generates a "aws/request.Request" representing the +// client's request for the GetBlueprints operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetBlueprints for more information on using the GetBlueprints +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetBlueprintsRequest method. +// req, resp := client.GetBlueprintsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetBlueprints +func (c *Lightsail) GetBlueprintsRequest(input *GetBlueprintsInput) (req *request.Request, output *GetBlueprintsOutput) { + op := &request.Operation{ + Name: opGetBlueprints, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetBlueprintsInput{} + } + + output = &GetBlueprintsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetBlueprints API operation for Amazon Lightsail. +// +// Returns the list of available instance images, or blueprints. You can use +// a blueprint to create a new virtual private server already running a specific +// operating system, as well as a preinstalled app or development stack. The +// software each instance is running depends on the blueprint image you choose. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetBlueprints for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetBlueprints +func (c *Lightsail) GetBlueprints(input *GetBlueprintsInput) (*GetBlueprintsOutput, error) { + req, out := c.GetBlueprintsRequest(input) + return out, req.Send() +} + +// GetBlueprintsWithContext is the same as GetBlueprints with the addition of +// the ability to pass a context and additional request options. +// +// See GetBlueprints for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetBlueprintsWithContext(ctx aws.Context, input *GetBlueprintsInput, opts ...request.Option) (*GetBlueprintsOutput, error) { + req, out := c.GetBlueprintsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetBundles = "GetBundles" + +// GetBundlesRequest generates a "aws/request.Request" representing the +// client's request for the GetBundles operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetBundles for more information on using the GetBundles +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetBundlesRequest method. +// req, resp := client.GetBundlesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetBundles +func (c *Lightsail) GetBundlesRequest(input *GetBundlesInput) (req *request.Request, output *GetBundlesOutput) { + op := &request.Operation{ + Name: opGetBundles, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetBundlesInput{} + } + + output = &GetBundlesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetBundles API operation for Amazon Lightsail. +// +// Returns the list of bundles that are available for purchase. A bundle describes +// the specs for your virtual private server (or instance). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetBundles for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetBundles +func (c *Lightsail) GetBundles(input *GetBundlesInput) (*GetBundlesOutput, error) { + req, out := c.GetBundlesRequest(input) + return out, req.Send() +} + +// GetBundlesWithContext is the same as GetBundles with the addition of +// the ability to pass a context and additional request options. +// +// See GetBundles for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetBundlesWithContext(ctx aws.Context, input *GetBundlesInput, opts ...request.Option) (*GetBundlesOutput, error) { + req, out := c.GetBundlesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetCloudFormationStackRecords = "GetCloudFormationStackRecords" + +// GetCloudFormationStackRecordsRequest generates a "aws/request.Request" representing the +// client's request for the GetCloudFormationStackRecords operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetCloudFormationStackRecords for more information on using the GetCloudFormationStackRecords +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetCloudFormationStackRecordsRequest method. +// req, resp := client.GetCloudFormationStackRecordsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetCloudFormationStackRecords +func (c *Lightsail) GetCloudFormationStackRecordsRequest(input *GetCloudFormationStackRecordsInput) (req *request.Request, output *GetCloudFormationStackRecordsOutput) { + op := &request.Operation{ + Name: opGetCloudFormationStackRecords, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetCloudFormationStackRecordsInput{} + } + + output = &GetCloudFormationStackRecordsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetCloudFormationStackRecords API operation for Amazon Lightsail. +// +// Returns the CloudFormation stack record created as a result of the create +// cloud formation stack operation. +// +// An AWS CloudFormation stack is used to create a new Amazon EC2 instance from +// an exported Lightsail snapshot. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetCloudFormationStackRecords for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetCloudFormationStackRecords +func (c *Lightsail) GetCloudFormationStackRecords(input *GetCloudFormationStackRecordsInput) (*GetCloudFormationStackRecordsOutput, error) { + req, out := c.GetCloudFormationStackRecordsRequest(input) + return out, req.Send() +} + +// GetCloudFormationStackRecordsWithContext is the same as GetCloudFormationStackRecords with the addition of +// the ability to pass a context and additional request options. +// +// See GetCloudFormationStackRecords for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetCloudFormationStackRecordsWithContext(ctx aws.Context, input *GetCloudFormationStackRecordsInput, opts ...request.Option) (*GetCloudFormationStackRecordsOutput, error) { + req, out := c.GetCloudFormationStackRecordsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetDisk = "GetDisk" + +// GetDiskRequest generates a "aws/request.Request" representing the +// client's request for the GetDisk operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetDisk for more information on using the GetDisk +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetDiskRequest method. +// req, resp := client.GetDiskRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDisk +func (c *Lightsail) GetDiskRequest(input *GetDiskInput) (req *request.Request, output *GetDiskOutput) { + op := &request.Operation{ + Name: opGetDisk, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetDiskInput{} + } + + output = &GetDiskOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetDisk API operation for Amazon Lightsail. +// +// Returns information about a specific block storage disk. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetDisk for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDisk +func (c *Lightsail) GetDisk(input *GetDiskInput) (*GetDiskOutput, error) { + req, out := c.GetDiskRequest(input) + return out, req.Send() +} + +// GetDiskWithContext is the same as GetDisk with the addition of +// the ability to pass a context and additional request options. +// +// See GetDisk for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetDiskWithContext(ctx aws.Context, input *GetDiskInput, opts ...request.Option) (*GetDiskOutput, error) { + req, out := c.GetDiskRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetDiskSnapshot = "GetDiskSnapshot" + +// GetDiskSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the GetDiskSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetDiskSnapshot for more information on using the GetDiskSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetDiskSnapshotRequest method. +// req, resp := client.GetDiskSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDiskSnapshot +func (c *Lightsail) GetDiskSnapshotRequest(input *GetDiskSnapshotInput) (req *request.Request, output *GetDiskSnapshotOutput) { + op := &request.Operation{ + Name: opGetDiskSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetDiskSnapshotInput{} + } + + output = &GetDiskSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetDiskSnapshot API operation for Amazon Lightsail. +// +// Returns information about a specific block storage disk snapshot. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetDiskSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDiskSnapshot +func (c *Lightsail) GetDiskSnapshot(input *GetDiskSnapshotInput) (*GetDiskSnapshotOutput, error) { + req, out := c.GetDiskSnapshotRequest(input) + return out, req.Send() +} + +// GetDiskSnapshotWithContext is the same as GetDiskSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See GetDiskSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetDiskSnapshotWithContext(ctx aws.Context, input *GetDiskSnapshotInput, opts ...request.Option) (*GetDiskSnapshotOutput, error) { + req, out := c.GetDiskSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetDiskSnapshots = "GetDiskSnapshots" + +// GetDiskSnapshotsRequest generates a "aws/request.Request" representing the +// client's request for the GetDiskSnapshots operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetDiskSnapshots for more information on using the GetDiskSnapshots +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetDiskSnapshotsRequest method. +// req, resp := client.GetDiskSnapshotsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDiskSnapshots +func (c *Lightsail) GetDiskSnapshotsRequest(input *GetDiskSnapshotsInput) (req *request.Request, output *GetDiskSnapshotsOutput) { + op := &request.Operation{ + Name: opGetDiskSnapshots, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetDiskSnapshotsInput{} + } + + output = &GetDiskSnapshotsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetDiskSnapshots API operation for Amazon Lightsail. +// +// Returns information about all block storage disk snapshots in your AWS account +// and region. +// +// If you are describing a long list of disk snapshots, you can paginate the +// output to make the list more manageable. You can use the pageToken and nextPageToken +// values to retrieve the next items in the list. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetDiskSnapshots for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDiskSnapshots +func (c *Lightsail) GetDiskSnapshots(input *GetDiskSnapshotsInput) (*GetDiskSnapshotsOutput, error) { + req, out := c.GetDiskSnapshotsRequest(input) + return out, req.Send() +} + +// GetDiskSnapshotsWithContext is the same as GetDiskSnapshots with the addition of +// the ability to pass a context and additional request options. +// +// See GetDiskSnapshots for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetDiskSnapshotsWithContext(ctx aws.Context, input *GetDiskSnapshotsInput, opts ...request.Option) (*GetDiskSnapshotsOutput, error) { + req, out := c.GetDiskSnapshotsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetDisks = "GetDisks" + +// GetDisksRequest generates a "aws/request.Request" representing the +// client's request for the GetDisks operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetDisks for more information on using the GetDisks +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetDisksRequest method. +// req, resp := client.GetDisksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDisks +func (c *Lightsail) GetDisksRequest(input *GetDisksInput) (req *request.Request, output *GetDisksOutput) { + op := &request.Operation{ + Name: opGetDisks, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetDisksInput{} + } + + output = &GetDisksOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetDisks API operation for Amazon Lightsail. +// +// Returns information about all block storage disks in your AWS account and +// region. +// +// If you are describing a long list of disks, you can paginate the output to +// make the list more manageable. You can use the pageToken and nextPageToken +// values to retrieve the next items in the list. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetDisks for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDisks +func (c *Lightsail) GetDisks(input *GetDisksInput) (*GetDisksOutput, error) { + req, out := c.GetDisksRequest(input) + return out, req.Send() +} + +// GetDisksWithContext is the same as GetDisks with the addition of +// the ability to pass a context and additional request options. +// +// See GetDisks for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetDisksWithContext(ctx aws.Context, input *GetDisksInput, opts ...request.Option) (*GetDisksOutput, error) { + req, out := c.GetDisksRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetDomain = "GetDomain" + +// GetDomainRequest generates a "aws/request.Request" representing the +// client's request for the GetDomain operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetDomain for more information on using the GetDomain +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetDomainRequest method. +// req, resp := client.GetDomainRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDomain +func (c *Lightsail) GetDomainRequest(input *GetDomainInput) (req *request.Request, output *GetDomainOutput) { + op := &request.Operation{ + Name: opGetDomain, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetDomainInput{} + } + + output = &GetDomainOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetDomain API operation for Amazon Lightsail. +// +// Returns information about a specific domain recordset. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetDomain for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDomain +func (c *Lightsail) GetDomain(input *GetDomainInput) (*GetDomainOutput, error) { + req, out := c.GetDomainRequest(input) + return out, req.Send() +} + +// GetDomainWithContext is the same as GetDomain with the addition of +// the ability to pass a context and additional request options. +// +// See GetDomain for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetDomainWithContext(ctx aws.Context, input *GetDomainInput, opts ...request.Option) (*GetDomainOutput, error) { + req, out := c.GetDomainRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetDomains = "GetDomains" + +// GetDomainsRequest generates a "aws/request.Request" representing the +// client's request for the GetDomains operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetDomains for more information on using the GetDomains +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetDomainsRequest method. +// req, resp := client.GetDomainsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDomains +func (c *Lightsail) GetDomainsRequest(input *GetDomainsInput) (req *request.Request, output *GetDomainsOutput) { + op := &request.Operation{ + Name: opGetDomains, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetDomainsInput{} + } + + output = &GetDomainsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetDomains API operation for Amazon Lightsail. +// +// Returns a list of all domains in the user's account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetDomains for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetDomains +func (c *Lightsail) GetDomains(input *GetDomainsInput) (*GetDomainsOutput, error) { + req, out := c.GetDomainsRequest(input) + return out, req.Send() +} + +// GetDomainsWithContext is the same as GetDomains with the addition of +// the ability to pass a context and additional request options. +// +// See GetDomains for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetDomainsWithContext(ctx aws.Context, input *GetDomainsInput, opts ...request.Option) (*GetDomainsOutput, error) { + req, out := c.GetDomainsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetExportSnapshotRecords = "GetExportSnapshotRecords" + +// GetExportSnapshotRecordsRequest generates a "aws/request.Request" representing the +// client's request for the GetExportSnapshotRecords operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetExportSnapshotRecords for more information on using the GetExportSnapshotRecords +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetExportSnapshotRecordsRequest method. +// req, resp := client.GetExportSnapshotRecordsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetExportSnapshotRecords +func (c *Lightsail) GetExportSnapshotRecordsRequest(input *GetExportSnapshotRecordsInput) (req *request.Request, output *GetExportSnapshotRecordsOutput) { + op := &request.Operation{ + Name: opGetExportSnapshotRecords, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetExportSnapshotRecordsInput{} + } + + output = &GetExportSnapshotRecordsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetExportSnapshotRecords API operation for Amazon Lightsail. +// +// Returns the export snapshot record created as a result of the export snapshot +// operation. +// +// An export snapshot record can be used to create a new Amazon EC2 instance +// and its related resources with the create cloud formation stack operation. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetExportSnapshotRecords for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetExportSnapshotRecords +func (c *Lightsail) GetExportSnapshotRecords(input *GetExportSnapshotRecordsInput) (*GetExportSnapshotRecordsOutput, error) { + req, out := c.GetExportSnapshotRecordsRequest(input) + return out, req.Send() +} + +// GetExportSnapshotRecordsWithContext is the same as GetExportSnapshotRecords with the addition of +// the ability to pass a context and additional request options. +// +// See GetExportSnapshotRecords for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetExportSnapshotRecordsWithContext(ctx aws.Context, input *GetExportSnapshotRecordsInput, opts ...request.Option) (*GetExportSnapshotRecordsOutput, error) { + req, out := c.GetExportSnapshotRecordsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetInstance = "GetInstance" + +// GetInstanceRequest generates a "aws/request.Request" representing the +// client's request for the GetInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetInstance for more information on using the GetInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetInstanceRequest method. +// req, resp := client.GetInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstance +func (c *Lightsail) GetInstanceRequest(input *GetInstanceInput) (req *request.Request, output *GetInstanceOutput) { + op := &request.Operation{ + Name: opGetInstance, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetInstanceInput{} + } + + output = &GetInstanceOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetInstance API operation for Amazon Lightsail. +// +// Returns information about a specific Amazon Lightsail instance, which is +// a virtual private server. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstance +func (c *Lightsail) GetInstance(input *GetInstanceInput) (*GetInstanceOutput, error) { + req, out := c.GetInstanceRequest(input) + return out, req.Send() +} + +// GetInstanceWithContext is the same as GetInstance with the addition of +// the ability to pass a context and additional request options. +// +// See GetInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetInstanceWithContext(ctx aws.Context, input *GetInstanceInput, opts ...request.Option) (*GetInstanceOutput, error) { + req, out := c.GetInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetInstanceAccessDetails = "GetInstanceAccessDetails" + +// GetInstanceAccessDetailsRequest generates a "aws/request.Request" representing the +// client's request for the GetInstanceAccessDetails operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetInstanceAccessDetails for more information on using the GetInstanceAccessDetails +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetInstanceAccessDetailsRequest method. +// req, resp := client.GetInstanceAccessDetailsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceAccessDetails +func (c *Lightsail) GetInstanceAccessDetailsRequest(input *GetInstanceAccessDetailsInput) (req *request.Request, output *GetInstanceAccessDetailsOutput) { + op := &request.Operation{ + Name: opGetInstanceAccessDetails, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetInstanceAccessDetailsInput{} + } + + output = &GetInstanceAccessDetailsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetInstanceAccessDetails API operation for Amazon Lightsail. +// +// Returns temporary SSH keys you can use to connect to a specific virtual private +// server, or instance. +// +// The get instance access details operation supports tag-based access control +// via resource tags applied to the resource identified by instanceName. For +// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetInstanceAccessDetails for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceAccessDetails +func (c *Lightsail) GetInstanceAccessDetails(input *GetInstanceAccessDetailsInput) (*GetInstanceAccessDetailsOutput, error) { + req, out := c.GetInstanceAccessDetailsRequest(input) + return out, req.Send() +} + +// GetInstanceAccessDetailsWithContext is the same as GetInstanceAccessDetails with the addition of +// the ability to pass a context and additional request options. +// +// See GetInstanceAccessDetails for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetInstanceAccessDetailsWithContext(ctx aws.Context, input *GetInstanceAccessDetailsInput, opts ...request.Option) (*GetInstanceAccessDetailsOutput, error) { + req, out := c.GetInstanceAccessDetailsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetInstanceMetricData = "GetInstanceMetricData" + +// GetInstanceMetricDataRequest generates a "aws/request.Request" representing the +// client's request for the GetInstanceMetricData operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetInstanceMetricData for more information on using the GetInstanceMetricData +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetInstanceMetricDataRequest method. +// req, resp := client.GetInstanceMetricDataRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceMetricData +func (c *Lightsail) GetInstanceMetricDataRequest(input *GetInstanceMetricDataInput) (req *request.Request, output *GetInstanceMetricDataOutput) { + op := &request.Operation{ + Name: opGetInstanceMetricData, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetInstanceMetricDataInput{} + } + + output = &GetInstanceMetricDataOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetInstanceMetricData API operation for Amazon Lightsail. +// +// Returns the data points for the specified Amazon Lightsail instance metric, +// given an instance name. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetInstanceMetricData for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceMetricData +func (c *Lightsail) GetInstanceMetricData(input *GetInstanceMetricDataInput) (*GetInstanceMetricDataOutput, error) { + req, out := c.GetInstanceMetricDataRequest(input) + return out, req.Send() +} + +// GetInstanceMetricDataWithContext is the same as GetInstanceMetricData with the addition of +// the ability to pass a context and additional request options. +// +// See GetInstanceMetricData for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetInstanceMetricDataWithContext(ctx aws.Context, input *GetInstanceMetricDataInput, opts ...request.Option) (*GetInstanceMetricDataOutput, error) { + req, out := c.GetInstanceMetricDataRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetInstancePortStates = "GetInstancePortStates" + +// GetInstancePortStatesRequest generates a "aws/request.Request" representing the +// client's request for the GetInstancePortStates operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetInstancePortStates for more information on using the GetInstancePortStates +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetInstancePortStatesRequest method. +// req, resp := client.GetInstancePortStatesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstancePortStates +func (c *Lightsail) GetInstancePortStatesRequest(input *GetInstancePortStatesInput) (req *request.Request, output *GetInstancePortStatesOutput) { + op := &request.Operation{ + Name: opGetInstancePortStates, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetInstancePortStatesInput{} + } + + output = &GetInstancePortStatesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetInstancePortStates API operation for Amazon Lightsail. +// +// Returns the port states for a specific virtual private server, or instance. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetInstancePortStates for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstancePortStates +func (c *Lightsail) GetInstancePortStates(input *GetInstancePortStatesInput) (*GetInstancePortStatesOutput, error) { + req, out := c.GetInstancePortStatesRequest(input) + return out, req.Send() +} + +// GetInstancePortStatesWithContext is the same as GetInstancePortStates with the addition of +// the ability to pass a context and additional request options. +// +// See GetInstancePortStates for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetInstancePortStatesWithContext(ctx aws.Context, input *GetInstancePortStatesInput, opts ...request.Option) (*GetInstancePortStatesOutput, error) { + req, out := c.GetInstancePortStatesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetInstanceSnapshot = "GetInstanceSnapshot" + +// GetInstanceSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the GetInstanceSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetInstanceSnapshot for more information on using the GetInstanceSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetInstanceSnapshotRequest method. +// req, resp := client.GetInstanceSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceSnapshot +func (c *Lightsail) GetInstanceSnapshotRequest(input *GetInstanceSnapshotInput) (req *request.Request, output *GetInstanceSnapshotOutput) { + op := &request.Operation{ + Name: opGetInstanceSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetInstanceSnapshotInput{} + } + + output = &GetInstanceSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetInstanceSnapshot API operation for Amazon Lightsail. +// +// Returns information about a specific instance snapshot. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetInstanceSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceSnapshot +func (c *Lightsail) GetInstanceSnapshot(input *GetInstanceSnapshotInput) (*GetInstanceSnapshotOutput, error) { + req, out := c.GetInstanceSnapshotRequest(input) + return out, req.Send() +} + +// GetInstanceSnapshotWithContext is the same as GetInstanceSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See GetInstanceSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetInstanceSnapshotWithContext(ctx aws.Context, input *GetInstanceSnapshotInput, opts ...request.Option) (*GetInstanceSnapshotOutput, error) { + req, out := c.GetInstanceSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetInstanceSnapshots = "GetInstanceSnapshots" + +// GetInstanceSnapshotsRequest generates a "aws/request.Request" representing the +// client's request for the GetInstanceSnapshots operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetInstanceSnapshots for more information on using the GetInstanceSnapshots +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetInstanceSnapshotsRequest method. +// req, resp := client.GetInstanceSnapshotsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceSnapshots +func (c *Lightsail) GetInstanceSnapshotsRequest(input *GetInstanceSnapshotsInput) (req *request.Request, output *GetInstanceSnapshotsOutput) { + op := &request.Operation{ + Name: opGetInstanceSnapshots, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetInstanceSnapshotsInput{} + } + + output = &GetInstanceSnapshotsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetInstanceSnapshots API operation for Amazon Lightsail. +// +// Returns all instance snapshots for the user's account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetInstanceSnapshots for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceSnapshots +func (c *Lightsail) GetInstanceSnapshots(input *GetInstanceSnapshotsInput) (*GetInstanceSnapshotsOutput, error) { + req, out := c.GetInstanceSnapshotsRequest(input) + return out, req.Send() +} + +// GetInstanceSnapshotsWithContext is the same as GetInstanceSnapshots with the addition of +// the ability to pass a context and additional request options. +// +// See GetInstanceSnapshots for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetInstanceSnapshotsWithContext(ctx aws.Context, input *GetInstanceSnapshotsInput, opts ...request.Option) (*GetInstanceSnapshotsOutput, error) { + req, out := c.GetInstanceSnapshotsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetInstanceState = "GetInstanceState" + +// GetInstanceStateRequest generates a "aws/request.Request" representing the +// client's request for the GetInstanceState operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetInstanceState for more information on using the GetInstanceState +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetInstanceStateRequest method. +// req, resp := client.GetInstanceStateRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceState +func (c *Lightsail) GetInstanceStateRequest(input *GetInstanceStateInput) (req *request.Request, output *GetInstanceStateOutput) { + op := &request.Operation{ + Name: opGetInstanceState, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetInstanceStateInput{} + } + + output = &GetInstanceStateOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetInstanceState API operation for Amazon Lightsail. +// +// Returns the state of a specific instance. Works on one instance at a time. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetInstanceState for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstanceState +func (c *Lightsail) GetInstanceState(input *GetInstanceStateInput) (*GetInstanceStateOutput, error) { + req, out := c.GetInstanceStateRequest(input) + return out, req.Send() +} + +// GetInstanceStateWithContext is the same as GetInstanceState with the addition of +// the ability to pass a context and additional request options. +// +// See GetInstanceState for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetInstanceStateWithContext(ctx aws.Context, input *GetInstanceStateInput, opts ...request.Option) (*GetInstanceStateOutput, error) { + req, out := c.GetInstanceStateRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetInstances = "GetInstances" + +// GetInstancesRequest generates a "aws/request.Request" representing the +// client's request for the GetInstances operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetInstances for more information on using the GetInstances +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetInstancesRequest method. +// req, resp := client.GetInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstances +func (c *Lightsail) GetInstancesRequest(input *GetInstancesInput) (req *request.Request, output *GetInstancesOutput) { + op := &request.Operation{ + Name: opGetInstances, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetInstancesInput{} + } + + output = &GetInstancesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetInstances API operation for Amazon Lightsail. +// +// Returns information about all Amazon Lightsail virtual private servers, or +// instances. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetInstances for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetInstances +func (c *Lightsail) GetInstances(input *GetInstancesInput) (*GetInstancesOutput, error) { + req, out := c.GetInstancesRequest(input) + return out, req.Send() +} + +// GetInstancesWithContext is the same as GetInstances with the addition of +// the ability to pass a context and additional request options. +// +// See GetInstances for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetInstancesWithContext(ctx aws.Context, input *GetInstancesInput, opts ...request.Option) (*GetInstancesOutput, error) { + req, out := c.GetInstancesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetKeyPair = "GetKeyPair" + +// GetKeyPairRequest generates a "aws/request.Request" representing the +// client's request for the GetKeyPair operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetKeyPair for more information on using the GetKeyPair +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetKeyPairRequest method. +// req, resp := client.GetKeyPairRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetKeyPair +func (c *Lightsail) GetKeyPairRequest(input *GetKeyPairInput) (req *request.Request, output *GetKeyPairOutput) { + op := &request.Operation{ + Name: opGetKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetKeyPairInput{} + } + + output = &GetKeyPairOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetKeyPair API operation for Amazon Lightsail. +// +// Returns information about a specific key pair. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetKeyPair for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetKeyPair +func (c *Lightsail) GetKeyPair(input *GetKeyPairInput) (*GetKeyPairOutput, error) { + req, out := c.GetKeyPairRequest(input) + return out, req.Send() +} + +// GetKeyPairWithContext is the same as GetKeyPair with the addition of +// the ability to pass a context and additional request options. +// +// See GetKeyPair for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetKeyPairWithContext(ctx aws.Context, input *GetKeyPairInput, opts ...request.Option) (*GetKeyPairOutput, error) { + req, out := c.GetKeyPairRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetKeyPairs = "GetKeyPairs" + +// GetKeyPairsRequest generates a "aws/request.Request" representing the +// client's request for the GetKeyPairs operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetKeyPairs for more information on using the GetKeyPairs +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetKeyPairsRequest method. +// req, resp := client.GetKeyPairsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetKeyPairs +func (c *Lightsail) GetKeyPairsRequest(input *GetKeyPairsInput) (req *request.Request, output *GetKeyPairsOutput) { + op := &request.Operation{ + Name: opGetKeyPairs, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetKeyPairsInput{} + } + + output = &GetKeyPairsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetKeyPairs API operation for Amazon Lightsail. +// +// Returns information about all key pairs in the user's account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetKeyPairs for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetKeyPairs +func (c *Lightsail) GetKeyPairs(input *GetKeyPairsInput) (*GetKeyPairsOutput, error) { + req, out := c.GetKeyPairsRequest(input) + return out, req.Send() +} + +// GetKeyPairsWithContext is the same as GetKeyPairs with the addition of +// the ability to pass a context and additional request options. +// +// See GetKeyPairs for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetKeyPairsWithContext(ctx aws.Context, input *GetKeyPairsInput, opts ...request.Option) (*GetKeyPairsOutput, error) { + req, out := c.GetKeyPairsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetLoadBalancer = "GetLoadBalancer" + +// GetLoadBalancerRequest generates a "aws/request.Request" representing the +// client's request for the GetLoadBalancer operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLoadBalancer for more information on using the GetLoadBalancer +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLoadBalancerRequest method. +// req, resp := client.GetLoadBalancerRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetLoadBalancer +func (c *Lightsail) GetLoadBalancerRequest(input *GetLoadBalancerInput) (req *request.Request, output *GetLoadBalancerOutput) { + op := &request.Operation{ + Name: opGetLoadBalancer, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetLoadBalancerInput{} + } + + output = &GetLoadBalancerOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLoadBalancer API operation for Amazon Lightsail. +// +// Returns information about the specified Lightsail load balancer. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetLoadBalancer for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetLoadBalancer +func (c *Lightsail) GetLoadBalancer(input *GetLoadBalancerInput) (*GetLoadBalancerOutput, error) { + req, out := c.GetLoadBalancerRequest(input) + return out, req.Send() +} + +// GetLoadBalancerWithContext is the same as GetLoadBalancer with the addition of +// the ability to pass a context and additional request options. +// +// See GetLoadBalancer for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetLoadBalancerWithContext(ctx aws.Context, input *GetLoadBalancerInput, opts ...request.Option) (*GetLoadBalancerOutput, error) { + req, out := c.GetLoadBalancerRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetLoadBalancerMetricData = "GetLoadBalancerMetricData" + +// GetLoadBalancerMetricDataRequest generates a "aws/request.Request" representing the +// client's request for the GetLoadBalancerMetricData operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLoadBalancerMetricData for more information on using the GetLoadBalancerMetricData +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLoadBalancerMetricDataRequest method. +// req, resp := client.GetLoadBalancerMetricDataRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetLoadBalancerMetricData +func (c *Lightsail) GetLoadBalancerMetricDataRequest(input *GetLoadBalancerMetricDataInput) (req *request.Request, output *GetLoadBalancerMetricDataOutput) { + op := &request.Operation{ + Name: opGetLoadBalancerMetricData, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetLoadBalancerMetricDataInput{} + } + + output = &GetLoadBalancerMetricDataOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLoadBalancerMetricData API operation for Amazon Lightsail. +// +// Returns information about health metrics for your Lightsail load balancer. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetLoadBalancerMetricData for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetLoadBalancerMetricData +func (c *Lightsail) GetLoadBalancerMetricData(input *GetLoadBalancerMetricDataInput) (*GetLoadBalancerMetricDataOutput, error) { + req, out := c.GetLoadBalancerMetricDataRequest(input) + return out, req.Send() +} + +// GetLoadBalancerMetricDataWithContext is the same as GetLoadBalancerMetricData with the addition of +// the ability to pass a context and additional request options. +// +// See GetLoadBalancerMetricData for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetLoadBalancerMetricDataWithContext(ctx aws.Context, input *GetLoadBalancerMetricDataInput, opts ...request.Option) (*GetLoadBalancerMetricDataOutput, error) { + req, out := c.GetLoadBalancerMetricDataRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetLoadBalancerTlsCertificates = "GetLoadBalancerTlsCertificates" + +// GetLoadBalancerTlsCertificatesRequest generates a "aws/request.Request" representing the +// client's request for the GetLoadBalancerTlsCertificates operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLoadBalancerTlsCertificates for more information on using the GetLoadBalancerTlsCertificates +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLoadBalancerTlsCertificatesRequest method. +// req, resp := client.GetLoadBalancerTlsCertificatesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetLoadBalancerTlsCertificates +func (c *Lightsail) GetLoadBalancerTlsCertificatesRequest(input *GetLoadBalancerTlsCertificatesInput) (req *request.Request, output *GetLoadBalancerTlsCertificatesOutput) { + op := &request.Operation{ + Name: opGetLoadBalancerTlsCertificates, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetLoadBalancerTlsCertificatesInput{} + } + + output = &GetLoadBalancerTlsCertificatesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLoadBalancerTlsCertificates API operation for Amazon Lightsail. +// +// Returns information about the TLS certificates that are associated with the +// specified Lightsail load balancer. +// +// TLS is just an updated, more secure version of Secure Socket Layer (SSL). +// +// You can have a maximum of 2 certificates associated with a Lightsail load +// balancer. One is active and the other is inactive. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetLoadBalancerTlsCertificates for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetLoadBalancerTlsCertificates +func (c *Lightsail) GetLoadBalancerTlsCertificates(input *GetLoadBalancerTlsCertificatesInput) (*GetLoadBalancerTlsCertificatesOutput, error) { + req, out := c.GetLoadBalancerTlsCertificatesRequest(input) + return out, req.Send() +} + +// GetLoadBalancerTlsCertificatesWithContext is the same as GetLoadBalancerTlsCertificates with the addition of +// the ability to pass a context and additional request options. +// +// See GetLoadBalancerTlsCertificates for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetLoadBalancerTlsCertificatesWithContext(ctx aws.Context, input *GetLoadBalancerTlsCertificatesInput, opts ...request.Option) (*GetLoadBalancerTlsCertificatesOutput, error) { + req, out := c.GetLoadBalancerTlsCertificatesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetLoadBalancers = "GetLoadBalancers" + +// GetLoadBalancersRequest generates a "aws/request.Request" representing the +// client's request for the GetLoadBalancers operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetLoadBalancers for more information on using the GetLoadBalancers +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetLoadBalancersRequest method. +// req, resp := client.GetLoadBalancersRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetLoadBalancers +func (c *Lightsail) GetLoadBalancersRequest(input *GetLoadBalancersInput) (req *request.Request, output *GetLoadBalancersOutput) { + op := &request.Operation{ + Name: opGetLoadBalancers, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetLoadBalancersInput{} + } + + output = &GetLoadBalancersOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetLoadBalancers API operation for Amazon Lightsail. +// +// Returns information about all load balancers in an account. +// +// If you are describing a long list of load balancers, you can paginate the +// output to make the list more manageable. You can use the pageToken and nextPageToken +// values to retrieve the next items in the list. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetLoadBalancers for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetLoadBalancers +func (c *Lightsail) GetLoadBalancers(input *GetLoadBalancersInput) (*GetLoadBalancersOutput, error) { + req, out := c.GetLoadBalancersRequest(input) + return out, req.Send() +} + +// GetLoadBalancersWithContext is the same as GetLoadBalancers with the addition of +// the ability to pass a context and additional request options. +// +// See GetLoadBalancers for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetLoadBalancersWithContext(ctx aws.Context, input *GetLoadBalancersInput, opts ...request.Option) (*GetLoadBalancersOutput, error) { + req, out := c.GetLoadBalancersRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetOperation = "GetOperation" + +// GetOperationRequest generates a "aws/request.Request" representing the +// client's request for the GetOperation operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetOperation for more information on using the GetOperation +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetOperationRequest method. +// req, resp := client.GetOperationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetOperation +func (c *Lightsail) GetOperationRequest(input *GetOperationInput) (req *request.Request, output *GetOperationOutput) { + op := &request.Operation{ + Name: opGetOperation, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetOperationInput{} + } + + output = &GetOperationOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetOperation API operation for Amazon Lightsail. +// +// Returns information about a specific operation. Operations include events +// such as when you create an instance, allocate a static IP, attach a static +// IP, and so on. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetOperation for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetOperation +func (c *Lightsail) GetOperation(input *GetOperationInput) (*GetOperationOutput, error) { + req, out := c.GetOperationRequest(input) + return out, req.Send() +} + +// GetOperationWithContext is the same as GetOperation with the addition of +// the ability to pass a context and additional request options. +// +// See GetOperation for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetOperationWithContext(ctx aws.Context, input *GetOperationInput, opts ...request.Option) (*GetOperationOutput, error) { + req, out := c.GetOperationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetOperations = "GetOperations" + +// GetOperationsRequest generates a "aws/request.Request" representing the +// client's request for the GetOperations operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetOperations for more information on using the GetOperations +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetOperationsRequest method. +// req, resp := client.GetOperationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetOperations +func (c *Lightsail) GetOperationsRequest(input *GetOperationsInput) (req *request.Request, output *GetOperationsOutput) { + op := &request.Operation{ + Name: opGetOperations, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetOperationsInput{} + } + + output = &GetOperationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetOperations API operation for Amazon Lightsail. +// +// Returns information about all operations. +// +// Results are returned from oldest to newest, up to a maximum of 200. Results +// can be paged by making each subsequent call to GetOperations use the maximum +// (last) statusChangedAt value from the previous request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetOperations for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetOperations +func (c *Lightsail) GetOperations(input *GetOperationsInput) (*GetOperationsOutput, error) { + req, out := c.GetOperationsRequest(input) + return out, req.Send() +} + +// GetOperationsWithContext is the same as GetOperations with the addition of +// the ability to pass a context and additional request options. +// +// See GetOperations for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetOperationsWithContext(ctx aws.Context, input *GetOperationsInput, opts ...request.Option) (*GetOperationsOutput, error) { + req, out := c.GetOperationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetOperationsForResource = "GetOperationsForResource" + +// GetOperationsForResourceRequest generates a "aws/request.Request" representing the +// client's request for the GetOperationsForResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetOperationsForResource for more information on using the GetOperationsForResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetOperationsForResourceRequest method. +// req, resp := client.GetOperationsForResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetOperationsForResource +func (c *Lightsail) GetOperationsForResourceRequest(input *GetOperationsForResourceInput) (req *request.Request, output *GetOperationsForResourceOutput) { + op := &request.Operation{ + Name: opGetOperationsForResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetOperationsForResourceInput{} + } + + output = &GetOperationsForResourceOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetOperationsForResource API operation for Amazon Lightsail. +// +// Gets operations for a specific resource (e.g., an instance or a static IP). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetOperationsForResource for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetOperationsForResource +func (c *Lightsail) GetOperationsForResource(input *GetOperationsForResourceInput) (*GetOperationsForResourceOutput, error) { + req, out := c.GetOperationsForResourceRequest(input) + return out, req.Send() +} + +// GetOperationsForResourceWithContext is the same as GetOperationsForResource with the addition of +// the ability to pass a context and additional request options. +// +// See GetOperationsForResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetOperationsForResourceWithContext(ctx aws.Context, input *GetOperationsForResourceInput, opts ...request.Option) (*GetOperationsForResourceOutput, error) { + req, out := c.GetOperationsForResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRegions = "GetRegions" + +// GetRegionsRequest generates a "aws/request.Request" representing the +// client's request for the GetRegions operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRegions for more information on using the GetRegions +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRegionsRequest method. +// req, resp := client.GetRegionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRegions +func (c *Lightsail) GetRegionsRequest(input *GetRegionsInput) (req *request.Request, output *GetRegionsOutput) { + op := &request.Operation{ + Name: opGetRegions, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRegionsInput{} + } + + output = &GetRegionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRegions API operation for Amazon Lightsail. +// +// Returns a list of all valid regions for Amazon Lightsail. Use the include +// availability zones parameter to also return the Availability Zones in a region. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRegions for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRegions +func (c *Lightsail) GetRegions(input *GetRegionsInput) (*GetRegionsOutput, error) { + req, out := c.GetRegionsRequest(input) + return out, req.Send() +} + +// GetRegionsWithContext is the same as GetRegions with the addition of +// the ability to pass a context and additional request options. +// +// See GetRegions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRegionsWithContext(ctx aws.Context, input *GetRegionsInput, opts ...request.Option) (*GetRegionsOutput, error) { + req, out := c.GetRegionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabase = "GetRelationalDatabase" + +// GetRelationalDatabaseRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabase operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabase for more information on using the GetRelationalDatabase +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseRequest method. +// req, resp := client.GetRelationalDatabaseRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabase +func (c *Lightsail) GetRelationalDatabaseRequest(input *GetRelationalDatabaseInput) (req *request.Request, output *GetRelationalDatabaseOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabase, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseInput{} + } + + output = &GetRelationalDatabaseOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabase API operation for Amazon Lightsail. +// +// Returns information about a specific database in Amazon Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabase for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabase +func (c *Lightsail) GetRelationalDatabase(input *GetRelationalDatabaseInput) (*GetRelationalDatabaseOutput, error) { + req, out := c.GetRelationalDatabaseRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseWithContext is the same as GetRelationalDatabase with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabase for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseWithContext(ctx aws.Context, input *GetRelationalDatabaseInput, opts ...request.Option) (*GetRelationalDatabaseOutput, error) { + req, out := c.GetRelationalDatabaseRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseBlueprints = "GetRelationalDatabaseBlueprints" + +// GetRelationalDatabaseBlueprintsRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseBlueprints operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseBlueprints for more information on using the GetRelationalDatabaseBlueprints +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseBlueprintsRequest method. +// req, resp := client.GetRelationalDatabaseBlueprintsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseBlueprints +func (c *Lightsail) GetRelationalDatabaseBlueprintsRequest(input *GetRelationalDatabaseBlueprintsInput) (req *request.Request, output *GetRelationalDatabaseBlueprintsOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseBlueprints, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseBlueprintsInput{} + } + + output = &GetRelationalDatabaseBlueprintsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseBlueprints API operation for Amazon Lightsail. +// +// Returns a list of available database blueprints in Amazon Lightsail. A blueprint +// describes the major engine version of a database. +// +// You can use a blueprint ID to create a new database that runs a specific +// database engine. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseBlueprints for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseBlueprints +func (c *Lightsail) GetRelationalDatabaseBlueprints(input *GetRelationalDatabaseBlueprintsInput) (*GetRelationalDatabaseBlueprintsOutput, error) { + req, out := c.GetRelationalDatabaseBlueprintsRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseBlueprintsWithContext is the same as GetRelationalDatabaseBlueprints with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseBlueprints for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseBlueprintsWithContext(ctx aws.Context, input *GetRelationalDatabaseBlueprintsInput, opts ...request.Option) (*GetRelationalDatabaseBlueprintsOutput, error) { + req, out := c.GetRelationalDatabaseBlueprintsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseBundles = "GetRelationalDatabaseBundles" + +// GetRelationalDatabaseBundlesRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseBundles operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseBundles for more information on using the GetRelationalDatabaseBundles +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseBundlesRequest method. +// req, resp := client.GetRelationalDatabaseBundlesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseBundles +func (c *Lightsail) GetRelationalDatabaseBundlesRequest(input *GetRelationalDatabaseBundlesInput) (req *request.Request, output *GetRelationalDatabaseBundlesOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseBundles, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseBundlesInput{} + } + + output = &GetRelationalDatabaseBundlesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseBundles API operation for Amazon Lightsail. +// +// Returns the list of bundles that are available in Amazon Lightsail. A bundle +// describes the performance specifications for a database. +// +// You can use a bundle ID to create a new database with explicit performance +// specifications. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseBundles for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseBundles +func (c *Lightsail) GetRelationalDatabaseBundles(input *GetRelationalDatabaseBundlesInput) (*GetRelationalDatabaseBundlesOutput, error) { + req, out := c.GetRelationalDatabaseBundlesRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseBundlesWithContext is the same as GetRelationalDatabaseBundles with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseBundles for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseBundlesWithContext(ctx aws.Context, input *GetRelationalDatabaseBundlesInput, opts ...request.Option) (*GetRelationalDatabaseBundlesOutput, error) { + req, out := c.GetRelationalDatabaseBundlesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseEvents = "GetRelationalDatabaseEvents" + +// GetRelationalDatabaseEventsRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseEvents operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseEvents for more information on using the GetRelationalDatabaseEvents +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseEventsRequest method. +// req, resp := client.GetRelationalDatabaseEventsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseEvents +func (c *Lightsail) GetRelationalDatabaseEventsRequest(input *GetRelationalDatabaseEventsInput) (req *request.Request, output *GetRelationalDatabaseEventsOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseEvents, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseEventsInput{} + } + + output = &GetRelationalDatabaseEventsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseEvents API operation for Amazon Lightsail. +// +// Returns a list of events for a specific database in Amazon Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseEvents for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseEvents +func (c *Lightsail) GetRelationalDatabaseEvents(input *GetRelationalDatabaseEventsInput) (*GetRelationalDatabaseEventsOutput, error) { + req, out := c.GetRelationalDatabaseEventsRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseEventsWithContext is the same as GetRelationalDatabaseEvents with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseEvents for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseEventsWithContext(ctx aws.Context, input *GetRelationalDatabaseEventsInput, opts ...request.Option) (*GetRelationalDatabaseEventsOutput, error) { + req, out := c.GetRelationalDatabaseEventsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseLogEvents = "GetRelationalDatabaseLogEvents" + +// GetRelationalDatabaseLogEventsRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseLogEvents operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseLogEvents for more information on using the GetRelationalDatabaseLogEvents +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseLogEventsRequest method. +// req, resp := client.GetRelationalDatabaseLogEventsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseLogEvents +func (c *Lightsail) GetRelationalDatabaseLogEventsRequest(input *GetRelationalDatabaseLogEventsInput) (req *request.Request, output *GetRelationalDatabaseLogEventsOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseLogEvents, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseLogEventsInput{} + } + + output = &GetRelationalDatabaseLogEventsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseLogEvents API operation for Amazon Lightsail. +// +// Returns a list of log events for a database in Amazon Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseLogEvents for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseLogEvents +func (c *Lightsail) GetRelationalDatabaseLogEvents(input *GetRelationalDatabaseLogEventsInput) (*GetRelationalDatabaseLogEventsOutput, error) { + req, out := c.GetRelationalDatabaseLogEventsRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseLogEventsWithContext is the same as GetRelationalDatabaseLogEvents with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseLogEvents for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseLogEventsWithContext(ctx aws.Context, input *GetRelationalDatabaseLogEventsInput, opts ...request.Option) (*GetRelationalDatabaseLogEventsOutput, error) { + req, out := c.GetRelationalDatabaseLogEventsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseLogStreams = "GetRelationalDatabaseLogStreams" + +// GetRelationalDatabaseLogStreamsRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseLogStreams operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseLogStreams for more information on using the GetRelationalDatabaseLogStreams +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseLogStreamsRequest method. +// req, resp := client.GetRelationalDatabaseLogStreamsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseLogStreams +func (c *Lightsail) GetRelationalDatabaseLogStreamsRequest(input *GetRelationalDatabaseLogStreamsInput) (req *request.Request, output *GetRelationalDatabaseLogStreamsOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseLogStreams, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseLogStreamsInput{} + } + + output = &GetRelationalDatabaseLogStreamsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseLogStreams API operation for Amazon Lightsail. +// +// Returns a list of available log streams for a specific database in Amazon +// Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseLogStreams for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseLogStreams +func (c *Lightsail) GetRelationalDatabaseLogStreams(input *GetRelationalDatabaseLogStreamsInput) (*GetRelationalDatabaseLogStreamsOutput, error) { + req, out := c.GetRelationalDatabaseLogStreamsRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseLogStreamsWithContext is the same as GetRelationalDatabaseLogStreams with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseLogStreams for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseLogStreamsWithContext(ctx aws.Context, input *GetRelationalDatabaseLogStreamsInput, opts ...request.Option) (*GetRelationalDatabaseLogStreamsOutput, error) { + req, out := c.GetRelationalDatabaseLogStreamsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseMasterUserPassword = "GetRelationalDatabaseMasterUserPassword" + +// GetRelationalDatabaseMasterUserPasswordRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseMasterUserPassword operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseMasterUserPassword for more information on using the GetRelationalDatabaseMasterUserPassword +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseMasterUserPasswordRequest method. +// req, resp := client.GetRelationalDatabaseMasterUserPasswordRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseMasterUserPassword +func (c *Lightsail) GetRelationalDatabaseMasterUserPasswordRequest(input *GetRelationalDatabaseMasterUserPasswordInput) (req *request.Request, output *GetRelationalDatabaseMasterUserPasswordOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseMasterUserPassword, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseMasterUserPasswordInput{} + } + + output = &GetRelationalDatabaseMasterUserPasswordOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseMasterUserPassword API operation for Amazon Lightsail. +// +// Returns the current, previous, or pending versions of the master user password +// for a Lightsail database. +// +// The asdf operation GetRelationalDatabaseMasterUserPassword supports tag-based +// access control via resource tags applied to the resource identified by relationalDatabaseName. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseMasterUserPassword for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseMasterUserPassword +func (c *Lightsail) GetRelationalDatabaseMasterUserPassword(input *GetRelationalDatabaseMasterUserPasswordInput) (*GetRelationalDatabaseMasterUserPasswordOutput, error) { + req, out := c.GetRelationalDatabaseMasterUserPasswordRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseMasterUserPasswordWithContext is the same as GetRelationalDatabaseMasterUserPassword with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseMasterUserPassword for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseMasterUserPasswordWithContext(ctx aws.Context, input *GetRelationalDatabaseMasterUserPasswordInput, opts ...request.Option) (*GetRelationalDatabaseMasterUserPasswordOutput, error) { + req, out := c.GetRelationalDatabaseMasterUserPasswordRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseMetricData = "GetRelationalDatabaseMetricData" + +// GetRelationalDatabaseMetricDataRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseMetricData operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseMetricData for more information on using the GetRelationalDatabaseMetricData +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseMetricDataRequest method. +// req, resp := client.GetRelationalDatabaseMetricDataRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseMetricData +func (c *Lightsail) GetRelationalDatabaseMetricDataRequest(input *GetRelationalDatabaseMetricDataInput) (req *request.Request, output *GetRelationalDatabaseMetricDataOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseMetricData, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseMetricDataInput{} + } + + output = &GetRelationalDatabaseMetricDataOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseMetricData API operation for Amazon Lightsail. +// +// Returns the data points of the specified metric for a database in Amazon +// Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseMetricData for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseMetricData +func (c *Lightsail) GetRelationalDatabaseMetricData(input *GetRelationalDatabaseMetricDataInput) (*GetRelationalDatabaseMetricDataOutput, error) { + req, out := c.GetRelationalDatabaseMetricDataRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseMetricDataWithContext is the same as GetRelationalDatabaseMetricData with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseMetricData for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseMetricDataWithContext(ctx aws.Context, input *GetRelationalDatabaseMetricDataInput, opts ...request.Option) (*GetRelationalDatabaseMetricDataOutput, error) { + req, out := c.GetRelationalDatabaseMetricDataRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseParameters = "GetRelationalDatabaseParameters" + +// GetRelationalDatabaseParametersRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseParameters operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseParameters for more information on using the GetRelationalDatabaseParameters +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseParametersRequest method. +// req, resp := client.GetRelationalDatabaseParametersRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseParameters +func (c *Lightsail) GetRelationalDatabaseParametersRequest(input *GetRelationalDatabaseParametersInput) (req *request.Request, output *GetRelationalDatabaseParametersOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseParameters, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseParametersInput{} + } + + output = &GetRelationalDatabaseParametersOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseParameters API operation for Amazon Lightsail. +// +// Returns all of the runtime parameters offered by the underlying database +// software, or engine, for a specific database in Amazon Lightsail. +// +// In addition to the parameter names and values, this operation returns other +// information about each parameter. This information includes whether changes +// require a reboot, whether the parameter is modifiable, the allowed values, +// and the data types. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseParameters for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseParameters +func (c *Lightsail) GetRelationalDatabaseParameters(input *GetRelationalDatabaseParametersInput) (*GetRelationalDatabaseParametersOutput, error) { + req, out := c.GetRelationalDatabaseParametersRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseParametersWithContext is the same as GetRelationalDatabaseParameters with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseParameters for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseParametersWithContext(ctx aws.Context, input *GetRelationalDatabaseParametersInput, opts ...request.Option) (*GetRelationalDatabaseParametersOutput, error) { + req, out := c.GetRelationalDatabaseParametersRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseSnapshot = "GetRelationalDatabaseSnapshot" + +// GetRelationalDatabaseSnapshotRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseSnapshot operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseSnapshot for more information on using the GetRelationalDatabaseSnapshot +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseSnapshotRequest method. +// req, resp := client.GetRelationalDatabaseSnapshotRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseSnapshot +func (c *Lightsail) GetRelationalDatabaseSnapshotRequest(input *GetRelationalDatabaseSnapshotInput) (req *request.Request, output *GetRelationalDatabaseSnapshotOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseSnapshot, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseSnapshotInput{} + } + + output = &GetRelationalDatabaseSnapshotOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseSnapshot API operation for Amazon Lightsail. +// +// Returns information about a specific database snapshot in Amazon Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseSnapshot for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseSnapshot +func (c *Lightsail) GetRelationalDatabaseSnapshot(input *GetRelationalDatabaseSnapshotInput) (*GetRelationalDatabaseSnapshotOutput, error) { + req, out := c.GetRelationalDatabaseSnapshotRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseSnapshotWithContext is the same as GetRelationalDatabaseSnapshot with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseSnapshot for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseSnapshotWithContext(ctx aws.Context, input *GetRelationalDatabaseSnapshotInput, opts ...request.Option) (*GetRelationalDatabaseSnapshotOutput, error) { + req, out := c.GetRelationalDatabaseSnapshotRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabaseSnapshots = "GetRelationalDatabaseSnapshots" + +// GetRelationalDatabaseSnapshotsRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabaseSnapshots operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabaseSnapshots for more information on using the GetRelationalDatabaseSnapshots +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabaseSnapshotsRequest method. +// req, resp := client.GetRelationalDatabaseSnapshotsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseSnapshots +func (c *Lightsail) GetRelationalDatabaseSnapshotsRequest(input *GetRelationalDatabaseSnapshotsInput) (req *request.Request, output *GetRelationalDatabaseSnapshotsOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabaseSnapshots, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabaseSnapshotsInput{} + } + + output = &GetRelationalDatabaseSnapshotsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabaseSnapshots API operation for Amazon Lightsail. +// +// Returns information about all of your database snapshots in Amazon Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabaseSnapshots for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabaseSnapshots +func (c *Lightsail) GetRelationalDatabaseSnapshots(input *GetRelationalDatabaseSnapshotsInput) (*GetRelationalDatabaseSnapshotsOutput, error) { + req, out := c.GetRelationalDatabaseSnapshotsRequest(input) + return out, req.Send() +} + +// GetRelationalDatabaseSnapshotsWithContext is the same as GetRelationalDatabaseSnapshots with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabaseSnapshots for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabaseSnapshotsWithContext(ctx aws.Context, input *GetRelationalDatabaseSnapshotsInput, opts ...request.Option) (*GetRelationalDatabaseSnapshotsOutput, error) { + req, out := c.GetRelationalDatabaseSnapshotsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetRelationalDatabases = "GetRelationalDatabases" + +// GetRelationalDatabasesRequest generates a "aws/request.Request" representing the +// client's request for the GetRelationalDatabases operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetRelationalDatabases for more information on using the GetRelationalDatabases +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetRelationalDatabasesRequest method. +// req, resp := client.GetRelationalDatabasesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabases +func (c *Lightsail) GetRelationalDatabasesRequest(input *GetRelationalDatabasesInput) (req *request.Request, output *GetRelationalDatabasesOutput) { + op := &request.Operation{ + Name: opGetRelationalDatabases, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetRelationalDatabasesInput{} + } + + output = &GetRelationalDatabasesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetRelationalDatabases API operation for Amazon Lightsail. +// +// Returns information about all of your databases in Amazon Lightsail. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetRelationalDatabases for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetRelationalDatabases +func (c *Lightsail) GetRelationalDatabases(input *GetRelationalDatabasesInput) (*GetRelationalDatabasesOutput, error) { + req, out := c.GetRelationalDatabasesRequest(input) + return out, req.Send() +} + +// GetRelationalDatabasesWithContext is the same as GetRelationalDatabases with the addition of +// the ability to pass a context and additional request options. +// +// See GetRelationalDatabases for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetRelationalDatabasesWithContext(ctx aws.Context, input *GetRelationalDatabasesInput, opts ...request.Option) (*GetRelationalDatabasesOutput, error) { + req, out := c.GetRelationalDatabasesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetStaticIp = "GetStaticIp" + +// GetStaticIpRequest generates a "aws/request.Request" representing the +// client's request for the GetStaticIp operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetStaticIp for more information on using the GetStaticIp +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetStaticIpRequest method. +// req, resp := client.GetStaticIpRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetStaticIp +func (c *Lightsail) GetStaticIpRequest(input *GetStaticIpInput) (req *request.Request, output *GetStaticIpOutput) { + op := &request.Operation{ + Name: opGetStaticIp, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetStaticIpInput{} + } + + output = &GetStaticIpOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetStaticIp API operation for Amazon Lightsail. +// +// Returns information about a specific static IP. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetStaticIp for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetStaticIp +func (c *Lightsail) GetStaticIp(input *GetStaticIpInput) (*GetStaticIpOutput, error) { + req, out := c.GetStaticIpRequest(input) + return out, req.Send() +} + +// GetStaticIpWithContext is the same as GetStaticIp with the addition of +// the ability to pass a context and additional request options. +// +// See GetStaticIp for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetStaticIpWithContext(ctx aws.Context, input *GetStaticIpInput, opts ...request.Option) (*GetStaticIpOutput, error) { + req, out := c.GetStaticIpRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetStaticIps = "GetStaticIps" + +// GetStaticIpsRequest generates a "aws/request.Request" representing the +// client's request for the GetStaticIps operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetStaticIps for more information on using the GetStaticIps +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetStaticIpsRequest method. +// req, resp := client.GetStaticIpsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetStaticIps +func (c *Lightsail) GetStaticIpsRequest(input *GetStaticIpsInput) (req *request.Request, output *GetStaticIpsOutput) { + op := &request.Operation{ + Name: opGetStaticIps, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetStaticIpsInput{} + } + + output = &GetStaticIpsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetStaticIps API operation for Amazon Lightsail. +// +// Returns information about all static IPs in the user's account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation GetStaticIps for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/GetStaticIps +func (c *Lightsail) GetStaticIps(input *GetStaticIpsInput) (*GetStaticIpsOutput, error) { + req, out := c.GetStaticIpsRequest(input) + return out, req.Send() +} + +// GetStaticIpsWithContext is the same as GetStaticIps with the addition of +// the ability to pass a context and additional request options. +// +// See GetStaticIps for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) GetStaticIpsWithContext(ctx aws.Context, input *GetStaticIpsInput, opts ...request.Option) (*GetStaticIpsOutput, error) { + req, out := c.GetStaticIpsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opImportKeyPair = "ImportKeyPair" + +// ImportKeyPairRequest generates a "aws/request.Request" representing the +// client's request for the ImportKeyPair operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ImportKeyPair for more information on using the ImportKeyPair +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ImportKeyPairRequest method. +// req, resp := client.ImportKeyPairRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/ImportKeyPair +func (c *Lightsail) ImportKeyPairRequest(input *ImportKeyPairInput) (req *request.Request, output *ImportKeyPairOutput) { + op := &request.Operation{ + Name: opImportKeyPair, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ImportKeyPairInput{} + } + + output = &ImportKeyPairOutput{} + req = c.newRequest(op, input, output) + return +} + +// ImportKeyPair API operation for Amazon Lightsail. +// +// Imports a public SSH key from a specific key pair. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation ImportKeyPair for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/ImportKeyPair +func (c *Lightsail) ImportKeyPair(input *ImportKeyPairInput) (*ImportKeyPairOutput, error) { + req, out := c.ImportKeyPairRequest(input) + return out, req.Send() +} + +// ImportKeyPairWithContext is the same as ImportKeyPair with the addition of +// the ability to pass a context and additional request options. +// +// See ImportKeyPair for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) ImportKeyPairWithContext(ctx aws.Context, input *ImportKeyPairInput, opts ...request.Option) (*ImportKeyPairOutput, error) { + req, out := c.ImportKeyPairRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opIsVpcPeered = "IsVpcPeered" + +// IsVpcPeeredRequest generates a "aws/request.Request" representing the +// client's request for the IsVpcPeered operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See IsVpcPeered for more information on using the IsVpcPeered +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the IsVpcPeeredRequest method. +// req, resp := client.IsVpcPeeredRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/IsVpcPeered +func (c *Lightsail) IsVpcPeeredRequest(input *IsVpcPeeredInput) (req *request.Request, output *IsVpcPeeredOutput) { + op := &request.Operation{ + Name: opIsVpcPeered, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &IsVpcPeeredInput{} + } + + output = &IsVpcPeeredOutput{} + req = c.newRequest(op, input, output) + return +} + +// IsVpcPeered API operation for Amazon Lightsail. +// +// Returns a Boolean value indicating whether your Lightsail VPC is peered. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation IsVpcPeered for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/IsVpcPeered +func (c *Lightsail) IsVpcPeered(input *IsVpcPeeredInput) (*IsVpcPeeredOutput, error) { + req, out := c.IsVpcPeeredRequest(input) + return out, req.Send() +} + +// IsVpcPeeredWithContext is the same as IsVpcPeered with the addition of +// the ability to pass a context and additional request options. +// +// See IsVpcPeered for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) IsVpcPeeredWithContext(ctx aws.Context, input *IsVpcPeeredInput, opts ...request.Option) (*IsVpcPeeredOutput, error) { + req, out := c.IsVpcPeeredRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opOpenInstancePublicPorts = "OpenInstancePublicPorts" + +// OpenInstancePublicPortsRequest generates a "aws/request.Request" representing the +// client's request for the OpenInstancePublicPorts operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See OpenInstancePublicPorts for more information on using the OpenInstancePublicPorts +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the OpenInstancePublicPortsRequest method. +// req, resp := client.OpenInstancePublicPortsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/OpenInstancePublicPorts +func (c *Lightsail) OpenInstancePublicPortsRequest(input *OpenInstancePublicPortsInput) (req *request.Request, output *OpenInstancePublicPortsOutput) { + op := &request.Operation{ + Name: opOpenInstancePublicPorts, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &OpenInstancePublicPortsInput{} + } + + output = &OpenInstancePublicPortsOutput{} + req = c.newRequest(op, input, output) + return +} + +// OpenInstancePublicPorts API operation for Amazon Lightsail. +// +// Adds public ports to an Amazon Lightsail instance. +// +// The open instance public ports operation supports tag-based access control +// via resource tags applied to the resource identified by instanceName. For +// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation OpenInstancePublicPorts for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/OpenInstancePublicPorts +func (c *Lightsail) OpenInstancePublicPorts(input *OpenInstancePublicPortsInput) (*OpenInstancePublicPortsOutput, error) { + req, out := c.OpenInstancePublicPortsRequest(input) + return out, req.Send() +} + +// OpenInstancePublicPortsWithContext is the same as OpenInstancePublicPorts with the addition of +// the ability to pass a context and additional request options. +// +// See OpenInstancePublicPorts for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) OpenInstancePublicPortsWithContext(ctx aws.Context, input *OpenInstancePublicPortsInput, opts ...request.Option) (*OpenInstancePublicPortsOutput, error) { + req, out := c.OpenInstancePublicPortsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opPeerVpc = "PeerVpc" + +// PeerVpcRequest generates a "aws/request.Request" representing the +// client's request for the PeerVpc operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PeerVpc for more information on using the PeerVpc +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PeerVpcRequest method. +// req, resp := client.PeerVpcRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/PeerVpc +func (c *Lightsail) PeerVpcRequest(input *PeerVpcInput) (req *request.Request, output *PeerVpcOutput) { + op := &request.Operation{ + Name: opPeerVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PeerVpcInput{} + } + + output = &PeerVpcOutput{} + req = c.newRequest(op, input, output) + return +} + +// PeerVpc API operation for Amazon Lightsail. +// +// Tries to peer the Lightsail VPC with the user's default VPC. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation PeerVpc for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/PeerVpc +func (c *Lightsail) PeerVpc(input *PeerVpcInput) (*PeerVpcOutput, error) { + req, out := c.PeerVpcRequest(input) + return out, req.Send() +} + +// PeerVpcWithContext is the same as PeerVpc with the addition of +// the ability to pass a context and additional request options. +// +// See PeerVpc for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) PeerVpcWithContext(ctx aws.Context, input *PeerVpcInput, opts ...request.Option) (*PeerVpcOutput, error) { + req, out := c.PeerVpcRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opPutInstancePublicPorts = "PutInstancePublicPorts" + +// PutInstancePublicPortsRequest generates a "aws/request.Request" representing the +// client's request for the PutInstancePublicPorts operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PutInstancePublicPorts for more information on using the PutInstancePublicPorts +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PutInstancePublicPortsRequest method. +// req, resp := client.PutInstancePublicPortsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/PutInstancePublicPorts +func (c *Lightsail) PutInstancePublicPortsRequest(input *PutInstancePublicPortsInput) (req *request.Request, output *PutInstancePublicPortsOutput) { + op := &request.Operation{ + Name: opPutInstancePublicPorts, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &PutInstancePublicPortsInput{} + } + + output = &PutInstancePublicPortsOutput{} + req = c.newRequest(op, input, output) + return +} + +// PutInstancePublicPorts API operation for Amazon Lightsail. +// +// Sets the specified open ports for an Amazon Lightsail instance, and closes +// all ports for every protocol not included in the current request. +// +// The put instance public ports operation supports tag-based access control +// via resource tags applied to the resource identified by instanceName. For +// more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation PutInstancePublicPorts for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/PutInstancePublicPorts +func (c *Lightsail) PutInstancePublicPorts(input *PutInstancePublicPortsInput) (*PutInstancePublicPortsOutput, error) { + req, out := c.PutInstancePublicPortsRequest(input) + return out, req.Send() +} + +// PutInstancePublicPortsWithContext is the same as PutInstancePublicPorts with the addition of +// the ability to pass a context and additional request options. +// +// See PutInstancePublicPorts for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) PutInstancePublicPortsWithContext(ctx aws.Context, input *PutInstancePublicPortsInput, opts ...request.Option) (*PutInstancePublicPortsOutput, error) { + req, out := c.PutInstancePublicPortsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opRebootInstance = "RebootInstance" + +// RebootInstanceRequest generates a "aws/request.Request" representing the +// client's request for the RebootInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See RebootInstance for more information on using the RebootInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the RebootInstanceRequest method. +// req, resp := client.RebootInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/RebootInstance +func (c *Lightsail) RebootInstanceRequest(input *RebootInstanceInput) (req *request.Request, output *RebootInstanceOutput) { + op := &request.Operation{ + Name: opRebootInstance, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RebootInstanceInput{} + } + + output = &RebootInstanceOutput{} + req = c.newRequest(op, input, output) + return +} + +// RebootInstance API operation for Amazon Lightsail. +// +// Restarts a specific instance. +// +// The reboot instance operation supports tag-based access control via resource +// tags applied to the resource identified by instanceName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation RebootInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/RebootInstance +func (c *Lightsail) RebootInstance(input *RebootInstanceInput) (*RebootInstanceOutput, error) { + req, out := c.RebootInstanceRequest(input) + return out, req.Send() +} + +// RebootInstanceWithContext is the same as RebootInstance with the addition of +// the ability to pass a context and additional request options. +// +// See RebootInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) RebootInstanceWithContext(ctx aws.Context, input *RebootInstanceInput, opts ...request.Option) (*RebootInstanceOutput, error) { + req, out := c.RebootInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opRebootRelationalDatabase = "RebootRelationalDatabase" + +// RebootRelationalDatabaseRequest generates a "aws/request.Request" representing the +// client's request for the RebootRelationalDatabase operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See RebootRelationalDatabase for more information on using the RebootRelationalDatabase +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the RebootRelationalDatabaseRequest method. +// req, resp := client.RebootRelationalDatabaseRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/RebootRelationalDatabase +func (c *Lightsail) RebootRelationalDatabaseRequest(input *RebootRelationalDatabaseInput) (req *request.Request, output *RebootRelationalDatabaseOutput) { + op := &request.Operation{ + Name: opRebootRelationalDatabase, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &RebootRelationalDatabaseInput{} + } + + output = &RebootRelationalDatabaseOutput{} + req = c.newRequest(op, input, output) + return +} + +// RebootRelationalDatabase API operation for Amazon Lightsail. +// +// Restarts a specific database in Amazon Lightsail. +// +// The reboot relational database operation supports tag-based access control +// via resource tags applied to the resource identified by relationalDatabaseName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation RebootRelationalDatabase for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/RebootRelationalDatabase +func (c *Lightsail) RebootRelationalDatabase(input *RebootRelationalDatabaseInput) (*RebootRelationalDatabaseOutput, error) { + req, out := c.RebootRelationalDatabaseRequest(input) + return out, req.Send() +} + +// RebootRelationalDatabaseWithContext is the same as RebootRelationalDatabase with the addition of +// the ability to pass a context and additional request options. +// +// See RebootRelationalDatabase for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) RebootRelationalDatabaseWithContext(ctx aws.Context, input *RebootRelationalDatabaseInput, opts ...request.Option) (*RebootRelationalDatabaseOutput, error) { + req, out := c.RebootRelationalDatabaseRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opReleaseStaticIp = "ReleaseStaticIp" + +// ReleaseStaticIpRequest generates a "aws/request.Request" representing the +// client's request for the ReleaseStaticIp operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ReleaseStaticIp for more information on using the ReleaseStaticIp +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ReleaseStaticIpRequest method. +// req, resp := client.ReleaseStaticIpRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/ReleaseStaticIp +func (c *Lightsail) ReleaseStaticIpRequest(input *ReleaseStaticIpInput) (req *request.Request, output *ReleaseStaticIpOutput) { + op := &request.Operation{ + Name: opReleaseStaticIp, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &ReleaseStaticIpInput{} + } + + output = &ReleaseStaticIpOutput{} + req = c.newRequest(op, input, output) + return +} + +// ReleaseStaticIp API operation for Amazon Lightsail. +// +// Deletes a specific static IP from your account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation ReleaseStaticIp for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/ReleaseStaticIp +func (c *Lightsail) ReleaseStaticIp(input *ReleaseStaticIpInput) (*ReleaseStaticIpOutput, error) { + req, out := c.ReleaseStaticIpRequest(input) + return out, req.Send() +} + +// ReleaseStaticIpWithContext is the same as ReleaseStaticIp with the addition of +// the ability to pass a context and additional request options. +// +// See ReleaseStaticIp for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) ReleaseStaticIpWithContext(ctx aws.Context, input *ReleaseStaticIpInput, opts ...request.Option) (*ReleaseStaticIpOutput, error) { + req, out := c.ReleaseStaticIpRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opStartInstance = "StartInstance" + +// StartInstanceRequest generates a "aws/request.Request" representing the +// client's request for the StartInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StartInstance for more information on using the StartInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StartInstanceRequest method. +// req, resp := client.StartInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/StartInstance +func (c *Lightsail) StartInstanceRequest(input *StartInstanceInput) (req *request.Request, output *StartInstanceOutput) { + op := &request.Operation{ + Name: opStartInstance, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &StartInstanceInput{} + } + + output = &StartInstanceOutput{} + req = c.newRequest(op, input, output) + return +} + +// StartInstance API operation for Amazon Lightsail. +// +// Starts a specific Amazon Lightsail instance from a stopped state. To restart +// an instance, use the reboot instance operation. +// +// When you start a stopped instance, Lightsail assigns a new public IP address +// to the instance. To use the same IP address after stopping and starting an +// instance, create a static IP address and attach it to the instance. For more +// information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/lightsail-create-static-ip). +// +// The start instance operation supports tag-based access control via resource +// tags applied to the resource identified by instanceName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation StartInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/StartInstance +func (c *Lightsail) StartInstance(input *StartInstanceInput) (*StartInstanceOutput, error) { + req, out := c.StartInstanceRequest(input) + return out, req.Send() +} + +// StartInstanceWithContext is the same as StartInstance with the addition of +// the ability to pass a context and additional request options. +// +// See StartInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) StartInstanceWithContext(ctx aws.Context, input *StartInstanceInput, opts ...request.Option) (*StartInstanceOutput, error) { + req, out := c.StartInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opStartRelationalDatabase = "StartRelationalDatabase" + +// StartRelationalDatabaseRequest generates a "aws/request.Request" representing the +// client's request for the StartRelationalDatabase operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StartRelationalDatabase for more information on using the StartRelationalDatabase +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StartRelationalDatabaseRequest method. +// req, resp := client.StartRelationalDatabaseRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/StartRelationalDatabase +func (c *Lightsail) StartRelationalDatabaseRequest(input *StartRelationalDatabaseInput) (req *request.Request, output *StartRelationalDatabaseOutput) { + op := &request.Operation{ + Name: opStartRelationalDatabase, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &StartRelationalDatabaseInput{} + } + + output = &StartRelationalDatabaseOutput{} + req = c.newRequest(op, input, output) + return +} + +// StartRelationalDatabase API operation for Amazon Lightsail. +// +// Starts a specific database from a stopped state in Amazon Lightsail. To restart +// a database, use the reboot relational database operation. +// +// The start relational database operation supports tag-based access control +// via resource tags applied to the resource identified by relationalDatabaseName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation StartRelationalDatabase for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/StartRelationalDatabase +func (c *Lightsail) StartRelationalDatabase(input *StartRelationalDatabaseInput) (*StartRelationalDatabaseOutput, error) { + req, out := c.StartRelationalDatabaseRequest(input) + return out, req.Send() +} + +// StartRelationalDatabaseWithContext is the same as StartRelationalDatabase with the addition of +// the ability to pass a context and additional request options. +// +// See StartRelationalDatabase for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) StartRelationalDatabaseWithContext(ctx aws.Context, input *StartRelationalDatabaseInput, opts ...request.Option) (*StartRelationalDatabaseOutput, error) { + req, out := c.StartRelationalDatabaseRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opStopInstance = "StopInstance" + +// StopInstanceRequest generates a "aws/request.Request" representing the +// client's request for the StopInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StopInstance for more information on using the StopInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StopInstanceRequest method. +// req, resp := client.StopInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/StopInstance +func (c *Lightsail) StopInstanceRequest(input *StopInstanceInput) (req *request.Request, output *StopInstanceOutput) { + op := &request.Operation{ + Name: opStopInstance, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &StopInstanceInput{} + } + + output = &StopInstanceOutput{} + req = c.newRequest(op, input, output) + return +} + +// StopInstance API operation for Amazon Lightsail. +// +// Stops a specific Amazon Lightsail instance that is currently running. +// +// When you start a stopped instance, Lightsail assigns a new public IP address +// to the instance. To use the same IP address after stopping and starting an +// instance, create a static IP address and attach it to the instance. For more +// information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/lightsail-create-static-ip). +// +// The stop instance operation supports tag-based access control via resource +// tags applied to the resource identified by instanceName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation StopInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/StopInstance +func (c *Lightsail) StopInstance(input *StopInstanceInput) (*StopInstanceOutput, error) { + req, out := c.StopInstanceRequest(input) + return out, req.Send() +} + +// StopInstanceWithContext is the same as StopInstance with the addition of +// the ability to pass a context and additional request options. +// +// See StopInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) StopInstanceWithContext(ctx aws.Context, input *StopInstanceInput, opts ...request.Option) (*StopInstanceOutput, error) { + req, out := c.StopInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opStopRelationalDatabase = "StopRelationalDatabase" + +// StopRelationalDatabaseRequest generates a "aws/request.Request" representing the +// client's request for the StopRelationalDatabase operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See StopRelationalDatabase for more information on using the StopRelationalDatabase +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the StopRelationalDatabaseRequest method. +// req, resp := client.StopRelationalDatabaseRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/StopRelationalDatabase +func (c *Lightsail) StopRelationalDatabaseRequest(input *StopRelationalDatabaseInput) (req *request.Request, output *StopRelationalDatabaseOutput) { + op := &request.Operation{ + Name: opStopRelationalDatabase, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &StopRelationalDatabaseInput{} + } + + output = &StopRelationalDatabaseOutput{} + req = c.newRequest(op, input, output) + return +} + +// StopRelationalDatabase API operation for Amazon Lightsail. +// +// Stops a specific database that is currently running in Amazon Lightsail. +// +// The stop relational database operation supports tag-based access control +// via resource tags applied to the resource identified by relationalDatabaseName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation StopRelationalDatabase for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/StopRelationalDatabase +func (c *Lightsail) StopRelationalDatabase(input *StopRelationalDatabaseInput) (*StopRelationalDatabaseOutput, error) { + req, out := c.StopRelationalDatabaseRequest(input) + return out, req.Send() +} + +// StopRelationalDatabaseWithContext is the same as StopRelationalDatabase with the addition of +// the ability to pass a context and additional request options. +// +// See StopRelationalDatabase for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) StopRelationalDatabaseWithContext(ctx aws.Context, input *StopRelationalDatabaseInput, opts ...request.Option) (*StopRelationalDatabaseOutput, error) { + req, out := c.StopRelationalDatabaseRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opTagResource = "TagResource" + +// TagResourceRequest generates a "aws/request.Request" representing the +// client's request for the TagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See TagResource for more information on using the TagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the TagResourceRequest method. +// req, resp := client.TagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/TagResource +func (c *Lightsail) TagResourceRequest(input *TagResourceInput) (req *request.Request, output *TagResourceOutput) { + op := &request.Operation{ + Name: opTagResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &TagResourceInput{} + } + + output = &TagResourceOutput{} + req = c.newRequest(op, input, output) + return +} + +// TagResource API operation for Amazon Lightsail. +// +// Adds one or more tags to the specified Amazon Lightsail resource. Each resource +// can have a maximum of 50 tags. Each tag consists of a key and an optional +// value. Tag keys must be unique per resource. For more information about tags, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). +// +// The tag resource operation supports tag-based access control via request +// tags and resource tags applied to the resource identified by resourceName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation TagResource for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/TagResource +func (c *Lightsail) TagResource(input *TagResourceInput) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + return out, req.Send() +} + +// TagResourceWithContext is the same as TagResource with the addition of +// the ability to pass a context and additional request options. +// +// See TagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) TagResourceWithContext(ctx aws.Context, input *TagResourceInput, opts ...request.Option) (*TagResourceOutput, error) { + req, out := c.TagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUnpeerVpc = "UnpeerVpc" + +// UnpeerVpcRequest generates a "aws/request.Request" representing the +// client's request for the UnpeerVpc operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UnpeerVpc for more information on using the UnpeerVpc +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UnpeerVpcRequest method. +// req, resp := client.UnpeerVpcRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UnpeerVpc +func (c *Lightsail) UnpeerVpcRequest(input *UnpeerVpcInput) (req *request.Request, output *UnpeerVpcOutput) { + op := &request.Operation{ + Name: opUnpeerVpc, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UnpeerVpcInput{} + } + + output = &UnpeerVpcOutput{} + req = c.newRequest(op, input, output) + return +} + +// UnpeerVpc API operation for Amazon Lightsail. +// +// Attempts to unpeer the Lightsail VPC from the user's default VPC. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation UnpeerVpc for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UnpeerVpc +func (c *Lightsail) UnpeerVpc(input *UnpeerVpcInput) (*UnpeerVpcOutput, error) { + req, out := c.UnpeerVpcRequest(input) + return out, req.Send() +} + +// UnpeerVpcWithContext is the same as UnpeerVpc with the addition of +// the ability to pass a context and additional request options. +// +// See UnpeerVpc for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) UnpeerVpcWithContext(ctx aws.Context, input *UnpeerVpcInput, opts ...request.Option) (*UnpeerVpcOutput, error) { + req, out := c.UnpeerVpcRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUntagResource = "UntagResource" + +// UntagResourceRequest generates a "aws/request.Request" representing the +// client's request for the UntagResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UntagResource for more information on using the UntagResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UntagResourceRequest method. +// req, resp := client.UntagResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UntagResource +func (c *Lightsail) UntagResourceRequest(input *UntagResourceInput) (req *request.Request, output *UntagResourceOutput) { + op := &request.Operation{ + Name: opUntagResource, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UntagResourceInput{} + } + + output = &UntagResourceOutput{} + req = c.newRequest(op, input, output) + return +} + +// UntagResource API operation for Amazon Lightsail. +// +// Deletes the specified set of tag keys and their values from the specified +// Amazon Lightsail resource. +// +// The untag resource operation supports tag-based access control via request +// tags and resource tags applied to the resource identified by resourceName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation UntagResource for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UntagResource +func (c *Lightsail) UntagResource(input *UntagResourceInput) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + return out, req.Send() +} + +// UntagResourceWithContext is the same as UntagResource with the addition of +// the ability to pass a context and additional request options. +// +// See UntagResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) UntagResourceWithContext(ctx aws.Context, input *UntagResourceInput, opts ...request.Option) (*UntagResourceOutput, error) { + req, out := c.UntagResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateDomainEntry = "UpdateDomainEntry" + +// UpdateDomainEntryRequest generates a "aws/request.Request" representing the +// client's request for the UpdateDomainEntry operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateDomainEntry for more information on using the UpdateDomainEntry +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateDomainEntryRequest method. +// req, resp := client.UpdateDomainEntryRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UpdateDomainEntry +func (c *Lightsail) UpdateDomainEntryRequest(input *UpdateDomainEntryInput) (req *request.Request, output *UpdateDomainEntryOutput) { + op := &request.Operation{ + Name: opUpdateDomainEntry, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateDomainEntryInput{} + } + + output = &UpdateDomainEntryOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateDomainEntry API operation for Amazon Lightsail. +// +// Updates a domain recordset after it is created. +// +// The update domain entry operation supports tag-based access control via resource +// tags applied to the resource identified by domainName. For more information, +// see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation UpdateDomainEntry for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UpdateDomainEntry +func (c *Lightsail) UpdateDomainEntry(input *UpdateDomainEntryInput) (*UpdateDomainEntryOutput, error) { + req, out := c.UpdateDomainEntryRequest(input) + return out, req.Send() +} + +// UpdateDomainEntryWithContext is the same as UpdateDomainEntry with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateDomainEntry for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) UpdateDomainEntryWithContext(ctx aws.Context, input *UpdateDomainEntryInput, opts ...request.Option) (*UpdateDomainEntryOutput, error) { + req, out := c.UpdateDomainEntryRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateLoadBalancerAttribute = "UpdateLoadBalancerAttribute" + +// UpdateLoadBalancerAttributeRequest generates a "aws/request.Request" representing the +// client's request for the UpdateLoadBalancerAttribute operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateLoadBalancerAttribute for more information on using the UpdateLoadBalancerAttribute +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateLoadBalancerAttributeRequest method. +// req, resp := client.UpdateLoadBalancerAttributeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UpdateLoadBalancerAttribute +func (c *Lightsail) UpdateLoadBalancerAttributeRequest(input *UpdateLoadBalancerAttributeInput) (req *request.Request, output *UpdateLoadBalancerAttributeOutput) { + op := &request.Operation{ + Name: opUpdateLoadBalancerAttribute, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateLoadBalancerAttributeInput{} + } + + output = &UpdateLoadBalancerAttributeOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateLoadBalancerAttribute API operation for Amazon Lightsail. +// +// Updates the specified attribute for a load balancer. You can only update +// one attribute at a time. +// +// The update load balancer attribute operation supports tag-based access control +// via resource tags applied to the resource identified by loadBalancerName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation UpdateLoadBalancerAttribute for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UpdateLoadBalancerAttribute +func (c *Lightsail) UpdateLoadBalancerAttribute(input *UpdateLoadBalancerAttributeInput) (*UpdateLoadBalancerAttributeOutput, error) { + req, out := c.UpdateLoadBalancerAttributeRequest(input) + return out, req.Send() +} + +// UpdateLoadBalancerAttributeWithContext is the same as UpdateLoadBalancerAttribute with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateLoadBalancerAttribute for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) UpdateLoadBalancerAttributeWithContext(ctx aws.Context, input *UpdateLoadBalancerAttributeInput, opts ...request.Option) (*UpdateLoadBalancerAttributeOutput, error) { + req, out := c.UpdateLoadBalancerAttributeRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateRelationalDatabase = "UpdateRelationalDatabase" + +// UpdateRelationalDatabaseRequest generates a "aws/request.Request" representing the +// client's request for the UpdateRelationalDatabase operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateRelationalDatabase for more information on using the UpdateRelationalDatabase +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateRelationalDatabaseRequest method. +// req, resp := client.UpdateRelationalDatabaseRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UpdateRelationalDatabase +func (c *Lightsail) UpdateRelationalDatabaseRequest(input *UpdateRelationalDatabaseInput) (req *request.Request, output *UpdateRelationalDatabaseOutput) { + op := &request.Operation{ + Name: opUpdateRelationalDatabase, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateRelationalDatabaseInput{} + } + + output = &UpdateRelationalDatabaseOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateRelationalDatabase API operation for Amazon Lightsail. +// +// Allows the update of one or more attributes of a database in Amazon Lightsail. +// +// Updates are applied immediately, or in cases where the updates could result +// in an outage, are applied during the database's predefined maintenance window. +// +// The update relational database operation supports tag-based access control +// via resource tags applied to the resource identified by relationalDatabaseName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation UpdateRelationalDatabase for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UpdateRelationalDatabase +func (c *Lightsail) UpdateRelationalDatabase(input *UpdateRelationalDatabaseInput) (*UpdateRelationalDatabaseOutput, error) { + req, out := c.UpdateRelationalDatabaseRequest(input) + return out, req.Send() +} + +// UpdateRelationalDatabaseWithContext is the same as UpdateRelationalDatabase with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateRelationalDatabase for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) UpdateRelationalDatabaseWithContext(ctx aws.Context, input *UpdateRelationalDatabaseInput, opts ...request.Option) (*UpdateRelationalDatabaseOutput, error) { + req, out := c.UpdateRelationalDatabaseRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateRelationalDatabaseParameters = "UpdateRelationalDatabaseParameters" + +// UpdateRelationalDatabaseParametersRequest generates a "aws/request.Request" representing the +// client's request for the UpdateRelationalDatabaseParameters operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateRelationalDatabaseParameters for more information on using the UpdateRelationalDatabaseParameters +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateRelationalDatabaseParametersRequest method. +// req, resp := client.UpdateRelationalDatabaseParametersRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UpdateRelationalDatabaseParameters +func (c *Lightsail) UpdateRelationalDatabaseParametersRequest(input *UpdateRelationalDatabaseParametersInput) (req *request.Request, output *UpdateRelationalDatabaseParametersOutput) { + op := &request.Operation{ + Name: opUpdateRelationalDatabaseParameters, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &UpdateRelationalDatabaseParametersInput{} + } + + output = &UpdateRelationalDatabaseParametersOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateRelationalDatabaseParameters API operation for Amazon Lightsail. +// +// Allows the update of one or more parameters of a database in Amazon Lightsail. +// +// Parameter updates don't cause outages; therefore, their application is not +// subject to the preferred maintenance window. However, there are two ways +// in which paramater updates are applied: dynamic or pending-reboot. Parameters +// marked with a dynamic apply type are applied immediately. Parameters marked +// with a pending-reboot apply type are applied only after the database is rebooted +// using the reboot relational database operation. +// +// The update relational database parameters operation supports tag-based access +// control via resource tags applied to the resource identified by relationalDatabaseName. +// For more information, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-controlling-access-using-tags). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Lightsail's +// API operation UpdateRelationalDatabaseParameters for usage and error information. +// +// Returned Error Codes: +// * ErrCodeServiceException "ServiceException" +// A general service exception. +// +// * ErrCodeInvalidInputException "InvalidInputException" +// Lightsail throws this exception when user input does not conform to the validation +// rules of an input field. +// +// Domain-related APIs are only available in the N. Virginia (us-east-1) Region. +// Please set your AWS Region configuration to us-east-1 to create, view, or +// edit these resources. +// +// * ErrCodeNotFoundException "NotFoundException" +// Lightsail throws this exception when it cannot find a resource. +// +// * ErrCodeOperationFailureException "OperationFailureException" +// Lightsail throws this exception when an operation fails to execute. +// +// * ErrCodeAccessDeniedException "AccessDeniedException" +// Lightsail throws this exception when the user cannot be authenticated or +// uses invalid credentials to access a resource. +// +// * ErrCodeAccountSetupInProgressException "AccountSetupInProgressException" +// Lightsail throws this exception when an account is still in the setup in +// progress state. +// +// * ErrCodeUnauthenticatedException "UnauthenticatedException" +// Lightsail throws this exception when the user has not been authenticated. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28/UpdateRelationalDatabaseParameters +func (c *Lightsail) UpdateRelationalDatabaseParameters(input *UpdateRelationalDatabaseParametersInput) (*UpdateRelationalDatabaseParametersOutput, error) { + req, out := c.UpdateRelationalDatabaseParametersRequest(input) + return out, req.Send() +} + +// UpdateRelationalDatabaseParametersWithContext is the same as UpdateRelationalDatabaseParameters with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateRelationalDatabaseParameters for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Lightsail) UpdateRelationalDatabaseParametersWithContext(ctx aws.Context, input *UpdateRelationalDatabaseParametersInput, opts ...request.Option) (*UpdateRelationalDatabaseParametersOutput, error) { + req, out := c.UpdateRelationalDatabaseParametersRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +type AllocateStaticIpInput struct { + _ struct{} `type:"structure"` + + // The name of the static IP address. + // + // StaticIpName is a required field + StaticIpName *string `locationName:"staticIpName" type:"string" required:"true"` +} + +// String returns the string representation +func (s AllocateStaticIpInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllocateStaticIpInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AllocateStaticIpInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AllocateStaticIpInput"} + if s.StaticIpName == nil { + invalidParams.Add(request.NewErrParamRequired("StaticIpName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetStaticIpName sets the StaticIpName field's value. +func (s *AllocateStaticIpInput) SetStaticIpName(v string) *AllocateStaticIpInput { + s.StaticIpName = &v + return s +} + +type AllocateStaticIpOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the static IP address + // you allocated. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s AllocateStaticIpOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AllocateStaticIpOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *AllocateStaticIpOutput) SetOperations(v []*Operation) *AllocateStaticIpOutput { + s.Operations = v + return s +} + +type AttachDiskInput struct { + _ struct{} `type:"structure"` + + // The unique Lightsail disk name (e.g., my-disk). + // + // DiskName is a required field + DiskName *string `locationName:"diskName" type:"string" required:"true"` + + // The disk path to expose to the instance (e.g., /dev/xvdf). + // + // DiskPath is a required field + DiskPath *string `locationName:"diskPath" type:"string" required:"true"` + + // The name of the Lightsail instance where you want to utilize the storage + // disk. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachDiskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachDiskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachDiskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachDiskInput"} + if s.DiskName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskName")) + } + if s.DiskPath == nil { + invalidParams.Add(request.NewErrParamRequired("DiskPath")) + } + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDiskName sets the DiskName field's value. +func (s *AttachDiskInput) SetDiskName(v string) *AttachDiskInput { + s.DiskName = &v + return s +} + +// SetDiskPath sets the DiskPath field's value. +func (s *AttachDiskInput) SetDiskPath(v string) *AttachDiskInput { + s.DiskPath = &v + return s +} + +// SetInstanceName sets the InstanceName field's value. +func (s *AttachDiskInput) SetInstanceName(v string) *AttachDiskInput { + s.InstanceName = &v + return s +} + +type AttachDiskOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s AttachDiskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachDiskOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *AttachDiskOutput) SetOperations(v []*Operation) *AttachDiskOutput { + s.Operations = v + return s +} + +type AttachInstancesToLoadBalancerInput struct { + _ struct{} `type:"structure"` + + // An array of strings representing the instance name(s) you want to attach + // to your load balancer. + // + // An instance must be running before you can attach it to your load balancer. + // + // There are no additional limits on the number of instances you can attach + // to your load balancer, aside from the limit of Lightsail instances you can + // create in your account (20). + // + // InstanceNames is a required field + InstanceNames []*string `locationName:"instanceNames" type:"list" required:"true"` + + // The name of the load balancer. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachInstancesToLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachInstancesToLoadBalancerInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachInstancesToLoadBalancerInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachInstancesToLoadBalancerInput"} + if s.InstanceNames == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceNames")) + } + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceNames sets the InstanceNames field's value. +func (s *AttachInstancesToLoadBalancerInput) SetInstanceNames(v []*string) *AttachInstancesToLoadBalancerInput { + s.InstanceNames = v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *AttachInstancesToLoadBalancerInput) SetLoadBalancerName(v string) *AttachInstancesToLoadBalancerInput { + s.LoadBalancerName = &v + return s +} + +type AttachInstancesToLoadBalancerOutput struct { + _ struct{} `type:"structure"` + + // An object representing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s AttachInstancesToLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachInstancesToLoadBalancerOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *AttachInstancesToLoadBalancerOutput) SetOperations(v []*Operation) *AttachInstancesToLoadBalancerOutput { + s.Operations = v + return s +} + +type AttachLoadBalancerTlsCertificateInput struct { + _ struct{} `type:"structure"` + + // The name of your SSL/TLS certificate. + // + // CertificateName is a required field + CertificateName *string `locationName:"certificateName" type:"string" required:"true"` + + // The name of the load balancer to which you want to associate the SSL/TLS + // certificate. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachLoadBalancerTlsCertificateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachLoadBalancerTlsCertificateInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachLoadBalancerTlsCertificateInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachLoadBalancerTlsCertificateInput"} + if s.CertificateName == nil { + invalidParams.Add(request.NewErrParamRequired("CertificateName")) + } + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCertificateName sets the CertificateName field's value. +func (s *AttachLoadBalancerTlsCertificateInput) SetCertificateName(v string) *AttachLoadBalancerTlsCertificateInput { + s.CertificateName = &v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *AttachLoadBalancerTlsCertificateInput) SetLoadBalancerName(v string) *AttachLoadBalancerTlsCertificateInput { + s.LoadBalancerName = &v + return s +} + +type AttachLoadBalancerTlsCertificateOutput struct { + _ struct{} `type:"structure"` + + // An object representing the API operations. + // + // These SSL/TLS certificates are only usable by Lightsail load balancers. You + // can't get the certificate and use it for another purpose. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s AttachLoadBalancerTlsCertificateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachLoadBalancerTlsCertificateOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *AttachLoadBalancerTlsCertificateOutput) SetOperations(v []*Operation) *AttachLoadBalancerTlsCertificateOutput { + s.Operations = v + return s +} + +type AttachStaticIpInput struct { + _ struct{} `type:"structure"` + + // The instance name to which you want to attach the static IP address. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` + + // The name of the static IP. + // + // StaticIpName is a required field + StaticIpName *string `locationName:"staticIpName" type:"string" required:"true"` +} + +// String returns the string representation +func (s AttachStaticIpInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachStaticIpInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AttachStaticIpInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AttachStaticIpInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + if s.StaticIpName == nil { + invalidParams.Add(request.NewErrParamRequired("StaticIpName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *AttachStaticIpInput) SetInstanceName(v string) *AttachStaticIpInput { + s.InstanceName = &v + return s +} + +// SetStaticIpName sets the StaticIpName field's value. +func (s *AttachStaticIpInput) SetStaticIpName(v string) *AttachStaticIpInput { + s.StaticIpName = &v + return s +} + +type AttachStaticIpOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about your API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s AttachStaticIpOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AttachStaticIpOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *AttachStaticIpOutput) SetOperations(v []*Operation) *AttachStaticIpOutput { + s.Operations = v + return s +} + +// Describes an Availability Zone. +type AvailabilityZone struct { + _ struct{} `type:"structure"` + + // The state of the Availability Zone. + State *string `locationName:"state" type:"string"` + + // The name of the Availability Zone. The format is us-east-2a (case-sensitive). + ZoneName *string `locationName:"zoneName" type:"string"` +} + +// String returns the string representation +func (s AvailabilityZone) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AvailabilityZone) GoString() string { + return s.String() +} + +// SetState sets the State field's value. +func (s *AvailabilityZone) SetState(v string) *AvailabilityZone { + s.State = &v + return s +} + +// SetZoneName sets the ZoneName field's value. +func (s *AvailabilityZone) SetZoneName(v string) *AvailabilityZone { + s.ZoneName = &v + return s +} + +// Describes a blueprint (a virtual private server image). +type Blueprint struct { + _ struct{} `type:"structure"` + + // The ID for the virtual private server image (e.g., app_wordpress_4_4 or app_lamp_7_0). + BlueprintId *string `locationName:"blueprintId" type:"string"` + + // The description of the blueprint. + Description *string `locationName:"description" type:"string"` + + // The group name of the blueprint (e.g., amazon-linux). + Group *string `locationName:"group" type:"string"` + + // A Boolean value indicating whether the blueprint is active. Inactive blueprints + // are listed to support customers with existing instances but are not necessarily + // available for launch of new instances. Blueprints are marked inactive when + // they become outdated due to operating system updates or new application releases. + IsActive *bool `locationName:"isActive" type:"boolean"` + + // The end-user license agreement URL for the image or blueprint. + LicenseUrl *string `locationName:"licenseUrl" type:"string"` + + // The minimum bundle power required to run this blueprint. For example, you + // need a bundle with a power value of 500 or more to create an instance that + // uses a blueprint with a minimum power value of 500. 0 indicates that the + // blueprint runs on all instance sizes. + MinPower *int64 `locationName:"minPower" type:"integer"` + + // The friendly name of the blueprint (e.g., Amazon Linux). + Name *string `locationName:"name" type:"string"` + + // The operating system platform (either Linux/Unix-based or Windows Server-based) + // of the blueprint. + Platform *string `locationName:"platform" type:"string" enum:"InstancePlatform"` + + // The product URL to learn more about the image or blueprint. + ProductUrl *string `locationName:"productUrl" type:"string"` + + // The type of the blueprint (e.g., os or app). + Type *string `locationName:"type" type:"string" enum:"BlueprintType"` + + // The version number of the operating system, application, or stack (e.g., + // 2016.03.0). + Version *string `locationName:"version" type:"string"` + + // The version code. + VersionCode *string `locationName:"versionCode" type:"string"` +} + +// String returns the string representation +func (s Blueprint) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Blueprint) GoString() string { + return s.String() +} + +// SetBlueprintId sets the BlueprintId field's value. +func (s *Blueprint) SetBlueprintId(v string) *Blueprint { + s.BlueprintId = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *Blueprint) SetDescription(v string) *Blueprint { + s.Description = &v + return s +} + +// SetGroup sets the Group field's value. +func (s *Blueprint) SetGroup(v string) *Blueprint { + s.Group = &v + return s +} + +// SetIsActive sets the IsActive field's value. +func (s *Blueprint) SetIsActive(v bool) *Blueprint { + s.IsActive = &v + return s +} + +// SetLicenseUrl sets the LicenseUrl field's value. +func (s *Blueprint) SetLicenseUrl(v string) *Blueprint { + s.LicenseUrl = &v + return s +} + +// SetMinPower sets the MinPower field's value. +func (s *Blueprint) SetMinPower(v int64) *Blueprint { + s.MinPower = &v + return s +} + +// SetName sets the Name field's value. +func (s *Blueprint) SetName(v string) *Blueprint { + s.Name = &v + return s +} + +// SetPlatform sets the Platform field's value. +func (s *Blueprint) SetPlatform(v string) *Blueprint { + s.Platform = &v + return s +} + +// SetProductUrl sets the ProductUrl field's value. +func (s *Blueprint) SetProductUrl(v string) *Blueprint { + s.ProductUrl = &v + return s +} + +// SetType sets the Type field's value. +func (s *Blueprint) SetType(v string) *Blueprint { + s.Type = &v + return s +} + +// SetVersion sets the Version field's value. +func (s *Blueprint) SetVersion(v string) *Blueprint { + s.Version = &v + return s +} + +// SetVersionCode sets the VersionCode field's value. +func (s *Blueprint) SetVersionCode(v string) *Blueprint { + s.VersionCode = &v + return s +} + +// Describes a bundle, which is a set of specs describing your virtual private +// server (or instance). +type Bundle struct { + _ struct{} `type:"structure"` + + // The bundle ID (e.g., micro_1_0). + BundleId *string `locationName:"bundleId" type:"string"` + + // The number of vCPUs included in the bundle (e.g., 2). + CpuCount *int64 `locationName:"cpuCount" type:"integer"` + + // The size of the SSD (e.g., 30). + DiskSizeInGb *int64 `locationName:"diskSizeInGb" type:"integer"` + + // The Amazon EC2 instance type (e.g., t2.micro). + InstanceType *string `locationName:"instanceType" type:"string"` + + // A Boolean value indicating whether the bundle is active. + IsActive *bool `locationName:"isActive" type:"boolean"` + + // A friendly name for the bundle (e.g., Micro). + Name *string `locationName:"name" type:"string"` + + // A numeric value that represents the power of the bundle (e.g., 500). You + // can use the bundle's power value in conjunction with a blueprint's minimum + // power value to determine whether the blueprint will run on the bundle. For + // example, you need a bundle with a power value of 500 or more to create an + // instance that uses a blueprint with a minimum power value of 500. + Power *int64 `locationName:"power" type:"integer"` + + // The price in US dollars (e.g., 5.0). + Price *float64 `locationName:"price" type:"float"` + + // The amount of RAM in GB (e.g., 2.0). + RamSizeInGb *float64 `locationName:"ramSizeInGb" type:"float"` + + // The operating system platform (Linux/Unix-based or Windows Server-based) + // that the bundle supports. You can only launch a WINDOWS bundle on a blueprint + // that supports the WINDOWS platform. LINUX_UNIX blueprints require a LINUX_UNIX + // bundle. + SupportedPlatforms []*string `locationName:"supportedPlatforms" type:"list"` + + // The data transfer rate per month in GB (e.g., 2000). + TransferPerMonthInGb *int64 `locationName:"transferPerMonthInGb" type:"integer"` +} + +// String returns the string representation +func (s Bundle) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Bundle) GoString() string { + return s.String() +} + +// SetBundleId sets the BundleId field's value. +func (s *Bundle) SetBundleId(v string) *Bundle { + s.BundleId = &v + return s +} + +// SetCpuCount sets the CpuCount field's value. +func (s *Bundle) SetCpuCount(v int64) *Bundle { + s.CpuCount = &v + return s +} + +// SetDiskSizeInGb sets the DiskSizeInGb field's value. +func (s *Bundle) SetDiskSizeInGb(v int64) *Bundle { + s.DiskSizeInGb = &v + return s +} + +// SetInstanceType sets the InstanceType field's value. +func (s *Bundle) SetInstanceType(v string) *Bundle { + s.InstanceType = &v + return s +} + +// SetIsActive sets the IsActive field's value. +func (s *Bundle) SetIsActive(v bool) *Bundle { + s.IsActive = &v + return s +} + +// SetName sets the Name field's value. +func (s *Bundle) SetName(v string) *Bundle { + s.Name = &v + return s +} + +// SetPower sets the Power field's value. +func (s *Bundle) SetPower(v int64) *Bundle { + s.Power = &v + return s +} + +// SetPrice sets the Price field's value. +func (s *Bundle) SetPrice(v float64) *Bundle { + s.Price = &v + return s +} + +// SetRamSizeInGb sets the RamSizeInGb field's value. +func (s *Bundle) SetRamSizeInGb(v float64) *Bundle { + s.RamSizeInGb = &v + return s +} + +// SetSupportedPlatforms sets the SupportedPlatforms field's value. +func (s *Bundle) SetSupportedPlatforms(v []*string) *Bundle { + s.SupportedPlatforms = v + return s +} + +// SetTransferPerMonthInGb sets the TransferPerMonthInGb field's value. +func (s *Bundle) SetTransferPerMonthInGb(v int64) *Bundle { + s.TransferPerMonthInGb = &v + return s +} + +type CloseInstancePublicPortsInput struct { + _ struct{} `type:"structure"` + + // The name of the instance on which you're attempting to close the public ports. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` + + // Information about the public port you are trying to close. + // + // PortInfo is a required field + PortInfo *PortInfo `locationName:"portInfo" type:"structure" required:"true"` +} + +// String returns the string representation +func (s CloseInstancePublicPortsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CloseInstancePublicPortsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CloseInstancePublicPortsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CloseInstancePublicPortsInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + if s.PortInfo == nil { + invalidParams.Add(request.NewErrParamRequired("PortInfo")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *CloseInstancePublicPortsInput) SetInstanceName(v string) *CloseInstancePublicPortsInput { + s.InstanceName = &v + return s +} + +// SetPortInfo sets the PortInfo field's value. +func (s *CloseInstancePublicPortsInput) SetPortInfo(v *PortInfo) *CloseInstancePublicPortsInput { + s.PortInfo = v + return s +} + +type CloseInstancePublicPortsOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs that contains information about the operation. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s CloseInstancePublicPortsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CloseInstancePublicPortsOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *CloseInstancePublicPortsOutput) SetOperation(v *Operation) *CloseInstancePublicPortsOutput { + s.Operation = v + return s +} + +// Describes a CloudFormation stack record created as a result of the create +// cloud formation stack operation. +// +// A CloudFormation stack record provides information about the AWS CloudFormation +// stack used to create a new Amazon Elastic Compute Cloud instance from an +// exported Lightsail instance snapshot. +type CloudFormationStackRecord struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the CloudFormation stack record. + Arn *string `locationName:"arn" type:"string"` + + // The date when the CloudFormation stack record was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // A list of objects describing the destination service, which is AWS CloudFormation, + // and the Amazon Resource Name (ARN) of the AWS CloudFormation stack. + DestinationInfo *DestinationInfo `locationName:"destinationInfo" type:"structure"` + + // A list of objects describing the Availability Zone and AWS Region of the + // CloudFormation stack record. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the CloudFormation stack record. It starts with CloudFormationStackRecord + // followed by a GUID. + Name *string `locationName:"name" type:"string"` + + // The Lightsail resource type (e.g., CloudFormationStackRecord). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // A list of objects describing the source of the CloudFormation stack record. + SourceInfo []*CloudFormationStackRecordSourceInfo `locationName:"sourceInfo" type:"list"` + + // The current state of the CloudFormation stack record. + State *string `locationName:"state" type:"string" enum:"RecordState"` +} + +// String returns the string representation +func (s CloudFormationStackRecord) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CloudFormationStackRecord) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *CloudFormationStackRecord) SetArn(v string) *CloudFormationStackRecord { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *CloudFormationStackRecord) SetCreatedAt(v time.Time) *CloudFormationStackRecord { + s.CreatedAt = &v + return s +} + +// SetDestinationInfo sets the DestinationInfo field's value. +func (s *CloudFormationStackRecord) SetDestinationInfo(v *DestinationInfo) *CloudFormationStackRecord { + s.DestinationInfo = v + return s +} + +// SetLocation sets the Location field's value. +func (s *CloudFormationStackRecord) SetLocation(v *ResourceLocation) *CloudFormationStackRecord { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *CloudFormationStackRecord) SetName(v string) *CloudFormationStackRecord { + s.Name = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *CloudFormationStackRecord) SetResourceType(v string) *CloudFormationStackRecord { + s.ResourceType = &v + return s +} + +// SetSourceInfo sets the SourceInfo field's value. +func (s *CloudFormationStackRecord) SetSourceInfo(v []*CloudFormationStackRecordSourceInfo) *CloudFormationStackRecord { + s.SourceInfo = v + return s +} + +// SetState sets the State field's value. +func (s *CloudFormationStackRecord) SetState(v string) *CloudFormationStackRecord { + s.State = &v + return s +} + +// Describes the source of a CloudFormation stack record (i.e., the export snapshot +// record). +type CloudFormationStackRecordSourceInfo struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the export snapshot record. + Arn *string `locationName:"arn" type:"string"` + + // The name of the record. + Name *string `locationName:"name" type:"string"` + + // The Lightsail resource type (e.g., ExportSnapshotRecord). + ResourceType *string `locationName:"resourceType" type:"string" enum:"CloudFormationStackRecordSourceType"` +} + +// String returns the string representation +func (s CloudFormationStackRecordSourceInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CloudFormationStackRecordSourceInfo) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *CloudFormationStackRecordSourceInfo) SetArn(v string) *CloudFormationStackRecordSourceInfo { + s.Arn = &v + return s +} + +// SetName sets the Name field's value. +func (s *CloudFormationStackRecordSourceInfo) SetName(v string) *CloudFormationStackRecordSourceInfo { + s.Name = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *CloudFormationStackRecordSourceInfo) SetResourceType(v string) *CloudFormationStackRecordSourceInfo { + s.ResourceType = &v + return s +} + +type CopySnapshotInput struct { + _ struct{} `type:"structure"` + + // The AWS Region where the source snapshot is located. + // + // SourceRegion is a required field + SourceRegion *string `locationName:"sourceRegion" type:"string" required:"true" enum:"RegionName"` + + // The name of the source instance or disk snapshot to be copied. + // + // SourceSnapshotName is a required field + SourceSnapshotName *string `locationName:"sourceSnapshotName" type:"string" required:"true"` + + // The name of the new instance or disk snapshot to be created as a copy. + // + // TargetSnapshotName is a required field + TargetSnapshotName *string `locationName:"targetSnapshotName" type:"string" required:"true"` +} + +// String returns the string representation +func (s CopySnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopySnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CopySnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CopySnapshotInput"} + if s.SourceRegion == nil { + invalidParams.Add(request.NewErrParamRequired("SourceRegion")) + } + if s.SourceSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("SourceSnapshotName")) + } + if s.TargetSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("TargetSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetSourceRegion sets the SourceRegion field's value. +func (s *CopySnapshotInput) SetSourceRegion(v string) *CopySnapshotInput { + s.SourceRegion = &v + return s +} + +// SetSourceSnapshotName sets the SourceSnapshotName field's value. +func (s *CopySnapshotInput) SetSourceSnapshotName(v string) *CopySnapshotInput { + s.SourceSnapshotName = &v + return s +} + +// SetTargetSnapshotName sets the TargetSnapshotName field's value. +func (s *CopySnapshotInput) SetTargetSnapshotName(v string) *CopySnapshotInput { + s.TargetSnapshotName = &v + return s +} + +type CopySnapshotOutput struct { + _ struct{} `type:"structure"` + + // A list of objects describing the API operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CopySnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CopySnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CopySnapshotOutput) SetOperations(v []*Operation) *CopySnapshotOutput { + s.Operations = v + return s +} + +type CreateCloudFormationStackInput struct { + _ struct{} `type:"structure"` + + // An array of parameters that will be used to create the new Amazon EC2 instance. + // You can only pass one instance entry at a time in this array. You will get + // an invalid parameter error if you pass more than one instance entry in this + // array. + // + // Instances is a required field + Instances []*InstanceEntry `locationName:"instances" type:"list" required:"true"` +} + +// String returns the string representation +func (s CreateCloudFormationStackInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateCloudFormationStackInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateCloudFormationStackInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateCloudFormationStackInput"} + if s.Instances == nil { + invalidParams.Add(request.NewErrParamRequired("Instances")) + } + if s.Instances != nil { + for i, v := range s.Instances { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Instances", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstances sets the Instances field's value. +func (s *CreateCloudFormationStackInput) SetInstances(v []*InstanceEntry) *CreateCloudFormationStackInput { + s.Instances = v + return s +} + +type CreateCloudFormationStackOutput struct { + _ struct{} `type:"structure"` + + // A list of objects describing the API operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateCloudFormationStackOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateCloudFormationStackOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateCloudFormationStackOutput) SetOperations(v []*Operation) *CreateCloudFormationStackOutput { + s.Operations = v + return s +} + +type CreateDiskFromSnapshotInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone where you want to create the disk (e.g., us-east-2a). + // Choose the same Availability Zone as the Lightsail instance where you want + // to create the disk. + // + // Use the GetRegions operation to list the Availability Zones where Lightsail + // is currently available. + // + // AvailabilityZone is a required field + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // The unique Lightsail disk name (e.g., my-disk). + // + // DiskName is a required field + DiskName *string `locationName:"diskName" type:"string" required:"true"` + + // The name of the disk snapshot (e.g., my-snapshot) from which to create the + // new storage disk. + // + // DiskSnapshotName is a required field + DiskSnapshotName *string `locationName:"diskSnapshotName" type:"string" required:"true"` + + // The size of the disk in GB (e.g., 32). + // + // SizeInGb is a required field + SizeInGb *int64 `locationName:"sizeInGb" type:"integer" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateDiskFromSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDiskFromSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDiskFromSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDiskFromSnapshotInput"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + if s.DiskName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskName")) + } + if s.DiskSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskSnapshotName")) + } + if s.SizeInGb == nil { + invalidParams.Add(request.NewErrParamRequired("SizeInGb")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *CreateDiskFromSnapshotInput) SetAvailabilityZone(v string) *CreateDiskFromSnapshotInput { + s.AvailabilityZone = &v + return s +} + +// SetDiskName sets the DiskName field's value. +func (s *CreateDiskFromSnapshotInput) SetDiskName(v string) *CreateDiskFromSnapshotInput { + s.DiskName = &v + return s +} + +// SetDiskSnapshotName sets the DiskSnapshotName field's value. +func (s *CreateDiskFromSnapshotInput) SetDiskSnapshotName(v string) *CreateDiskFromSnapshotInput { + s.DiskSnapshotName = &v + return s +} + +// SetSizeInGb sets the SizeInGb field's value. +func (s *CreateDiskFromSnapshotInput) SetSizeInGb(v int64) *CreateDiskFromSnapshotInput { + s.SizeInGb = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateDiskFromSnapshotInput) SetTags(v []*Tag) *CreateDiskFromSnapshotInput { + s.Tags = v + return s +} + +type CreateDiskFromSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateDiskFromSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDiskFromSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateDiskFromSnapshotOutput) SetOperations(v []*Operation) *CreateDiskFromSnapshotOutput { + s.Operations = v + return s +} + +type CreateDiskInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone where you want to create the disk (e.g., us-east-2a). + // Choose the same Availability Zone as the Lightsail instance where you want + // to create the disk. + // + // Use the GetRegions operation to list the Availability Zones where Lightsail + // is currently available. + // + // AvailabilityZone is a required field + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // The unique Lightsail disk name (e.g., my-disk). + // + // DiskName is a required field + DiskName *string `locationName:"diskName" type:"string" required:"true"` + + // The size of the disk in GB (e.g., 32). + // + // SizeInGb is a required field + SizeInGb *int64 `locationName:"sizeInGb" type:"integer" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateDiskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDiskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDiskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDiskInput"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + if s.DiskName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskName")) + } + if s.SizeInGb == nil { + invalidParams.Add(request.NewErrParamRequired("SizeInGb")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *CreateDiskInput) SetAvailabilityZone(v string) *CreateDiskInput { + s.AvailabilityZone = &v + return s +} + +// SetDiskName sets the DiskName field's value. +func (s *CreateDiskInput) SetDiskName(v string) *CreateDiskInput { + s.DiskName = &v + return s +} + +// SetSizeInGb sets the SizeInGb field's value. +func (s *CreateDiskInput) SetSizeInGb(v int64) *CreateDiskInput { + s.SizeInGb = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateDiskInput) SetTags(v []*Tag) *CreateDiskInput { + s.Tags = v + return s +} + +type CreateDiskOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateDiskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDiskOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateDiskOutput) SetOperations(v []*Operation) *CreateDiskOutput { + s.Operations = v + return s +} + +type CreateDiskSnapshotInput struct { + _ struct{} `type:"structure"` + + // The unique name of the source disk (e.g., Disk-Virginia-1). + // + // This parameter cannot be defined together with the instance name parameter. + // The disk name and instance name parameters are mutually exclusive. + DiskName *string `locationName:"diskName" type:"string"` + + // The name of the destination disk snapshot (e.g., my-disk-snapshot) based + // on the source disk. + // + // DiskSnapshotName is a required field + DiskSnapshotName *string `locationName:"diskSnapshotName" type:"string" required:"true"` + + // The unique name of the source instance (e.g., Amazon_Linux-512MB-Virginia-1). + // When this is defined, a snapshot of the instance's system volume is created. + // + // This parameter cannot be defined together with the disk name parameter. The + // instance name and disk name parameters are mutually exclusive. + InstanceName *string `locationName:"instanceName" type:"string"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateDiskSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDiskSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDiskSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDiskSnapshotInput"} + if s.DiskSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDiskName sets the DiskName field's value. +func (s *CreateDiskSnapshotInput) SetDiskName(v string) *CreateDiskSnapshotInput { + s.DiskName = &v + return s +} + +// SetDiskSnapshotName sets the DiskSnapshotName field's value. +func (s *CreateDiskSnapshotInput) SetDiskSnapshotName(v string) *CreateDiskSnapshotInput { + s.DiskSnapshotName = &v + return s +} + +// SetInstanceName sets the InstanceName field's value. +func (s *CreateDiskSnapshotInput) SetInstanceName(v string) *CreateDiskSnapshotInput { + s.InstanceName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateDiskSnapshotInput) SetTags(v []*Tag) *CreateDiskSnapshotInput { + s.Tags = v + return s +} + +type CreateDiskSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateDiskSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDiskSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateDiskSnapshotOutput) SetOperations(v []*Operation) *CreateDiskSnapshotOutput { + s.Operations = v + return s +} + +type CreateDomainEntryInput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the domain entry + // request. + // + // DomainEntry is a required field + DomainEntry *DomainEntry `locationName:"domainEntry" type:"structure" required:"true"` + + // The domain name (e.g., example.com) for which you want to create the domain + // entry. + // + // DomainName is a required field + DomainName *string `locationName:"domainName" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateDomainEntryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDomainEntryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDomainEntryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDomainEntryInput"} + if s.DomainEntry == nil { + invalidParams.Add(request.NewErrParamRequired("DomainEntry")) + } + if s.DomainName == nil { + invalidParams.Add(request.NewErrParamRequired("DomainName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDomainEntry sets the DomainEntry field's value. +func (s *CreateDomainEntryInput) SetDomainEntry(v *DomainEntry) *CreateDomainEntryInput { + s.DomainEntry = v + return s +} + +// SetDomainName sets the DomainName field's value. +func (s *CreateDomainEntryInput) SetDomainName(v string) *CreateDomainEntryInput { + s.DomainName = &v + return s +} + +type CreateDomainEntryOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the operation. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s CreateDomainEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDomainEntryOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *CreateDomainEntryOutput) SetOperation(v *Operation) *CreateDomainEntryOutput { + s.Operation = v + return s +} + +type CreateDomainInput struct { + _ struct{} `type:"structure"` + + // The domain name to manage (e.g., example.com). + // + // You cannot register a new domain name using Lightsail. You must register + // a domain name using Amazon Route 53 or another domain name registrar. If + // you have already registered your domain, you can enter its name in this parameter + // to manage the DNS records for that domain. + // + // DomainName is a required field + DomainName *string `locationName:"domainName" type:"string" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateDomainInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDomainInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateDomainInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateDomainInput"} + if s.DomainName == nil { + invalidParams.Add(request.NewErrParamRequired("DomainName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDomainName sets the DomainName field's value. +func (s *CreateDomainInput) SetDomainName(v string) *CreateDomainInput { + s.DomainName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateDomainInput) SetTags(v []*Tag) *CreateDomainInput { + s.Tags = v + return s +} + +type CreateDomainOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the domain resource + // you created. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s CreateDomainOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateDomainOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *CreateDomainOutput) SetOperation(v *Operation) *CreateDomainOutput { + s.Operation = v + return s +} + +type CreateInstanceSnapshotInput struct { + _ struct{} `type:"structure"` + + // The Lightsail instance on which to base your snapshot. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` + + // The name for your new snapshot. + // + // InstanceSnapshotName is a required field + InstanceSnapshotName *string `locationName:"instanceSnapshotName" type:"string" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateInstanceSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstanceSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateInstanceSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateInstanceSnapshotInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + if s.InstanceSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *CreateInstanceSnapshotInput) SetInstanceName(v string) *CreateInstanceSnapshotInput { + s.InstanceName = &v + return s +} + +// SetInstanceSnapshotName sets the InstanceSnapshotName field's value. +func (s *CreateInstanceSnapshotInput) SetInstanceSnapshotName(v string) *CreateInstanceSnapshotInput { + s.InstanceSnapshotName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateInstanceSnapshotInput) SetTags(v []*Tag) *CreateInstanceSnapshotInput { + s.Tags = v + return s +} + +type CreateInstanceSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // create instances snapshot request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateInstanceSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstanceSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateInstanceSnapshotOutput) SetOperations(v []*Operation) *CreateInstanceSnapshotOutput { + s.Operations = v + return s +} + +type CreateInstancesFromSnapshotInput struct { + _ struct{} `type:"structure"` + + // An object containing information about one or more disk mappings. + AttachedDiskMapping map[string][]*DiskMap `locationName:"attachedDiskMapping" type:"map"` + + // The Availability Zone where you want to create your instances. Use the following + // formatting: us-east-2a (case sensitive). You can get a list of Availability + // Zones by using the get regions (http://docs.aws.amazon.com/lightsail/2016-11-28/api-reference/API_GetRegions.html) + // operation. Be sure to add the include Availability Zones parameter to your + // request. + // + // AvailabilityZone is a required field + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // The bundle of specification information for your virtual private server (or + // instance), including the pricing plan (e.g., micro_1_0). + // + // BundleId is a required field + BundleId *string `locationName:"bundleId" type:"string" required:"true"` + + // The names for your new instances. + // + // InstanceNames is a required field + InstanceNames []*string `locationName:"instanceNames" type:"list" required:"true"` + + // The name of the instance snapshot on which you are basing your new instances. + // Use the get instance snapshots operation to return information about your + // existing snapshots. + // + // InstanceSnapshotName is a required field + InstanceSnapshotName *string `locationName:"instanceSnapshotName" type:"string" required:"true"` + + // The name for your key pair. + KeyPairName *string `locationName:"keyPairName" type:"string"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` + + // You can create a launch script that configures a server with additional user + // data. For example, apt-get -y update. + // + // Depending on the machine image you choose, the command to get software on + // your instance varies. Amazon Linux and CentOS use yum, Debian and Ubuntu + // use apt-get, and FreeBSD uses pkg. For a complete list, see the Dev Guide + // (https://lightsail.aws.amazon.com/ls/docs/getting-started/article/compare-options-choose-lightsail-instance-image). + UserData *string `locationName:"userData" type:"string"` +} + +// String returns the string representation +func (s CreateInstancesFromSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstancesFromSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateInstancesFromSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateInstancesFromSnapshotInput"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + if s.BundleId == nil { + invalidParams.Add(request.NewErrParamRequired("BundleId")) + } + if s.InstanceNames == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceNames")) + } + if s.InstanceSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttachedDiskMapping sets the AttachedDiskMapping field's value. +func (s *CreateInstancesFromSnapshotInput) SetAttachedDiskMapping(v map[string][]*DiskMap) *CreateInstancesFromSnapshotInput { + s.AttachedDiskMapping = v + return s +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *CreateInstancesFromSnapshotInput) SetAvailabilityZone(v string) *CreateInstancesFromSnapshotInput { + s.AvailabilityZone = &v + return s +} + +// SetBundleId sets the BundleId field's value. +func (s *CreateInstancesFromSnapshotInput) SetBundleId(v string) *CreateInstancesFromSnapshotInput { + s.BundleId = &v + return s +} + +// SetInstanceNames sets the InstanceNames field's value. +func (s *CreateInstancesFromSnapshotInput) SetInstanceNames(v []*string) *CreateInstancesFromSnapshotInput { + s.InstanceNames = v + return s +} + +// SetInstanceSnapshotName sets the InstanceSnapshotName field's value. +func (s *CreateInstancesFromSnapshotInput) SetInstanceSnapshotName(v string) *CreateInstancesFromSnapshotInput { + s.InstanceSnapshotName = &v + return s +} + +// SetKeyPairName sets the KeyPairName field's value. +func (s *CreateInstancesFromSnapshotInput) SetKeyPairName(v string) *CreateInstancesFromSnapshotInput { + s.KeyPairName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateInstancesFromSnapshotInput) SetTags(v []*Tag) *CreateInstancesFromSnapshotInput { + s.Tags = v + return s +} + +// SetUserData sets the UserData field's value. +func (s *CreateInstancesFromSnapshotInput) SetUserData(v string) *CreateInstancesFromSnapshotInput { + s.UserData = &v + return s +} + +type CreateInstancesFromSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // create instances from snapshot request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateInstancesFromSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstancesFromSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateInstancesFromSnapshotOutput) SetOperations(v []*Operation) *CreateInstancesFromSnapshotOutput { + s.Operations = v + return s +} + +type CreateInstancesInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which to create your instance. Use the following + // format: us-east-2a (case sensitive). You can get a list of Availability Zones + // by using the get regions (http://docs.aws.amazon.com/lightsail/2016-11-28/api-reference/API_GetRegions.html) + // operation. Be sure to add the include Availability Zones parameter to your + // request. + // + // AvailabilityZone is a required field + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // The ID for a virtual private server image (e.g., app_wordpress_4_4 or app_lamp_7_0). + // Use the get blueprints operation to return a list of available images (or + // blueprints). + // + // BlueprintId is a required field + BlueprintId *string `locationName:"blueprintId" type:"string" required:"true"` + + // The bundle of specification information for your virtual private server (or + // instance), including the pricing plan (e.g., micro_1_0). + // + // BundleId is a required field + BundleId *string `locationName:"bundleId" type:"string" required:"true"` + + // (Deprecated) The name for your custom image. + // + // In releases prior to June 12, 2017, this parameter was ignored by the API. + // It is now deprecated. + // + // Deprecated: CustomImageName has been deprecated + CustomImageName *string `locationName:"customImageName" deprecated:"true" type:"string"` + + // The names to use for your new Lightsail instances. Separate multiple values + // using quotation marks and commas, for example: ["MyFirstInstance","MySecondInstance"] + // + // InstanceNames is a required field + InstanceNames []*string `locationName:"instanceNames" type:"list" required:"true"` + + // The name of your key pair. + KeyPairName *string `locationName:"keyPairName" type:"string"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` + + // A launch script you can create that configures a server with additional user + // data. For example, you might want to run apt-get -y update. + // + // Depending on the machine image you choose, the command to get software on + // your instance varies. Amazon Linux and CentOS use yum, Debian and Ubuntu + // use apt-get, and FreeBSD uses pkg. For a complete list, see the Dev Guide + // (https://lightsail.aws.amazon.com/ls/docs/getting-started/article/compare-options-choose-lightsail-instance-image). + UserData *string `locationName:"userData" type:"string"` +} + +// String returns the string representation +func (s CreateInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstancesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateInstancesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateInstancesInput"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + if s.BlueprintId == nil { + invalidParams.Add(request.NewErrParamRequired("BlueprintId")) + } + if s.BundleId == nil { + invalidParams.Add(request.NewErrParamRequired("BundleId")) + } + if s.InstanceNames == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceNames")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *CreateInstancesInput) SetAvailabilityZone(v string) *CreateInstancesInput { + s.AvailabilityZone = &v + return s +} + +// SetBlueprintId sets the BlueprintId field's value. +func (s *CreateInstancesInput) SetBlueprintId(v string) *CreateInstancesInput { + s.BlueprintId = &v + return s +} + +// SetBundleId sets the BundleId field's value. +func (s *CreateInstancesInput) SetBundleId(v string) *CreateInstancesInput { + s.BundleId = &v + return s +} + +// SetCustomImageName sets the CustomImageName field's value. +func (s *CreateInstancesInput) SetCustomImageName(v string) *CreateInstancesInput { + s.CustomImageName = &v + return s +} + +// SetInstanceNames sets the InstanceNames field's value. +func (s *CreateInstancesInput) SetInstanceNames(v []*string) *CreateInstancesInput { + s.InstanceNames = v + return s +} + +// SetKeyPairName sets the KeyPairName field's value. +func (s *CreateInstancesInput) SetKeyPairName(v string) *CreateInstancesInput { + s.KeyPairName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateInstancesInput) SetTags(v []*Tag) *CreateInstancesInput { + s.Tags = v + return s +} + +// SetUserData sets the UserData field's value. +func (s *CreateInstancesInput) SetUserData(v string) *CreateInstancesInput { + s.UserData = &v + return s +} + +type CreateInstancesOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // create instances request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateInstancesOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateInstancesOutput) SetOperations(v []*Operation) *CreateInstancesOutput { + s.Operations = v + return s +} + +type CreateKeyPairInput struct { + _ struct{} `type:"structure"` + + // The name for your new key pair. + // + // KeyPairName is a required field + KeyPairName *string `locationName:"keyPairName" type:"string" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateKeyPairInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateKeyPairInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateKeyPairInput"} + if s.KeyPairName == nil { + invalidParams.Add(request.NewErrParamRequired("KeyPairName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKeyPairName sets the KeyPairName field's value. +func (s *CreateKeyPairInput) SetKeyPairName(v string) *CreateKeyPairInput { + s.KeyPairName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateKeyPairInput) SetTags(v []*Tag) *CreateKeyPairInput { + s.Tags = v + return s +} + +type CreateKeyPairOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the new key pair + // you just created. + KeyPair *KeyPair `locationName:"keyPair" type:"structure"` + + // An array of key-value pairs containing information about the results of your + // create key pair request. + Operation *Operation `locationName:"operation" type:"structure"` + + // A base64-encoded RSA private key. + PrivateKeyBase64 *string `locationName:"privateKeyBase64" type:"string"` + + // A base64-encoded public key of the ssh-rsa type. + PublicKeyBase64 *string `locationName:"publicKeyBase64" type:"string"` +} + +// String returns the string representation +func (s CreateKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateKeyPairOutput) GoString() string { + return s.String() +} + +// SetKeyPair sets the KeyPair field's value. +func (s *CreateKeyPairOutput) SetKeyPair(v *KeyPair) *CreateKeyPairOutput { + s.KeyPair = v + return s +} + +// SetOperation sets the Operation field's value. +func (s *CreateKeyPairOutput) SetOperation(v *Operation) *CreateKeyPairOutput { + s.Operation = v + return s +} + +// SetPrivateKeyBase64 sets the PrivateKeyBase64 field's value. +func (s *CreateKeyPairOutput) SetPrivateKeyBase64(v string) *CreateKeyPairOutput { + s.PrivateKeyBase64 = &v + return s +} + +// SetPublicKeyBase64 sets the PublicKeyBase64 field's value. +func (s *CreateKeyPairOutput) SetPublicKeyBase64(v string) *CreateKeyPairOutput { + s.PublicKeyBase64 = &v + return s +} + +type CreateLoadBalancerInput struct { + _ struct{} `type:"structure"` + + // The optional alternative domains and subdomains to use with your SSL/TLS + // certificate (e.g., www.example.com, example.com, m.example.com, blog.example.com). + CertificateAlternativeNames []*string `locationName:"certificateAlternativeNames" type:"list"` + + // The domain name with which your certificate is associated (e.g., example.com). + // + // If you specify certificateDomainName, then certificateName is required (and + // vice-versa). + CertificateDomainName *string `locationName:"certificateDomainName" type:"string"` + + // The name of the SSL/TLS certificate. + // + // If you specify certificateName, then certificateDomainName is required (and + // vice-versa). + CertificateName *string `locationName:"certificateName" type:"string"` + + // The path you provided to perform the load balancer health check. If you didn't + // specify a health check path, Lightsail uses the root path of your website + // (e.g., "/"). + // + // You may want to specify a custom health check path other than the root of + // your application if your home page loads slowly or has a lot of media or + // scripting on it. + HealthCheckPath *string `locationName:"healthCheckPath" type:"string"` + + // The instance port where you're creating your load balancer. + // + // InstancePort is a required field + InstancePort *int64 `locationName:"instancePort" type:"integer" required:"true"` + + // The name of your load balancer. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateLoadBalancerInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateLoadBalancerInput"} + if s.InstancePort == nil { + invalidParams.Add(request.NewErrParamRequired("InstancePort")) + } + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCertificateAlternativeNames sets the CertificateAlternativeNames field's value. +func (s *CreateLoadBalancerInput) SetCertificateAlternativeNames(v []*string) *CreateLoadBalancerInput { + s.CertificateAlternativeNames = v + return s +} + +// SetCertificateDomainName sets the CertificateDomainName field's value. +func (s *CreateLoadBalancerInput) SetCertificateDomainName(v string) *CreateLoadBalancerInput { + s.CertificateDomainName = &v + return s +} + +// SetCertificateName sets the CertificateName field's value. +func (s *CreateLoadBalancerInput) SetCertificateName(v string) *CreateLoadBalancerInput { + s.CertificateName = &v + return s +} + +// SetHealthCheckPath sets the HealthCheckPath field's value. +func (s *CreateLoadBalancerInput) SetHealthCheckPath(v string) *CreateLoadBalancerInput { + s.HealthCheckPath = &v + return s +} + +// SetInstancePort sets the InstancePort field's value. +func (s *CreateLoadBalancerInput) SetInstancePort(v int64) *CreateLoadBalancerInput { + s.InstancePort = &v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *CreateLoadBalancerInput) SetLoadBalancerName(v string) *CreateLoadBalancerInput { + s.LoadBalancerName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateLoadBalancerInput) SetTags(v []*Tag) *CreateLoadBalancerInput { + s.Tags = v + return s +} + +type CreateLoadBalancerOutput struct { + _ struct{} `type:"structure"` + + // An object containing information about the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateLoadBalancerOutput) SetOperations(v []*Operation) *CreateLoadBalancerOutput { + s.Operations = v + return s +} + +type CreateLoadBalancerTlsCertificateInput struct { + _ struct{} `type:"structure"` + + // An array of strings listing alternative domains and subdomains for your SSL/TLS + // certificate. Lightsail will de-dupe the names for you. You can have a maximum + // of 9 alternative names (in addition to the 1 primary domain). We do not support + // wildcards (e.g., *.example.com). + CertificateAlternativeNames []*string `locationName:"certificateAlternativeNames" type:"list"` + + // The domain name (e.g., example.com) for your SSL/TLS certificate. + // + // CertificateDomainName is a required field + CertificateDomainName *string `locationName:"certificateDomainName" type:"string" required:"true"` + + // The SSL/TLS certificate name. + // + // You can have up to 10 certificates in your account at one time. Each Lightsail + // load balancer can have up to 2 certificates associated with it at one time. + // There is also an overall limit to the number of certificates that can be + // issue in a 365-day period. For more information, see Limits (http://docs.aws.amazon.com/acm/latest/userguide/acm-limits.html). + // + // CertificateName is a required field + CertificateName *string `locationName:"certificateName" type:"string" required:"true"` + + // The load balancer name where you want to create the SSL/TLS certificate. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateLoadBalancerTlsCertificateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerTlsCertificateInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateLoadBalancerTlsCertificateInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateLoadBalancerTlsCertificateInput"} + if s.CertificateDomainName == nil { + invalidParams.Add(request.NewErrParamRequired("CertificateDomainName")) + } + if s.CertificateName == nil { + invalidParams.Add(request.NewErrParamRequired("CertificateName")) + } + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCertificateAlternativeNames sets the CertificateAlternativeNames field's value. +func (s *CreateLoadBalancerTlsCertificateInput) SetCertificateAlternativeNames(v []*string) *CreateLoadBalancerTlsCertificateInput { + s.CertificateAlternativeNames = v + return s +} + +// SetCertificateDomainName sets the CertificateDomainName field's value. +func (s *CreateLoadBalancerTlsCertificateInput) SetCertificateDomainName(v string) *CreateLoadBalancerTlsCertificateInput { + s.CertificateDomainName = &v + return s +} + +// SetCertificateName sets the CertificateName field's value. +func (s *CreateLoadBalancerTlsCertificateInput) SetCertificateName(v string) *CreateLoadBalancerTlsCertificateInput { + s.CertificateName = &v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *CreateLoadBalancerTlsCertificateInput) SetLoadBalancerName(v string) *CreateLoadBalancerTlsCertificateInput { + s.LoadBalancerName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateLoadBalancerTlsCertificateInput) SetTags(v []*Tag) *CreateLoadBalancerTlsCertificateInput { + s.Tags = v + return s +} + +type CreateLoadBalancerTlsCertificateOutput struct { + _ struct{} `type:"structure"` + + // An object containing information about the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateLoadBalancerTlsCertificateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateLoadBalancerTlsCertificateOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateLoadBalancerTlsCertificateOutput) SetOperations(v []*Operation) *CreateLoadBalancerTlsCertificateOutput { + s.Operations = v + return s +} + +type CreateRelationalDatabaseFromSnapshotInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which to create your new database. Use the us-east-2a + // case-sensitive format. + // + // You can get a list of Availability Zones by using the get regions operation. + // Be sure to add the include relational database Availability Zones parameter + // to your request. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // Specifies the accessibility options for your new database. A value of true + // specifies a database that is available to resources outside of your Lightsail + // account. A value of false specifies a database that is available only to + // your Lightsail resources in the same region as your database. + PubliclyAccessible *bool `locationName:"publiclyAccessible" type:"boolean"` + + // The bundle ID for your new database. A bundle describes the performance specifications + // for your database. + // + // You can get a list of database bundle IDs by using the get relational database + // bundles operation. + // + // When creating a new database from a snapshot, you cannot choose a bundle + // that is smaller than the bundle of the source database. + RelationalDatabaseBundleId *string `locationName:"relationalDatabaseBundleId" type:"string"` + + // The name to use for your new database. + // + // Constraints: + // + // * Must contain from 2 to 255 alphanumeric characters, or hyphens. + // + // * The first and last character must be a letter or number. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` + + // The name of the database snapshot from which to create your new database. + RelationalDatabaseSnapshotName *string `locationName:"relationalDatabaseSnapshotName" type:"string"` + + // The date and time to restore your database from. + // + // Constraints: + // + // * Must be before the latest restorable time for the database. + // + // * Cannot be specified if the use latest restorable time parameter is true. + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Specified in the Unix time format. For example, if you wish to use a + // restore time of October 1, 2018, at 8 PM UTC, then you input 1538424000 + // as the restore time. + RestoreTime *time.Time `locationName:"restoreTime" type:"timestamp"` + + // The name of the source database. + SourceRelationalDatabaseName *string `locationName:"sourceRelationalDatabaseName" type:"string"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` + + // Specifies whether your database is restored from the latest backup time. + // A value of true restores from the latest backup time. + // + // Default: false + // + // Constraints: Cannot be specified if the restore time parameter is provided. + UseLatestRestorableTime *bool `locationName:"useLatestRestorableTime" type:"boolean"` +} + +// String returns the string representation +func (s CreateRelationalDatabaseFromSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRelationalDatabaseFromSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateRelationalDatabaseFromSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateRelationalDatabaseFromSnapshotInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetAvailabilityZone(v string) *CreateRelationalDatabaseFromSnapshotInput { + s.AvailabilityZone = &v + return s +} + +// SetPubliclyAccessible sets the PubliclyAccessible field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetPubliclyAccessible(v bool) *CreateRelationalDatabaseFromSnapshotInput { + s.PubliclyAccessible = &v + return s +} + +// SetRelationalDatabaseBundleId sets the RelationalDatabaseBundleId field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetRelationalDatabaseBundleId(v string) *CreateRelationalDatabaseFromSnapshotInput { + s.RelationalDatabaseBundleId = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetRelationalDatabaseName(v string) *CreateRelationalDatabaseFromSnapshotInput { + s.RelationalDatabaseName = &v + return s +} + +// SetRelationalDatabaseSnapshotName sets the RelationalDatabaseSnapshotName field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetRelationalDatabaseSnapshotName(v string) *CreateRelationalDatabaseFromSnapshotInput { + s.RelationalDatabaseSnapshotName = &v + return s +} + +// SetRestoreTime sets the RestoreTime field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetRestoreTime(v time.Time) *CreateRelationalDatabaseFromSnapshotInput { + s.RestoreTime = &v + return s +} + +// SetSourceRelationalDatabaseName sets the SourceRelationalDatabaseName field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetSourceRelationalDatabaseName(v string) *CreateRelationalDatabaseFromSnapshotInput { + s.SourceRelationalDatabaseName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetTags(v []*Tag) *CreateRelationalDatabaseFromSnapshotInput { + s.Tags = v + return s +} + +// SetUseLatestRestorableTime sets the UseLatestRestorableTime field's value. +func (s *CreateRelationalDatabaseFromSnapshotInput) SetUseLatestRestorableTime(v bool) *CreateRelationalDatabaseFromSnapshotInput { + s.UseLatestRestorableTime = &v + return s +} + +type CreateRelationalDatabaseFromSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your create relational database from snapshot + // request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateRelationalDatabaseFromSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRelationalDatabaseFromSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateRelationalDatabaseFromSnapshotOutput) SetOperations(v []*Operation) *CreateRelationalDatabaseFromSnapshotOutput { + s.Operations = v + return s +} + +type CreateRelationalDatabaseInput struct { + _ struct{} `type:"structure"` + + // The Availability Zone in which to create your new database. Use the us-east-2a + // case-sensitive format. + // + // You can get a list of Availability Zones by using the get regions operation. + // Be sure to add the include relational database Availability Zones parameter + // to your request. + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The name of the master database created when the Lightsail database resource + // is created. + // + // Constraints: + // + // * Must contain from 1 to 64 alphanumeric characters. + // + // * Cannot be a word reserved by the specified database engine + // + // MasterDatabaseName is a required field + MasterDatabaseName *string `locationName:"masterDatabaseName" type:"string" required:"true"` + + // The password for the master user of your new database. The password can include + // any printable ASCII character except "/", """, or "@". + // + // Constraints: Must contain 8 to 41 characters. + MasterUserPassword *string `locationName:"masterUserPassword" type:"string" sensitive:"true"` + + // The master user name for your new database. + // + // Constraints: + // + // * Master user name is required. + // + // * Must contain from 1 to 16 alphanumeric characters. + // + // * The first character must be a letter. + // + // * Cannot be a reserved word for the database engine you choose. For more + // information about reserved words in MySQL 5.6 or 5.7, see the Keywords + // and Reserved Words articles for MySQL 5.6 (https://dev.mysql.com/doc/refman/5.6/en/keywords.html) + // or MySQL 5.7 (https://dev.mysql.com/doc/refman/5.7/en/keywords.html) respectively. + // + // MasterUsername is a required field + MasterUsername *string `locationName:"masterUsername" type:"string" required:"true"` + + // The daily time range during which automated backups are created for your + // new database if automated backups are enabled. + // + // The default is a 30-minute window selected at random from an 8-hour block + // of time for each AWS Region. For more information about the preferred backup + // window time blocks for each region, see the Working With Backups (https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithAutomatedBackups.html#USER_WorkingWithAutomatedBackups.BackupWindow) + // guide in the Amazon Relational Database Service (Amazon RDS) documentation. + // + // Constraints: + // + // * Must be in the hh24:mi-hh24:mi format. Example: 16:00-16:30 + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Must not conflict with the preferred maintenance window. + // + // * Must be at least 30 minutes. + PreferredBackupWindow *string `locationName:"preferredBackupWindow" type:"string"` + + // The weekly time range during which system maintenance can occur on your new + // database. + // + // The default is a 30-minute window selected at random from an 8-hour block + // of time for each AWS Region, occurring on a random day of the week. + // + // Constraints: + // + // * Must be in the ddd:hh24:mi-ddd:hh24:mi format. + // + // * Valid days: Mon, Tue, Wed, Thu, Fri, Sat, Sun. + // + // * Must be at least 30 minutes. + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Example: Tue:17:00-Tue:17:30 + PreferredMaintenanceWindow *string `locationName:"preferredMaintenanceWindow" type:"string"` + + // Specifies the accessibility options for your new database. A value of true + // specifies a database that is available to resources outside of your Lightsail + // account. A value of false specifies a database that is available only to + // your Lightsail resources in the same region as your database. + PubliclyAccessible *bool `locationName:"publiclyAccessible" type:"boolean"` + + // The blueprint ID for your new database. A blueprint describes the major engine + // version of a database. + // + // You can get a list of database blueprints IDs by using the get relational + // database blueprints operation. + // + // RelationalDatabaseBlueprintId is a required field + RelationalDatabaseBlueprintId *string `locationName:"relationalDatabaseBlueprintId" type:"string" required:"true"` + + // The bundle ID for your new database. A bundle describes the performance specifications + // for your database. + // + // You can get a list of database bundle IDs by using the get relational database + // bundles operation. + // + // RelationalDatabaseBundleId is a required field + RelationalDatabaseBundleId *string `locationName:"relationalDatabaseBundleId" type:"string" required:"true"` + + // The name to use for your new database. + // + // Constraints: + // + // * Must contain from 2 to 255 alphanumeric characters, or hyphens. + // + // * The first and last character must be a letter or number. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateRelationalDatabaseInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRelationalDatabaseInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateRelationalDatabaseInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateRelationalDatabaseInput"} + if s.MasterDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("MasterDatabaseName")) + } + if s.MasterUsername == nil { + invalidParams.Add(request.NewErrParamRequired("MasterUsername")) + } + if s.RelationalDatabaseBlueprintId == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseBlueprintId")) + } + if s.RelationalDatabaseBundleId == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseBundleId")) + } + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *CreateRelationalDatabaseInput) SetAvailabilityZone(v string) *CreateRelationalDatabaseInput { + s.AvailabilityZone = &v + return s +} + +// SetMasterDatabaseName sets the MasterDatabaseName field's value. +func (s *CreateRelationalDatabaseInput) SetMasterDatabaseName(v string) *CreateRelationalDatabaseInput { + s.MasterDatabaseName = &v + return s +} + +// SetMasterUserPassword sets the MasterUserPassword field's value. +func (s *CreateRelationalDatabaseInput) SetMasterUserPassword(v string) *CreateRelationalDatabaseInput { + s.MasterUserPassword = &v + return s +} + +// SetMasterUsername sets the MasterUsername field's value. +func (s *CreateRelationalDatabaseInput) SetMasterUsername(v string) *CreateRelationalDatabaseInput { + s.MasterUsername = &v + return s +} + +// SetPreferredBackupWindow sets the PreferredBackupWindow field's value. +func (s *CreateRelationalDatabaseInput) SetPreferredBackupWindow(v string) *CreateRelationalDatabaseInput { + s.PreferredBackupWindow = &v + return s +} + +// SetPreferredMaintenanceWindow sets the PreferredMaintenanceWindow field's value. +func (s *CreateRelationalDatabaseInput) SetPreferredMaintenanceWindow(v string) *CreateRelationalDatabaseInput { + s.PreferredMaintenanceWindow = &v + return s +} + +// SetPubliclyAccessible sets the PubliclyAccessible field's value. +func (s *CreateRelationalDatabaseInput) SetPubliclyAccessible(v bool) *CreateRelationalDatabaseInput { + s.PubliclyAccessible = &v + return s +} + +// SetRelationalDatabaseBlueprintId sets the RelationalDatabaseBlueprintId field's value. +func (s *CreateRelationalDatabaseInput) SetRelationalDatabaseBlueprintId(v string) *CreateRelationalDatabaseInput { + s.RelationalDatabaseBlueprintId = &v + return s +} + +// SetRelationalDatabaseBundleId sets the RelationalDatabaseBundleId field's value. +func (s *CreateRelationalDatabaseInput) SetRelationalDatabaseBundleId(v string) *CreateRelationalDatabaseInput { + s.RelationalDatabaseBundleId = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *CreateRelationalDatabaseInput) SetRelationalDatabaseName(v string) *CreateRelationalDatabaseInput { + s.RelationalDatabaseName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateRelationalDatabaseInput) SetTags(v []*Tag) *CreateRelationalDatabaseInput { + s.Tags = v + return s +} + +type CreateRelationalDatabaseOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your create relational database request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateRelationalDatabaseOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRelationalDatabaseOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateRelationalDatabaseOutput) SetOperations(v []*Operation) *CreateRelationalDatabaseOutput { + s.Operations = v + return s +} + +type CreateRelationalDatabaseSnapshotInput struct { + _ struct{} `type:"structure"` + + // The name of the database on which to base your new snapshot. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` + + // The name for your new database snapshot. + // + // Constraints: + // + // * Must contain from 2 to 255 alphanumeric characters, or hyphens. + // + // * The first and last character must be a letter or number. + // + // RelationalDatabaseSnapshotName is a required field + RelationalDatabaseSnapshotName *string `locationName:"relationalDatabaseSnapshotName" type:"string" required:"true"` + + // The tag keys and optional values to add to the resource during create. + // + // To tag a resource after it has been created, see the tag resource operation. + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s CreateRelationalDatabaseSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRelationalDatabaseSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateRelationalDatabaseSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateRelationalDatabaseSnapshotInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + if s.RelationalDatabaseSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *CreateRelationalDatabaseSnapshotInput) SetRelationalDatabaseName(v string) *CreateRelationalDatabaseSnapshotInput { + s.RelationalDatabaseName = &v + return s +} + +// SetRelationalDatabaseSnapshotName sets the RelationalDatabaseSnapshotName field's value. +func (s *CreateRelationalDatabaseSnapshotInput) SetRelationalDatabaseSnapshotName(v string) *CreateRelationalDatabaseSnapshotInput { + s.RelationalDatabaseSnapshotName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *CreateRelationalDatabaseSnapshotInput) SetTags(v []*Tag) *CreateRelationalDatabaseSnapshotInput { + s.Tags = v + return s +} + +type CreateRelationalDatabaseSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your create relational database snapshot + // request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s CreateRelationalDatabaseSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateRelationalDatabaseSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *CreateRelationalDatabaseSnapshotOutput) SetOperations(v []*Operation) *CreateRelationalDatabaseSnapshotOutput { + s.Operations = v + return s +} + +type DeleteDiskInput struct { + _ struct{} `type:"structure"` + + // The unique name of the disk you want to delete (e.g., my-disk). + // + // DiskName is a required field + DiskName *string `locationName:"diskName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteDiskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDiskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteDiskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteDiskInput"} + if s.DiskName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDiskName sets the DiskName field's value. +func (s *DeleteDiskInput) SetDiskName(v string) *DeleteDiskInput { + s.DiskName = &v + return s +} + +type DeleteDiskOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteDiskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDiskOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteDiskOutput) SetOperations(v []*Operation) *DeleteDiskOutput { + s.Operations = v + return s +} + +type DeleteDiskSnapshotInput struct { + _ struct{} `type:"structure"` + + // The name of the disk snapshot you want to delete (e.g., my-disk-snapshot). + // + // DiskSnapshotName is a required field + DiskSnapshotName *string `locationName:"diskSnapshotName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteDiskSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDiskSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteDiskSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteDiskSnapshotInput"} + if s.DiskSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDiskSnapshotName sets the DiskSnapshotName field's value. +func (s *DeleteDiskSnapshotInput) SetDiskSnapshotName(v string) *DeleteDiskSnapshotInput { + s.DiskSnapshotName = &v + return s +} + +type DeleteDiskSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteDiskSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDiskSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteDiskSnapshotOutput) SetOperations(v []*Operation) *DeleteDiskSnapshotOutput { + s.Operations = v + return s +} + +type DeleteDomainEntryInput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about your domain entries. + // + // DomainEntry is a required field + DomainEntry *DomainEntry `locationName:"domainEntry" type:"structure" required:"true"` + + // The name of the domain entry to delete. + // + // DomainName is a required field + DomainName *string `locationName:"domainName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteDomainEntryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDomainEntryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteDomainEntryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteDomainEntryInput"} + if s.DomainEntry == nil { + invalidParams.Add(request.NewErrParamRequired("DomainEntry")) + } + if s.DomainName == nil { + invalidParams.Add(request.NewErrParamRequired("DomainName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDomainEntry sets the DomainEntry field's value. +func (s *DeleteDomainEntryInput) SetDomainEntry(v *DomainEntry) *DeleteDomainEntryInput { + s.DomainEntry = v + return s +} + +// SetDomainName sets the DomainName field's value. +func (s *DeleteDomainEntryInput) SetDomainName(v string) *DeleteDomainEntryInput { + s.DomainName = &v + return s +} + +type DeleteDomainEntryOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // delete domain entry request. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s DeleteDomainEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDomainEntryOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *DeleteDomainEntryOutput) SetOperation(v *Operation) *DeleteDomainEntryOutput { + s.Operation = v + return s +} + +type DeleteDomainInput struct { + _ struct{} `type:"structure"` + + // The specific domain name to delete. + // + // DomainName is a required field + DomainName *string `locationName:"domainName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteDomainInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDomainInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteDomainInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteDomainInput"} + if s.DomainName == nil { + invalidParams.Add(request.NewErrParamRequired("DomainName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDomainName sets the DomainName field's value. +func (s *DeleteDomainInput) SetDomainName(v string) *DeleteDomainInput { + s.DomainName = &v + return s +} + +type DeleteDomainOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // delete domain request. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s DeleteDomainOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteDomainOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *DeleteDomainOutput) SetOperation(v *Operation) *DeleteDomainOutput { + s.Operation = v + return s +} + +type DeleteInstanceInput struct { + _ struct{} `type:"structure"` + + // The name of the instance to delete. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteInstanceInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *DeleteInstanceInput) SetInstanceName(v string) *DeleteInstanceInput { + s.InstanceName = &v + return s +} + +type DeleteInstanceOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // delete instance request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteInstanceOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteInstanceOutput) SetOperations(v []*Operation) *DeleteInstanceOutput { + s.Operations = v + return s +} + +type DeleteInstanceSnapshotInput struct { + _ struct{} `type:"structure"` + + // The name of the snapshot to delete. + // + // InstanceSnapshotName is a required field + InstanceSnapshotName *string `locationName:"instanceSnapshotName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteInstanceSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteInstanceSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteInstanceSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteInstanceSnapshotInput"} + if s.InstanceSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceSnapshotName sets the InstanceSnapshotName field's value. +func (s *DeleteInstanceSnapshotInput) SetInstanceSnapshotName(v string) *DeleteInstanceSnapshotInput { + s.InstanceSnapshotName = &v + return s +} + +type DeleteInstanceSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // delete instance snapshot request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteInstanceSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteInstanceSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteInstanceSnapshotOutput) SetOperations(v []*Operation) *DeleteInstanceSnapshotOutput { + s.Operations = v + return s +} + +type DeleteKeyPairInput struct { + _ struct{} `type:"structure"` + + // The name of the key pair to delete. + // + // KeyPairName is a required field + KeyPairName *string `locationName:"keyPairName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteKeyPairInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteKeyPairInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteKeyPairInput"} + if s.KeyPairName == nil { + invalidParams.Add(request.NewErrParamRequired("KeyPairName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKeyPairName sets the KeyPairName field's value. +func (s *DeleteKeyPairInput) SetKeyPairName(v string) *DeleteKeyPairInput { + s.KeyPairName = &v + return s +} + +type DeleteKeyPairOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // delete key pair request. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s DeleteKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteKeyPairOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *DeleteKeyPairOutput) SetOperation(v *Operation) *DeleteKeyPairOutput { + s.Operation = v + return s +} + +type DeleteKnownHostKeysInput struct { + _ struct{} `type:"structure"` + + // The name of the instance for which you want to reset the host key or certificate. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteKnownHostKeysInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteKnownHostKeysInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteKnownHostKeysInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteKnownHostKeysInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *DeleteKnownHostKeysInput) SetInstanceName(v string) *DeleteKnownHostKeysInput { + s.InstanceName = &v + return s +} + +type DeleteKnownHostKeysOutput struct { + _ struct{} `type:"structure"` + + // A list of objects describing the API operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteKnownHostKeysOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteKnownHostKeysOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteKnownHostKeysOutput) SetOperations(v []*Operation) *DeleteKnownHostKeysOutput { + s.Operations = v + return s +} + +type DeleteLoadBalancerInput struct { + _ struct{} `type:"structure"` + + // The name of the load balancer you want to delete. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteLoadBalancerInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteLoadBalancerInput"} + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *DeleteLoadBalancerInput) SetLoadBalancerName(v string) *DeleteLoadBalancerInput { + s.LoadBalancerName = &v + return s +} + +type DeleteLoadBalancerOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteLoadBalancerOutput) SetOperations(v []*Operation) *DeleteLoadBalancerOutput { + s.Operations = v + return s +} + +type DeleteLoadBalancerTlsCertificateInput struct { + _ struct{} `type:"structure"` + + // The SSL/TLS certificate name. + // + // CertificateName is a required field + CertificateName *string `locationName:"certificateName" type:"string" required:"true"` + + // When true, forces the deletion of an SSL/TLS certificate. + // + // There can be two certificates associated with a Lightsail load balancer: + // the primary and the backup. The force parameter is required when the primary + // SSL/TLS certificate is in use by an instance attached to the load balancer. + Force *bool `locationName:"force" type:"boolean"` + + // The load balancer name. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteLoadBalancerTlsCertificateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerTlsCertificateInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteLoadBalancerTlsCertificateInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteLoadBalancerTlsCertificateInput"} + if s.CertificateName == nil { + invalidParams.Add(request.NewErrParamRequired("CertificateName")) + } + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCertificateName sets the CertificateName field's value. +func (s *DeleteLoadBalancerTlsCertificateInput) SetCertificateName(v string) *DeleteLoadBalancerTlsCertificateInput { + s.CertificateName = &v + return s +} + +// SetForce sets the Force field's value. +func (s *DeleteLoadBalancerTlsCertificateInput) SetForce(v bool) *DeleteLoadBalancerTlsCertificateInput { + s.Force = &v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *DeleteLoadBalancerTlsCertificateInput) SetLoadBalancerName(v string) *DeleteLoadBalancerTlsCertificateInput { + s.LoadBalancerName = &v + return s +} + +type DeleteLoadBalancerTlsCertificateOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteLoadBalancerTlsCertificateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteLoadBalancerTlsCertificateOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteLoadBalancerTlsCertificateOutput) SetOperations(v []*Operation) *DeleteLoadBalancerTlsCertificateOutput { + s.Operations = v + return s +} + +type DeleteRelationalDatabaseInput struct { + _ struct{} `type:"structure"` + + // The name of the database snapshot created if skip final snapshot is false, + // which is the default value for that parameter. + // + // Specifying this parameter and also specifying the skip final snapshot parameter + // to true results in an error. + // + // Constraints: + // + // * Must contain from 2 to 255 alphanumeric characters, or hyphens. + // + // * The first and last character must be a letter or number. + FinalRelationalDatabaseSnapshotName *string `locationName:"finalRelationalDatabaseSnapshotName" type:"string"` + + // The name of the database that you are deleting. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` + + // Determines whether a final database snapshot is created before your database + // is deleted. If true is specified, no database snapshot is created. If false + // is specified, a database snapshot is created before your database is deleted. + // + // You must specify the final relational database snapshot name parameter if + // the skip final snapshot parameter is false. + // + // Default: false + SkipFinalSnapshot *bool `locationName:"skipFinalSnapshot" type:"boolean"` +} + +// String returns the string representation +func (s DeleteRelationalDatabaseInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRelationalDatabaseInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteRelationalDatabaseInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteRelationalDatabaseInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetFinalRelationalDatabaseSnapshotName sets the FinalRelationalDatabaseSnapshotName field's value. +func (s *DeleteRelationalDatabaseInput) SetFinalRelationalDatabaseSnapshotName(v string) *DeleteRelationalDatabaseInput { + s.FinalRelationalDatabaseSnapshotName = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *DeleteRelationalDatabaseInput) SetRelationalDatabaseName(v string) *DeleteRelationalDatabaseInput { + s.RelationalDatabaseName = &v + return s +} + +// SetSkipFinalSnapshot sets the SkipFinalSnapshot field's value. +func (s *DeleteRelationalDatabaseInput) SetSkipFinalSnapshot(v bool) *DeleteRelationalDatabaseInput { + s.SkipFinalSnapshot = &v + return s +} + +type DeleteRelationalDatabaseOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your delete relational database request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteRelationalDatabaseOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRelationalDatabaseOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteRelationalDatabaseOutput) SetOperations(v []*Operation) *DeleteRelationalDatabaseOutput { + s.Operations = v + return s +} + +type DeleteRelationalDatabaseSnapshotInput struct { + _ struct{} `type:"structure"` + + // The name of the database snapshot that you are deleting. + // + // RelationalDatabaseSnapshotName is a required field + RelationalDatabaseSnapshotName *string `locationName:"relationalDatabaseSnapshotName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteRelationalDatabaseSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRelationalDatabaseSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteRelationalDatabaseSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteRelationalDatabaseSnapshotInput"} + if s.RelationalDatabaseSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRelationalDatabaseSnapshotName sets the RelationalDatabaseSnapshotName field's value. +func (s *DeleteRelationalDatabaseSnapshotInput) SetRelationalDatabaseSnapshotName(v string) *DeleteRelationalDatabaseSnapshotInput { + s.RelationalDatabaseSnapshotName = &v + return s +} + +type DeleteRelationalDatabaseSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your delete relational database snapshot + // request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DeleteRelationalDatabaseSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteRelationalDatabaseSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DeleteRelationalDatabaseSnapshotOutput) SetOperations(v []*Operation) *DeleteRelationalDatabaseSnapshotOutput { + s.Operations = v + return s +} + +// Describes the destination of a record. +type DestinationInfo struct { + _ struct{} `type:"structure"` + + // The ID of the resource created at the destination. + Id *string `locationName:"id" type:"string"` + + // The destination service of the record. + Service *string `locationName:"service" type:"string"` +} + +// String returns the string representation +func (s DestinationInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DestinationInfo) GoString() string { + return s.String() +} + +// SetId sets the Id field's value. +func (s *DestinationInfo) SetId(v string) *DestinationInfo { + s.Id = &v + return s +} + +// SetService sets the Service field's value. +func (s *DestinationInfo) SetService(v string) *DestinationInfo { + s.Service = &v + return s +} + +type DetachDiskInput struct { + _ struct{} `type:"structure"` + + // The unique name of the disk you want to detach from your instance (e.g., + // my-disk). + // + // DiskName is a required field + DiskName *string `locationName:"diskName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DetachDiskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachDiskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DetachDiskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DetachDiskInput"} + if s.DiskName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDiskName sets the DiskName field's value. +func (s *DetachDiskInput) SetDiskName(v string) *DetachDiskInput { + s.DiskName = &v + return s +} + +type DetachDiskOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DetachDiskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachDiskOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DetachDiskOutput) SetOperations(v []*Operation) *DetachDiskOutput { + s.Operations = v + return s +} + +type DetachInstancesFromLoadBalancerInput struct { + _ struct{} `type:"structure"` + + // An array of strings containing the names of the instances you want to detach + // from the load balancer. + // + // InstanceNames is a required field + InstanceNames []*string `locationName:"instanceNames" type:"list" required:"true"` + + // The name of the Lightsail load balancer. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DetachInstancesFromLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachInstancesFromLoadBalancerInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DetachInstancesFromLoadBalancerInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DetachInstancesFromLoadBalancerInput"} + if s.InstanceNames == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceNames")) + } + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceNames sets the InstanceNames field's value. +func (s *DetachInstancesFromLoadBalancerInput) SetInstanceNames(v []*string) *DetachInstancesFromLoadBalancerInput { + s.InstanceNames = v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *DetachInstancesFromLoadBalancerInput) SetLoadBalancerName(v string) *DetachInstancesFromLoadBalancerInput { + s.LoadBalancerName = &v + return s +} + +type DetachInstancesFromLoadBalancerOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DetachInstancesFromLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachInstancesFromLoadBalancerOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DetachInstancesFromLoadBalancerOutput) SetOperations(v []*Operation) *DetachInstancesFromLoadBalancerOutput { + s.Operations = v + return s +} + +type DetachStaticIpInput struct { + _ struct{} `type:"structure"` + + // The name of the static IP to detach from the instance. + // + // StaticIpName is a required field + StaticIpName *string `locationName:"staticIpName" type:"string" required:"true"` +} + +// String returns the string representation +func (s DetachStaticIpInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachStaticIpInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DetachStaticIpInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DetachStaticIpInput"} + if s.StaticIpName == nil { + invalidParams.Add(request.NewErrParamRequired("StaticIpName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetStaticIpName sets the StaticIpName field's value. +func (s *DetachStaticIpInput) SetStaticIpName(v string) *DetachStaticIpInput { + s.StaticIpName = &v + return s +} + +type DetachStaticIpOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // detach static IP request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s DetachStaticIpOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DetachStaticIpOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *DetachStaticIpOutput) SetOperations(v []*Operation) *DetachStaticIpOutput { + s.Operations = v + return s +} + +// Describes a system disk or an block storage disk. +type Disk struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the disk. + Arn *string `locationName:"arn" type:"string"` + + // The resources to which the disk is attached. + AttachedTo *string `locationName:"attachedTo" type:"string"` + + // (Deprecated) The attachment state of the disk. + // + // In releases prior to November 14, 2017, this parameter returned attached + // for system disks in the API response. It is now deprecated, but still included + // in the response. Use isAttached instead. + // + // Deprecated: AttachmentState has been deprecated + AttachmentState *string `locationName:"attachmentState" deprecated:"true" type:"string"` + + // The date when the disk was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // (Deprecated) The number of GB in use by the disk. + // + // In releases prior to November 14, 2017, this parameter was not included in + // the API response. It is now deprecated. + // + // Deprecated: GbInUse has been deprecated + GbInUse *int64 `locationName:"gbInUse" deprecated:"true" type:"integer"` + + // The input/output operations per second (IOPS) of the disk. + Iops *int64 `locationName:"iops" type:"integer"` + + // A Boolean value indicating whether the disk is attached. + IsAttached *bool `locationName:"isAttached" type:"boolean"` + + // A Boolean value indicating whether this disk is a system disk (has an operating + // system loaded on it). + IsSystemDisk *bool `locationName:"isSystemDisk" type:"boolean"` + + // The AWS Region and Availability Zone where the disk is located. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The unique name of the disk. + Name *string `locationName:"name" type:"string"` + + // The disk path. + Path *string `locationName:"path" type:"string"` + + // The Lightsail resource type (e.g., Disk). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The size of the disk in GB. + SizeInGb *int64 `locationName:"sizeInGb" type:"integer"` + + // Describes the status of the disk. + State *string `locationName:"state" type:"string" enum:"DiskState"` + + // The support code. Include this code in your email to support when you have + // questions about an instance or another resource in Lightsail. This code enables + // our support team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s Disk) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Disk) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *Disk) SetArn(v string) *Disk { + s.Arn = &v + return s +} + +// SetAttachedTo sets the AttachedTo field's value. +func (s *Disk) SetAttachedTo(v string) *Disk { + s.AttachedTo = &v + return s +} + +// SetAttachmentState sets the AttachmentState field's value. +func (s *Disk) SetAttachmentState(v string) *Disk { + s.AttachmentState = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *Disk) SetCreatedAt(v time.Time) *Disk { + s.CreatedAt = &v + return s +} + +// SetGbInUse sets the GbInUse field's value. +func (s *Disk) SetGbInUse(v int64) *Disk { + s.GbInUse = &v + return s +} + +// SetIops sets the Iops field's value. +func (s *Disk) SetIops(v int64) *Disk { + s.Iops = &v + return s +} + +// SetIsAttached sets the IsAttached field's value. +func (s *Disk) SetIsAttached(v bool) *Disk { + s.IsAttached = &v + return s +} + +// SetIsSystemDisk sets the IsSystemDisk field's value. +func (s *Disk) SetIsSystemDisk(v bool) *Disk { + s.IsSystemDisk = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *Disk) SetLocation(v *ResourceLocation) *Disk { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *Disk) SetName(v string) *Disk { + s.Name = &v + return s +} + +// SetPath sets the Path field's value. +func (s *Disk) SetPath(v string) *Disk { + s.Path = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *Disk) SetResourceType(v string) *Disk { + s.ResourceType = &v + return s +} + +// SetSizeInGb sets the SizeInGb field's value. +func (s *Disk) SetSizeInGb(v int64) *Disk { + s.SizeInGb = &v + return s +} + +// SetState sets the State field's value. +func (s *Disk) SetState(v string) *Disk { + s.State = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *Disk) SetSupportCode(v string) *Disk { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *Disk) SetTags(v []*Tag) *Disk { + s.Tags = v + return s +} + +// Describes a disk. +type DiskInfo struct { + _ struct{} `type:"structure"` + + // A Boolean value indicating whether this disk is a system disk (has an operating + // system loaded on it). + IsSystemDisk *bool `locationName:"isSystemDisk" type:"boolean"` + + // The disk name. + Name *string `locationName:"name" type:"string"` + + // The disk path. + Path *string `locationName:"path" type:"string"` + + // The size of the disk in GB (e.g., 32). + SizeInGb *int64 `locationName:"sizeInGb" type:"integer"` +} + +// String returns the string representation +func (s DiskInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskInfo) GoString() string { + return s.String() +} + +// SetIsSystemDisk sets the IsSystemDisk field's value. +func (s *DiskInfo) SetIsSystemDisk(v bool) *DiskInfo { + s.IsSystemDisk = &v + return s +} + +// SetName sets the Name field's value. +func (s *DiskInfo) SetName(v string) *DiskInfo { + s.Name = &v + return s +} + +// SetPath sets the Path field's value. +func (s *DiskInfo) SetPath(v string) *DiskInfo { + s.Path = &v + return s +} + +// SetSizeInGb sets the SizeInGb field's value. +func (s *DiskInfo) SetSizeInGb(v int64) *DiskInfo { + s.SizeInGb = &v + return s +} + +// Describes a block storage disk mapping. +type DiskMap struct { + _ struct{} `type:"structure"` + + // The new disk name (e.g., my-new-disk). + NewDiskName *string `locationName:"newDiskName" type:"string"` + + // The original disk path exposed to the instance (for example, /dev/sdh). + OriginalDiskPath *string `locationName:"originalDiskPath" type:"string"` +} + +// String returns the string representation +func (s DiskMap) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskMap) GoString() string { + return s.String() +} + +// SetNewDiskName sets the NewDiskName field's value. +func (s *DiskMap) SetNewDiskName(v string) *DiskMap { + s.NewDiskName = &v + return s +} + +// SetOriginalDiskPath sets the OriginalDiskPath field's value. +func (s *DiskMap) SetOriginalDiskPath(v string) *DiskMap { + s.OriginalDiskPath = &v + return s +} + +// Describes a block storage disk snapshot. +type DiskSnapshot struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the disk snapshot. + Arn *string `locationName:"arn" type:"string"` + + // The date when the disk snapshot was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The Amazon Resource Name (ARN) of the source disk from which the disk snapshot + // was created. + FromDiskArn *string `locationName:"fromDiskArn" type:"string"` + + // The unique name of the source disk from which the disk snapshot was created. + FromDiskName *string `locationName:"fromDiskName" type:"string"` + + // The Amazon Resource Name (ARN) of the source instance from which the disk + // (system volume) snapshot was created. + FromInstanceArn *string `locationName:"fromInstanceArn" type:"string"` + + // The unique name of the source instance from which the disk (system volume) + // snapshot was created. + FromInstanceName *string `locationName:"fromInstanceName" type:"string"` + + // The AWS Region and Availability Zone where the disk snapshot was created. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the disk snapshot (e.g., my-disk-snapshot). + Name *string `locationName:"name" type:"string"` + + // The progress of the disk snapshot operation. + Progress *string `locationName:"progress" type:"string"` + + // The Lightsail resource type (e.g., DiskSnapshot). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The size of the disk in GB. + SizeInGb *int64 `locationName:"sizeInGb" type:"integer"` + + // The status of the disk snapshot operation. + State *string `locationName:"state" type:"string" enum:"DiskSnapshotState"` + + // The support code. Include this code in your email to support when you have + // questions about an instance or another resource in Lightsail. This code enables + // our support team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s DiskSnapshot) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskSnapshot) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *DiskSnapshot) SetArn(v string) *DiskSnapshot { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *DiskSnapshot) SetCreatedAt(v time.Time) *DiskSnapshot { + s.CreatedAt = &v + return s +} + +// SetFromDiskArn sets the FromDiskArn field's value. +func (s *DiskSnapshot) SetFromDiskArn(v string) *DiskSnapshot { + s.FromDiskArn = &v + return s +} + +// SetFromDiskName sets the FromDiskName field's value. +func (s *DiskSnapshot) SetFromDiskName(v string) *DiskSnapshot { + s.FromDiskName = &v + return s +} + +// SetFromInstanceArn sets the FromInstanceArn field's value. +func (s *DiskSnapshot) SetFromInstanceArn(v string) *DiskSnapshot { + s.FromInstanceArn = &v + return s +} + +// SetFromInstanceName sets the FromInstanceName field's value. +func (s *DiskSnapshot) SetFromInstanceName(v string) *DiskSnapshot { + s.FromInstanceName = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *DiskSnapshot) SetLocation(v *ResourceLocation) *DiskSnapshot { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *DiskSnapshot) SetName(v string) *DiskSnapshot { + s.Name = &v + return s +} + +// SetProgress sets the Progress field's value. +func (s *DiskSnapshot) SetProgress(v string) *DiskSnapshot { + s.Progress = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *DiskSnapshot) SetResourceType(v string) *DiskSnapshot { + s.ResourceType = &v + return s +} + +// SetSizeInGb sets the SizeInGb field's value. +func (s *DiskSnapshot) SetSizeInGb(v int64) *DiskSnapshot { + s.SizeInGb = &v + return s +} + +// SetState sets the State field's value. +func (s *DiskSnapshot) SetState(v string) *DiskSnapshot { + s.State = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *DiskSnapshot) SetSupportCode(v string) *DiskSnapshot { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *DiskSnapshot) SetTags(v []*Tag) *DiskSnapshot { + s.Tags = v + return s +} + +// Describes a disk snapshot. +type DiskSnapshotInfo struct { + _ struct{} `type:"structure"` + + // The size of the disk in GB (e.g., 32). + SizeInGb *int64 `locationName:"sizeInGb" type:"integer"` +} + +// String returns the string representation +func (s DiskSnapshotInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DiskSnapshotInfo) GoString() string { + return s.String() +} + +// SetSizeInGb sets the SizeInGb field's value. +func (s *DiskSnapshotInfo) SetSizeInGb(v int64) *DiskSnapshotInfo { + s.SizeInGb = &v + return s +} + +// Describes a domain where you are storing recordsets in Lightsail. +type Domain struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the domain recordset (e.g., arn:aws:lightsail:global:123456789101:Domain/824cede0-abc7-4f84-8dbc-12345EXAMPLE). + Arn *string `locationName:"arn" type:"string"` + + // The date when the domain recordset was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // An array of key-value pairs containing information about the domain entries. + DomainEntries []*DomainEntry `locationName:"domainEntries" type:"list"` + + // The AWS Region and Availability Zones where the domain recordset was created. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the domain. + Name *string `locationName:"name" type:"string"` + + // The resource type. + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The support code. Include this code in your email to support when you have + // questions about an instance or another resource in Lightsail. This code enables + // our support team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s Domain) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Domain) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *Domain) SetArn(v string) *Domain { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *Domain) SetCreatedAt(v time.Time) *Domain { + s.CreatedAt = &v + return s +} + +// SetDomainEntries sets the DomainEntries field's value. +func (s *Domain) SetDomainEntries(v []*DomainEntry) *Domain { + s.DomainEntries = v + return s +} + +// SetLocation sets the Location field's value. +func (s *Domain) SetLocation(v *ResourceLocation) *Domain { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *Domain) SetName(v string) *Domain { + s.Name = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *Domain) SetResourceType(v string) *Domain { + s.ResourceType = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *Domain) SetSupportCode(v string) *Domain { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *Domain) SetTags(v []*Tag) *Domain { + s.Tags = v + return s +} + +// Describes a domain recordset entry. +type DomainEntry struct { + _ struct{} `type:"structure"` + + // The ID of the domain recordset entry. + Id *string `locationName:"id" type:"string"` + + // When true, specifies whether the domain entry is an alias used by the Lightsail + // load balancer. You can include an alias (A type) record in your request, + // which points to a load balancer DNS name and routes traffic to your load + // balancer + IsAlias *bool `locationName:"isAlias" type:"boolean"` + + // The name of the domain. + Name *string `locationName:"name" type:"string"` + + // (Deprecated) The options for the domain entry. + // + // In releases prior to November 29, 2017, this parameter was not included in + // the API response. It is now deprecated. + // + // Deprecated: Options has been deprecated + Options map[string]*string `locationName:"options" deprecated:"true" type:"map"` + + // The target AWS name server (e.g., ns-111.awsdns-22.com.). + // + // For Lightsail load balancers, the value looks like ab1234c56789c6b86aba6fb203d443bc-123456789.us-east-2.elb.amazonaws.com. + // Be sure to also set isAlias to true when setting up an A record for a load + // balancer. + Target *string `locationName:"target" type:"string"` + + // The type of domain entry, such as address (A), canonical name (CNAME), mail + // exchanger (MX), name server (NS), start of authority (SOA), service locator + // (SRV), or text (TXT). + // + // The following domain entry types can be used: + // + // * A + // + // * CNAME + // + // * MX + // + // * NS + // + // * SOA + // + // * SRV + // + // * TXT + Type *string `locationName:"type" type:"string"` +} + +// String returns the string representation +func (s DomainEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DomainEntry) GoString() string { + return s.String() +} + +// SetId sets the Id field's value. +func (s *DomainEntry) SetId(v string) *DomainEntry { + s.Id = &v + return s +} + +// SetIsAlias sets the IsAlias field's value. +func (s *DomainEntry) SetIsAlias(v bool) *DomainEntry { + s.IsAlias = &v + return s +} + +// SetName sets the Name field's value. +func (s *DomainEntry) SetName(v string) *DomainEntry { + s.Name = &v + return s +} + +// SetOptions sets the Options field's value. +func (s *DomainEntry) SetOptions(v map[string]*string) *DomainEntry { + s.Options = v + return s +} + +// SetTarget sets the Target field's value. +func (s *DomainEntry) SetTarget(v string) *DomainEntry { + s.Target = &v + return s +} + +// SetType sets the Type field's value. +func (s *DomainEntry) SetType(v string) *DomainEntry { + s.Type = &v + return s +} + +type DownloadDefaultKeyPairInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DownloadDefaultKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DownloadDefaultKeyPairInput) GoString() string { + return s.String() +} + +type DownloadDefaultKeyPairOutput struct { + _ struct{} `type:"structure"` + + // A base64-encoded RSA private key. + PrivateKeyBase64 *string `locationName:"privateKeyBase64" type:"string"` + + // A base64-encoded public key of the ssh-rsa type. + PublicKeyBase64 *string `locationName:"publicKeyBase64" type:"string"` +} + +// String returns the string representation +func (s DownloadDefaultKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DownloadDefaultKeyPairOutput) GoString() string { + return s.String() +} + +// SetPrivateKeyBase64 sets the PrivateKeyBase64 field's value. +func (s *DownloadDefaultKeyPairOutput) SetPrivateKeyBase64(v string) *DownloadDefaultKeyPairOutput { + s.PrivateKeyBase64 = &v + return s +} + +// SetPublicKeyBase64 sets the PublicKeyBase64 field's value. +func (s *DownloadDefaultKeyPairOutput) SetPublicKeyBase64(v string) *DownloadDefaultKeyPairOutput { + s.PublicKeyBase64 = &v + return s +} + +type ExportSnapshotInput struct { + _ struct{} `type:"structure"` + + // The name of the instance or disk snapshot to be exported to Amazon EC2. + // + // SourceSnapshotName is a required field + SourceSnapshotName *string `locationName:"sourceSnapshotName" type:"string" required:"true"` +} + +// String returns the string representation +func (s ExportSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ExportSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ExportSnapshotInput"} + if s.SourceSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("SourceSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetSourceSnapshotName sets the SourceSnapshotName field's value. +func (s *ExportSnapshotInput) SetSourceSnapshotName(v string) *ExportSnapshotInput { + s.SourceSnapshotName = &v + return s +} + +type ExportSnapshotOutput struct { + _ struct{} `type:"structure"` + + // A list of objects describing the API operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s ExportSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportSnapshotOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *ExportSnapshotOutput) SetOperations(v []*Operation) *ExportSnapshotOutput { + s.Operations = v + return s +} + +// Describes an export snapshot record. +type ExportSnapshotRecord struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the export snapshot record. + Arn *string `locationName:"arn" type:"string"` + + // The date when the export snapshot record was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // A list of objects describing the destination of the export snapshot record. + DestinationInfo *DestinationInfo `locationName:"destinationInfo" type:"structure"` + + // The AWS Region and Availability Zone where the export snapshot record is + // located. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The export snapshot record name. + Name *string `locationName:"name" type:"string"` + + // The Lightsail resource type (e.g., ExportSnapshotRecord). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // A list of objects describing the source of the export snapshot record. + SourceInfo *ExportSnapshotRecordSourceInfo `locationName:"sourceInfo" type:"structure"` + + // The state of the export snapshot record. + State *string `locationName:"state" type:"string" enum:"RecordState"` +} + +// String returns the string representation +func (s ExportSnapshotRecord) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportSnapshotRecord) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *ExportSnapshotRecord) SetArn(v string) *ExportSnapshotRecord { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *ExportSnapshotRecord) SetCreatedAt(v time.Time) *ExportSnapshotRecord { + s.CreatedAt = &v + return s +} + +// SetDestinationInfo sets the DestinationInfo field's value. +func (s *ExportSnapshotRecord) SetDestinationInfo(v *DestinationInfo) *ExportSnapshotRecord { + s.DestinationInfo = v + return s +} + +// SetLocation sets the Location field's value. +func (s *ExportSnapshotRecord) SetLocation(v *ResourceLocation) *ExportSnapshotRecord { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *ExportSnapshotRecord) SetName(v string) *ExportSnapshotRecord { + s.Name = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *ExportSnapshotRecord) SetResourceType(v string) *ExportSnapshotRecord { + s.ResourceType = &v + return s +} + +// SetSourceInfo sets the SourceInfo field's value. +func (s *ExportSnapshotRecord) SetSourceInfo(v *ExportSnapshotRecordSourceInfo) *ExportSnapshotRecord { + s.SourceInfo = v + return s +} + +// SetState sets the State field's value. +func (s *ExportSnapshotRecord) SetState(v string) *ExportSnapshotRecord { + s.State = &v + return s +} + +// Describes the source of an export snapshot record. +type ExportSnapshotRecordSourceInfo struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the source instance or disk snapshot. + Arn *string `locationName:"arn" type:"string"` + + // The date when the source instance or disk snapshot was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // A list of objects describing a disk snapshot. + DiskSnapshotInfo *DiskSnapshotInfo `locationName:"diskSnapshotInfo" type:"structure"` + + // The Amazon Resource Name (ARN) of the snapshot's source instance or disk. + FromResourceArn *string `locationName:"fromResourceArn" type:"string"` + + // The name of the snapshot's source instance or disk. + FromResourceName *string `locationName:"fromResourceName" type:"string"` + + // A list of objects describing an instance snapshot. + InstanceSnapshotInfo *InstanceSnapshotInfo `locationName:"instanceSnapshotInfo" type:"structure"` + + // The name of the source instance or disk snapshot. + Name *string `locationName:"name" type:"string"` + + // The Lightsail resource type (e.g., InstanceSnapshot or DiskSnapshot). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ExportSnapshotRecordSourceType"` +} + +// String returns the string representation +func (s ExportSnapshotRecordSourceInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ExportSnapshotRecordSourceInfo) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *ExportSnapshotRecordSourceInfo) SetArn(v string) *ExportSnapshotRecordSourceInfo { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *ExportSnapshotRecordSourceInfo) SetCreatedAt(v time.Time) *ExportSnapshotRecordSourceInfo { + s.CreatedAt = &v + return s +} + +// SetDiskSnapshotInfo sets the DiskSnapshotInfo field's value. +func (s *ExportSnapshotRecordSourceInfo) SetDiskSnapshotInfo(v *DiskSnapshotInfo) *ExportSnapshotRecordSourceInfo { + s.DiskSnapshotInfo = v + return s +} + +// SetFromResourceArn sets the FromResourceArn field's value. +func (s *ExportSnapshotRecordSourceInfo) SetFromResourceArn(v string) *ExportSnapshotRecordSourceInfo { + s.FromResourceArn = &v + return s +} + +// SetFromResourceName sets the FromResourceName field's value. +func (s *ExportSnapshotRecordSourceInfo) SetFromResourceName(v string) *ExportSnapshotRecordSourceInfo { + s.FromResourceName = &v + return s +} + +// SetInstanceSnapshotInfo sets the InstanceSnapshotInfo field's value. +func (s *ExportSnapshotRecordSourceInfo) SetInstanceSnapshotInfo(v *InstanceSnapshotInfo) *ExportSnapshotRecordSourceInfo { + s.InstanceSnapshotInfo = v + return s +} + +// SetName sets the Name field's value. +func (s *ExportSnapshotRecordSourceInfo) SetName(v string) *ExportSnapshotRecordSourceInfo { + s.Name = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *ExportSnapshotRecordSourceInfo) SetResourceType(v string) *ExportSnapshotRecordSourceInfo { + s.ResourceType = &v + return s +} + +type GetActiveNamesInput struct { + _ struct{} `type:"structure"` + + // A token used for paginating results from your get active names request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetActiveNamesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetActiveNamesInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetActiveNamesInput) SetPageToken(v string) *GetActiveNamesInput { + s.PageToken = &v + return s +} + +type GetActiveNamesOutput struct { + _ struct{} `type:"structure"` + + // The list of active names returned by the get active names request. + ActiveNames []*string `locationName:"activeNames" type:"list"` + + // A token used for advancing to the next page of results from your get active + // names request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetActiveNamesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetActiveNamesOutput) GoString() string { + return s.String() +} + +// SetActiveNames sets the ActiveNames field's value. +func (s *GetActiveNamesOutput) SetActiveNames(v []*string) *GetActiveNamesOutput { + s.ActiveNames = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetActiveNamesOutput) SetNextPageToken(v string) *GetActiveNamesOutput { + s.NextPageToken = &v + return s +} + +type GetBlueprintsInput struct { + _ struct{} `type:"structure"` + + // A Boolean value indicating whether to include inactive results in your request. + IncludeInactive *bool `locationName:"includeInactive" type:"boolean"` + + // A token used for advancing to the next page of results from your get blueprints + // request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetBlueprintsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetBlueprintsInput) GoString() string { + return s.String() +} + +// SetIncludeInactive sets the IncludeInactive field's value. +func (s *GetBlueprintsInput) SetIncludeInactive(v bool) *GetBlueprintsInput { + s.IncludeInactive = &v + return s +} + +// SetPageToken sets the PageToken field's value. +func (s *GetBlueprintsInput) SetPageToken(v string) *GetBlueprintsInput { + s.PageToken = &v + return s +} + +type GetBlueprintsOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs that contains information about the available + // blueprints. + Blueprints []*Blueprint `locationName:"blueprints" type:"list"` + + // A token used for advancing to the next page of results from your get blueprints + // request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetBlueprintsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetBlueprintsOutput) GoString() string { + return s.String() +} + +// SetBlueprints sets the Blueprints field's value. +func (s *GetBlueprintsOutput) SetBlueprints(v []*Blueprint) *GetBlueprintsOutput { + s.Blueprints = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetBlueprintsOutput) SetNextPageToken(v string) *GetBlueprintsOutput { + s.NextPageToken = &v + return s +} + +type GetBundlesInput struct { + _ struct{} `type:"structure"` + + // A Boolean value that indicates whether to include inactive bundle results + // in your request. + IncludeInactive *bool `locationName:"includeInactive" type:"boolean"` + + // A token used for advancing to the next page of results from your get bundles + // request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetBundlesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetBundlesInput) GoString() string { + return s.String() +} + +// SetIncludeInactive sets the IncludeInactive field's value. +func (s *GetBundlesInput) SetIncludeInactive(v bool) *GetBundlesInput { + s.IncludeInactive = &v + return s +} + +// SetPageToken sets the PageToken field's value. +func (s *GetBundlesInput) SetPageToken(v string) *GetBundlesInput { + s.PageToken = &v + return s +} + +type GetBundlesOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs that contains information about the available + // bundles. + Bundles []*Bundle `locationName:"bundles" type:"list"` + + // A token used for advancing to the next page of results from your get active + // names request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetBundlesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetBundlesOutput) GoString() string { + return s.String() +} + +// SetBundles sets the Bundles field's value. +func (s *GetBundlesOutput) SetBundles(v []*Bundle) *GetBundlesOutput { + s.Bundles = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetBundlesOutput) SetNextPageToken(v string) *GetBundlesOutput { + s.NextPageToken = &v + return s +} + +type GetCloudFormationStackRecordsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to a specific page of results for your get cloud + // formation stack records request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetCloudFormationStackRecordsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCloudFormationStackRecordsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetCloudFormationStackRecordsInput) SetPageToken(v string) *GetCloudFormationStackRecordsInput { + s.PageToken = &v + return s +} + +type GetCloudFormationStackRecordsOutput struct { + _ struct{} `type:"structure"` + + // A list of objects describing the CloudFormation stack records. + CloudFormationStackRecords []*CloudFormationStackRecord `locationName:"cloudFormationStackRecords" type:"list"` + + // A token used for advancing to the next page of results of your get relational + // database bundles request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetCloudFormationStackRecordsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCloudFormationStackRecordsOutput) GoString() string { + return s.String() +} + +// SetCloudFormationStackRecords sets the CloudFormationStackRecords field's value. +func (s *GetCloudFormationStackRecordsOutput) SetCloudFormationStackRecords(v []*CloudFormationStackRecord) *GetCloudFormationStackRecordsOutput { + s.CloudFormationStackRecords = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetCloudFormationStackRecordsOutput) SetNextPageToken(v string) *GetCloudFormationStackRecordsOutput { + s.NextPageToken = &v + return s +} + +type GetDiskInput struct { + _ struct{} `type:"structure"` + + // The name of the disk (e.g., my-disk). + // + // DiskName is a required field + DiskName *string `locationName:"diskName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetDiskInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDiskInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetDiskInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetDiskInput"} + if s.DiskName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDiskName sets the DiskName field's value. +func (s *GetDiskInput) SetDiskName(v string) *GetDiskInput { + s.DiskName = &v + return s +} + +type GetDiskOutput struct { + _ struct{} `type:"structure"` + + // An object containing information about the disk. + Disk *Disk `locationName:"disk" type:"structure"` +} + +// String returns the string representation +func (s GetDiskOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDiskOutput) GoString() string { + return s.String() +} + +// SetDisk sets the Disk field's value. +func (s *GetDiskOutput) SetDisk(v *Disk) *GetDiskOutput { + s.Disk = v + return s +} + +type GetDiskSnapshotInput struct { + _ struct{} `type:"structure"` + + // The name of the disk snapshot (e.g., my-disk-snapshot). + // + // DiskSnapshotName is a required field + DiskSnapshotName *string `locationName:"diskSnapshotName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetDiskSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDiskSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetDiskSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetDiskSnapshotInput"} + if s.DiskSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("DiskSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDiskSnapshotName sets the DiskSnapshotName field's value. +func (s *GetDiskSnapshotInput) SetDiskSnapshotName(v string) *GetDiskSnapshotInput { + s.DiskSnapshotName = &v + return s +} + +type GetDiskSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An object containing information about the disk snapshot. + DiskSnapshot *DiskSnapshot `locationName:"diskSnapshot" type:"structure"` +} + +// String returns the string representation +func (s GetDiskSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDiskSnapshotOutput) GoString() string { + return s.String() +} + +// SetDiskSnapshot sets the DiskSnapshot field's value. +func (s *GetDiskSnapshotOutput) SetDiskSnapshot(v *DiskSnapshot) *GetDiskSnapshotOutput { + s.DiskSnapshot = v + return s +} + +type GetDiskSnapshotsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your GetDiskSnapshots + // request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetDiskSnapshotsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDiskSnapshotsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetDiskSnapshotsInput) SetPageToken(v string) *GetDiskSnapshotsInput { + s.PageToken = &v + return s +} + +type GetDiskSnapshotsOutput struct { + _ struct{} `type:"structure"` + + // An array of objects containing information about all block storage disk snapshots. + DiskSnapshots []*DiskSnapshot `locationName:"diskSnapshots" type:"list"` + + // A token used for advancing to the next page of results from your GetDiskSnapshots + // request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetDiskSnapshotsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDiskSnapshotsOutput) GoString() string { + return s.String() +} + +// SetDiskSnapshots sets the DiskSnapshots field's value. +func (s *GetDiskSnapshotsOutput) SetDiskSnapshots(v []*DiskSnapshot) *GetDiskSnapshotsOutput { + s.DiskSnapshots = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetDiskSnapshotsOutput) SetNextPageToken(v string) *GetDiskSnapshotsOutput { + s.NextPageToken = &v + return s +} + +type GetDisksInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your GetDisks + // request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetDisksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDisksInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetDisksInput) SetPageToken(v string) *GetDisksInput { + s.PageToken = &v + return s +} + +type GetDisksOutput struct { + _ struct{} `type:"structure"` + + // An array of objects containing information about all block storage disks. + Disks []*Disk `locationName:"disks" type:"list"` + + // A token used for advancing to the next page of results from your GetDisks + // request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetDisksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDisksOutput) GoString() string { + return s.String() +} + +// SetDisks sets the Disks field's value. +func (s *GetDisksOutput) SetDisks(v []*Disk) *GetDisksOutput { + s.Disks = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetDisksOutput) SetNextPageToken(v string) *GetDisksOutput { + s.NextPageToken = &v + return s +} + +type GetDomainInput struct { + _ struct{} `type:"structure"` + + // The domain name for which your want to return information about. + // + // DomainName is a required field + DomainName *string `locationName:"domainName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetDomainInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDomainInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetDomainInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetDomainInput"} + if s.DomainName == nil { + invalidParams.Add(request.NewErrParamRequired("DomainName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDomainName sets the DomainName field's value. +func (s *GetDomainInput) SetDomainName(v string) *GetDomainInput { + s.DomainName = &v + return s +} + +type GetDomainOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about your get domain + // request. + Domain *Domain `locationName:"domain" type:"structure"` +} + +// String returns the string representation +func (s GetDomainOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDomainOutput) GoString() string { + return s.String() +} + +// SetDomain sets the Domain field's value. +func (s *GetDomainOutput) SetDomain(v *Domain) *GetDomainOutput { + s.Domain = v + return s +} + +type GetDomainsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get domains + // request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetDomainsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDomainsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetDomainsInput) SetPageToken(v string) *GetDomainsInput { + s.PageToken = &v + return s +} + +type GetDomainsOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about each of the domain + // entries in the user's account. + Domains []*Domain `locationName:"domains" type:"list"` + + // A token used for advancing to the next page of results from your get active + // names request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetDomainsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetDomainsOutput) GoString() string { + return s.String() +} + +// SetDomains sets the Domains field's value. +func (s *GetDomainsOutput) SetDomains(v []*Domain) *GetDomainsOutput { + s.Domains = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetDomainsOutput) SetNextPageToken(v string) *GetDomainsOutput { + s.NextPageToken = &v + return s +} + +type GetExportSnapshotRecordsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to a specific page of results for your get export + // snapshot records request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetExportSnapshotRecordsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetExportSnapshotRecordsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetExportSnapshotRecordsInput) SetPageToken(v string) *GetExportSnapshotRecordsInput { + s.PageToken = &v + return s +} + +type GetExportSnapshotRecordsOutput struct { + _ struct{} `type:"structure"` + + // A list of objects describing the export snapshot records. + ExportSnapshotRecords []*ExportSnapshotRecord `locationName:"exportSnapshotRecords" type:"list"` + + // A token used for advancing to the next page of results of your get relational + // database bundles request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetExportSnapshotRecordsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetExportSnapshotRecordsOutput) GoString() string { + return s.String() +} + +// SetExportSnapshotRecords sets the ExportSnapshotRecords field's value. +func (s *GetExportSnapshotRecordsOutput) SetExportSnapshotRecords(v []*ExportSnapshotRecord) *GetExportSnapshotRecordsOutput { + s.ExportSnapshotRecords = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetExportSnapshotRecordsOutput) SetNextPageToken(v string) *GetExportSnapshotRecordsOutput { + s.NextPageToken = &v + return s +} + +type GetInstanceAccessDetailsInput struct { + _ struct{} `type:"structure"` + + // The name of the instance to access. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` + + // The protocol to use to connect to your instance. Defaults to ssh. + Protocol *string `locationName:"protocol" type:"string" enum:"InstanceAccessProtocol"` +} + +// String returns the string representation +func (s GetInstanceAccessDetailsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceAccessDetailsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetInstanceAccessDetailsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetInstanceAccessDetailsInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *GetInstanceAccessDetailsInput) SetInstanceName(v string) *GetInstanceAccessDetailsInput { + s.InstanceName = &v + return s +} + +// SetProtocol sets the Protocol field's value. +func (s *GetInstanceAccessDetailsInput) SetProtocol(v string) *GetInstanceAccessDetailsInput { + s.Protocol = &v + return s +} + +type GetInstanceAccessDetailsOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about a get instance access + // request. + AccessDetails *InstanceAccessDetails `locationName:"accessDetails" type:"structure"` +} + +// String returns the string representation +func (s GetInstanceAccessDetailsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceAccessDetailsOutput) GoString() string { + return s.String() +} + +// SetAccessDetails sets the AccessDetails field's value. +func (s *GetInstanceAccessDetailsOutput) SetAccessDetails(v *InstanceAccessDetails) *GetInstanceAccessDetailsOutput { + s.AccessDetails = v + return s +} + +type GetInstanceInput struct { + _ struct{} `type:"structure"` + + // The name of the instance. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetInstanceInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *GetInstanceInput) SetInstanceName(v string) *GetInstanceInput { + s.InstanceName = &v + return s +} + +type GetInstanceMetricDataInput struct { + _ struct{} `type:"structure"` + + // The end time of the time period. + // + // EndTime is a required field + EndTime *time.Time `locationName:"endTime" type:"timestamp" required:"true"` + + // The name of the instance for which you want to get metrics data. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` + + // The metric name to get data about. + // + // MetricName is a required field + MetricName *string `locationName:"metricName" type:"string" required:"true" enum:"InstanceMetricName"` + + // The granularity, in seconds, of the returned data points. + // + // Period is a required field + Period *int64 `locationName:"period" min:"60" type:"integer" required:"true"` + + // The start time of the time period. + // + // StartTime is a required field + StartTime *time.Time `locationName:"startTime" type:"timestamp" required:"true"` + + // The instance statistics. + // + // Statistics is a required field + Statistics []*string `locationName:"statistics" type:"list" required:"true"` + + // The unit. The list of valid values is below. + // + // Unit is a required field + Unit *string `locationName:"unit" type:"string" required:"true" enum:"MetricUnit"` +} + +// String returns the string representation +func (s GetInstanceMetricDataInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceMetricDataInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetInstanceMetricDataInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetInstanceMetricDataInput"} + if s.EndTime == nil { + invalidParams.Add(request.NewErrParamRequired("EndTime")) + } + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + if s.MetricName == nil { + invalidParams.Add(request.NewErrParamRequired("MetricName")) + } + if s.Period == nil { + invalidParams.Add(request.NewErrParamRequired("Period")) + } + if s.Period != nil && *s.Period < 60 { + invalidParams.Add(request.NewErrParamMinValue("Period", 60)) + } + if s.StartTime == nil { + invalidParams.Add(request.NewErrParamRequired("StartTime")) + } + if s.Statistics == nil { + invalidParams.Add(request.NewErrParamRequired("Statistics")) + } + if s.Unit == nil { + invalidParams.Add(request.NewErrParamRequired("Unit")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEndTime sets the EndTime field's value. +func (s *GetInstanceMetricDataInput) SetEndTime(v time.Time) *GetInstanceMetricDataInput { + s.EndTime = &v + return s +} + +// SetInstanceName sets the InstanceName field's value. +func (s *GetInstanceMetricDataInput) SetInstanceName(v string) *GetInstanceMetricDataInput { + s.InstanceName = &v + return s +} + +// SetMetricName sets the MetricName field's value. +func (s *GetInstanceMetricDataInput) SetMetricName(v string) *GetInstanceMetricDataInput { + s.MetricName = &v + return s +} + +// SetPeriod sets the Period field's value. +func (s *GetInstanceMetricDataInput) SetPeriod(v int64) *GetInstanceMetricDataInput { + s.Period = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *GetInstanceMetricDataInput) SetStartTime(v time.Time) *GetInstanceMetricDataInput { + s.StartTime = &v + return s +} + +// SetStatistics sets the Statistics field's value. +func (s *GetInstanceMetricDataInput) SetStatistics(v []*string) *GetInstanceMetricDataInput { + s.Statistics = v + return s +} + +// SetUnit sets the Unit field's value. +func (s *GetInstanceMetricDataInput) SetUnit(v string) *GetInstanceMetricDataInput { + s.Unit = &v + return s +} + +type GetInstanceMetricDataOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // get instance metric data request. + MetricData []*MetricDatapoint `locationName:"metricData" type:"list"` + + // The metric name to return data for. + MetricName *string `locationName:"metricName" type:"string" enum:"InstanceMetricName"` +} + +// String returns the string representation +func (s GetInstanceMetricDataOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceMetricDataOutput) GoString() string { + return s.String() +} + +// SetMetricData sets the MetricData field's value. +func (s *GetInstanceMetricDataOutput) SetMetricData(v []*MetricDatapoint) *GetInstanceMetricDataOutput { + s.MetricData = v + return s +} + +// SetMetricName sets the MetricName field's value. +func (s *GetInstanceMetricDataOutput) SetMetricName(v string) *GetInstanceMetricDataOutput { + s.MetricName = &v + return s +} + +type GetInstanceOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the specified instance. + Instance *Instance `locationName:"instance" type:"structure"` +} + +// String returns the string representation +func (s GetInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceOutput) GoString() string { + return s.String() +} + +// SetInstance sets the Instance field's value. +func (s *GetInstanceOutput) SetInstance(v *Instance) *GetInstanceOutput { + s.Instance = v + return s +} + +type GetInstancePortStatesInput struct { + _ struct{} `type:"structure"` + + // The name of the instance. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetInstancePortStatesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstancePortStatesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetInstancePortStatesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetInstancePortStatesInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *GetInstancePortStatesInput) SetInstanceName(v string) *GetInstancePortStatesInput { + s.InstanceName = &v + return s +} + +type GetInstancePortStatesOutput struct { + _ struct{} `type:"structure"` + + // Information about the port states resulting from your request. + PortStates []*InstancePortState `locationName:"portStates" type:"list"` +} + +// String returns the string representation +func (s GetInstancePortStatesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstancePortStatesOutput) GoString() string { + return s.String() +} + +// SetPortStates sets the PortStates field's value. +func (s *GetInstancePortStatesOutput) SetPortStates(v []*InstancePortState) *GetInstancePortStatesOutput { + s.PortStates = v + return s +} + +type GetInstanceSnapshotInput struct { + _ struct{} `type:"structure"` + + // The name of the snapshot for which you are requesting information. + // + // InstanceSnapshotName is a required field + InstanceSnapshotName *string `locationName:"instanceSnapshotName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetInstanceSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetInstanceSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetInstanceSnapshotInput"} + if s.InstanceSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceSnapshotName sets the InstanceSnapshotName field's value. +func (s *GetInstanceSnapshotInput) SetInstanceSnapshotName(v string) *GetInstanceSnapshotInput { + s.InstanceSnapshotName = &v + return s +} + +type GetInstanceSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // get instance snapshot request. + InstanceSnapshot *InstanceSnapshot `locationName:"instanceSnapshot" type:"structure"` +} + +// String returns the string representation +func (s GetInstanceSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceSnapshotOutput) GoString() string { + return s.String() +} + +// SetInstanceSnapshot sets the InstanceSnapshot field's value. +func (s *GetInstanceSnapshotOutput) SetInstanceSnapshot(v *InstanceSnapshot) *GetInstanceSnapshotOutput { + s.InstanceSnapshot = v + return s +} + +type GetInstanceSnapshotsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get instance + // snapshots request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetInstanceSnapshotsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceSnapshotsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetInstanceSnapshotsInput) SetPageToken(v string) *GetInstanceSnapshotsInput { + s.PageToken = &v + return s +} + +type GetInstanceSnapshotsOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // get instance snapshots request. + InstanceSnapshots []*InstanceSnapshot `locationName:"instanceSnapshots" type:"list"` + + // A token used for advancing to the next page of results from your get instance + // snapshots request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetInstanceSnapshotsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceSnapshotsOutput) GoString() string { + return s.String() +} + +// SetInstanceSnapshots sets the InstanceSnapshots field's value. +func (s *GetInstanceSnapshotsOutput) SetInstanceSnapshots(v []*InstanceSnapshot) *GetInstanceSnapshotsOutput { + s.InstanceSnapshots = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetInstanceSnapshotsOutput) SetNextPageToken(v string) *GetInstanceSnapshotsOutput { + s.NextPageToken = &v + return s +} + +type GetInstanceStateInput struct { + _ struct{} `type:"structure"` + + // The name of the instance to get state information about. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetInstanceStateInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceStateInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetInstanceStateInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetInstanceStateInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *GetInstanceStateInput) SetInstanceName(v string) *GetInstanceStateInput { + s.InstanceName = &v + return s +} + +type GetInstanceStateOutput struct { + _ struct{} `type:"structure"` + + // The state of the instance. + State *InstanceState `locationName:"state" type:"structure"` +} + +// String returns the string representation +func (s GetInstanceStateOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstanceStateOutput) GoString() string { + return s.String() +} + +// SetState sets the State field's value. +func (s *GetInstanceStateOutput) SetState(v *InstanceState) *GetInstanceStateOutput { + s.State = v + return s +} + +type GetInstancesInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get instances + // request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstancesInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetInstancesInput) SetPageToken(v string) *GetInstancesInput { + s.PageToken = &v + return s +} + +type GetInstancesOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about your instances. + Instances []*Instance `locationName:"instances" type:"list"` + + // A token used for advancing to the next page of results from your get instances + // request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetInstancesOutput) GoString() string { + return s.String() +} + +// SetInstances sets the Instances field's value. +func (s *GetInstancesOutput) SetInstances(v []*Instance) *GetInstancesOutput { + s.Instances = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetInstancesOutput) SetNextPageToken(v string) *GetInstancesOutput { + s.NextPageToken = &v + return s +} + +type GetKeyPairInput struct { + _ struct{} `type:"structure"` + + // The name of the key pair for which you are requesting information. + // + // KeyPairName is a required field + KeyPairName *string `locationName:"keyPairName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetKeyPairInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetKeyPairInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetKeyPairInput"} + if s.KeyPairName == nil { + invalidParams.Add(request.NewErrParamRequired("KeyPairName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKeyPairName sets the KeyPairName field's value. +func (s *GetKeyPairInput) SetKeyPairName(v string) *GetKeyPairInput { + s.KeyPairName = &v + return s +} + +type GetKeyPairOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the key pair. + KeyPair *KeyPair `locationName:"keyPair" type:"structure"` +} + +// String returns the string representation +func (s GetKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetKeyPairOutput) GoString() string { + return s.String() +} + +// SetKeyPair sets the KeyPair field's value. +func (s *GetKeyPairOutput) SetKeyPair(v *KeyPair) *GetKeyPairOutput { + s.KeyPair = v + return s +} + +type GetKeyPairsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get key + // pairs request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetKeyPairsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetKeyPairsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetKeyPairsInput) SetPageToken(v string) *GetKeyPairsInput { + s.PageToken = &v + return s +} + +type GetKeyPairsOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the key pairs. + KeyPairs []*KeyPair `locationName:"keyPairs" type:"list"` + + // A token used for advancing to the next page of results from your get key + // pairs request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetKeyPairsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetKeyPairsOutput) GoString() string { + return s.String() +} + +// SetKeyPairs sets the KeyPairs field's value. +func (s *GetKeyPairsOutput) SetKeyPairs(v []*KeyPair) *GetKeyPairsOutput { + s.KeyPairs = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetKeyPairsOutput) SetNextPageToken(v string) *GetKeyPairsOutput { + s.NextPageToken = &v + return s +} + +type GetLoadBalancerInput struct { + _ struct{} `type:"structure"` + + // The name of the load balancer. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetLoadBalancerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLoadBalancerInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetLoadBalancerInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetLoadBalancerInput"} + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *GetLoadBalancerInput) SetLoadBalancerName(v string) *GetLoadBalancerInput { + s.LoadBalancerName = &v + return s +} + +type GetLoadBalancerMetricDataInput struct { + _ struct{} `type:"structure"` + + // The end time of the period. + // + // EndTime is a required field + EndTime *time.Time `locationName:"endTime" type:"timestamp" required:"true"` + + // The name of the load balancer. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` + + // The metric about which you want to return information. Valid values are listed + // below, along with the most useful statistics to include in your request. + // + // * ClientTLSNegotiationErrorCount - The number of TLS connections initiated + // by the client that did not establish a session with the load balancer. + // Possible causes include a mismatch of ciphers or protocols. Statistics: + // The most useful statistic is Sum. + // + // * HealthyHostCount - The number of target instances that are considered + // healthy. Statistics: The most useful statistic are Average, Minimum, and + // Maximum. + // + // * UnhealthyHostCount - The number of target instances that are considered + // unhealthy. Statistics: The most useful statistic are Average, Minimum, + // and Maximum. + // + // * HTTPCode_LB_4XX_Count - The number of HTTP 4XX client error codes that + // originate from the load balancer. Client errors are generated when requests + // are malformed or incomplete. These requests have not been received by + // the target instance. This count does not include any response codes generated + // by the target instances. Statistics: The most useful statistic is Sum. + // Note that Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_LB_5XX_Count - The number of HTTP 5XX server error codes that + // originate from the load balancer. This count does not include any response + // codes generated by the target instances. Statistics: The most useful statistic + // is Sum. Note that Minimum, Maximum, and Average all return 1. Note that + // Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_Instance_2XX_Count - The number of HTTP response codes generated + // by the target instances. This does not include any response codes generated + // by the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_Instance_3XX_Count - The number of HTTP response codes generated + // by the target instances. This does not include any response codes generated + // by the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_Instance_4XX_Count - The number of HTTP response codes generated + // by the target instances. This does not include any response codes generated + // by the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_Instance_5XX_Count - The number of HTTP response codes generated + // by the target instances. This does not include any response codes generated + // by the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // * InstanceResponseTime - The time elapsed, in seconds, after the request + // leaves the load balancer until a response from the target instance is + // received. Statistics: The most useful statistic is Average. + // + // * RejectedConnectionCount - The number of connections that were rejected + // because the load balancer had reached its maximum number of connections. + // Statistics: The most useful statistic is Sum. + // + // * RequestCount - The number of requests processed over IPv4. This count + // includes only the requests with a response generated by a target instance + // of the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // MetricName is a required field + MetricName *string `locationName:"metricName" type:"string" required:"true" enum:"LoadBalancerMetricName"` + + // The granularity, in seconds, of the returned data points. + // + // Period is a required field + Period *int64 `locationName:"period" min:"60" type:"integer" required:"true"` + + // The start time of the period. + // + // StartTime is a required field + StartTime *time.Time `locationName:"startTime" type:"timestamp" required:"true"` + + // An array of statistics that you want to request metrics for. Valid values + // are listed below. + // + // * SampleCount - The count (number) of data points used for the statistical + // calculation. + // + // * Average - The value of Sum / SampleCount during the specified period. + // By comparing this statistic with the Minimum and Maximum, you can determine + // the full scope of a metric and how close the average use is to the Minimum + // and Maximum. This comparison helps you to know when to increase or decrease + // your resources as needed. + // + // * Sum - All values submitted for the matching metric added together. This + // statistic can be useful for determining the total volume of a metric. + // + // * Minimum - The lowest value observed during the specified period. You + // can use this value to determine low volumes of activity for your application. + // + // * Maximum - The highest value observed during the specified period. You + // can use this value to determine high volumes of activity for your application. + // + // Statistics is a required field + Statistics []*string `locationName:"statistics" type:"list" required:"true"` + + // The unit for the time period request. Valid values are listed below. + // + // Unit is a required field + Unit *string `locationName:"unit" type:"string" required:"true" enum:"MetricUnit"` +} + +// String returns the string representation +func (s GetLoadBalancerMetricDataInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLoadBalancerMetricDataInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetLoadBalancerMetricDataInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetLoadBalancerMetricDataInput"} + if s.EndTime == nil { + invalidParams.Add(request.NewErrParamRequired("EndTime")) + } + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + if s.MetricName == nil { + invalidParams.Add(request.NewErrParamRequired("MetricName")) + } + if s.Period == nil { + invalidParams.Add(request.NewErrParamRequired("Period")) + } + if s.Period != nil && *s.Period < 60 { + invalidParams.Add(request.NewErrParamMinValue("Period", 60)) + } + if s.StartTime == nil { + invalidParams.Add(request.NewErrParamRequired("StartTime")) + } + if s.Statistics == nil { + invalidParams.Add(request.NewErrParamRequired("Statistics")) + } + if s.Unit == nil { + invalidParams.Add(request.NewErrParamRequired("Unit")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEndTime sets the EndTime field's value. +func (s *GetLoadBalancerMetricDataInput) SetEndTime(v time.Time) *GetLoadBalancerMetricDataInput { + s.EndTime = &v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *GetLoadBalancerMetricDataInput) SetLoadBalancerName(v string) *GetLoadBalancerMetricDataInput { + s.LoadBalancerName = &v + return s +} + +// SetMetricName sets the MetricName field's value. +func (s *GetLoadBalancerMetricDataInput) SetMetricName(v string) *GetLoadBalancerMetricDataInput { + s.MetricName = &v + return s +} + +// SetPeriod sets the Period field's value. +func (s *GetLoadBalancerMetricDataInput) SetPeriod(v int64) *GetLoadBalancerMetricDataInput { + s.Period = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *GetLoadBalancerMetricDataInput) SetStartTime(v time.Time) *GetLoadBalancerMetricDataInput { + s.StartTime = &v + return s +} + +// SetStatistics sets the Statistics field's value. +func (s *GetLoadBalancerMetricDataInput) SetStatistics(v []*string) *GetLoadBalancerMetricDataInput { + s.Statistics = v + return s +} + +// SetUnit sets the Unit field's value. +func (s *GetLoadBalancerMetricDataInput) SetUnit(v string) *GetLoadBalancerMetricDataInput { + s.Unit = &v + return s +} + +type GetLoadBalancerMetricDataOutput struct { + _ struct{} `type:"structure"` + + // An array of metric datapoint objects. + MetricData []*MetricDatapoint `locationName:"metricData" type:"list"` + + // The metric about which you are receiving information. Valid values are listed + // below, along with the most useful statistics to include in your request. + // + // * ClientTLSNegotiationErrorCount - The number of TLS connections initiated + // by the client that did not establish a session with the load balancer. + // Possible causes include a mismatch of ciphers or protocols. Statistics: + // The most useful statistic is Sum. + // + // * HealthyHostCount - The number of target instances that are considered + // healthy. Statistics: The most useful statistic are Average, Minimum, and + // Maximum. + // + // * UnhealthyHostCount - The number of target instances that are considered + // unhealthy. Statistics: The most useful statistic are Average, Minimum, + // and Maximum. + // + // * HTTPCode_LB_4XX_Count - The number of HTTP 4XX client error codes that + // originate from the load balancer. Client errors are generated when requests + // are malformed or incomplete. These requests have not been received by + // the target instance. This count does not include any response codes generated + // by the target instances. Statistics: The most useful statistic is Sum. + // Note that Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_LB_5XX_Count - The number of HTTP 5XX server error codes that + // originate from the load balancer. This count does not include any response + // codes generated by the target instances. Statistics: The most useful statistic + // is Sum. Note that Minimum, Maximum, and Average all return 1. Note that + // Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_Instance_2XX_Count - The number of HTTP response codes generated + // by the target instances. This does not include any response codes generated + // by the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_Instance_3XX_Count - The number of HTTP response codes generated + // by the target instances. This does not include any response codes generated + // by the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_Instance_4XX_Count - The number of HTTP response codes generated + // by the target instances. This does not include any response codes generated + // by the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // * HTTPCode_Instance_5XX_Count - The number of HTTP response codes generated + // by the target instances. This does not include any response codes generated + // by the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + // + // * InstanceResponseTime - The time elapsed, in seconds, after the request + // leaves the load balancer until a response from the target instance is + // received. Statistics: The most useful statistic is Average. + // + // * RejectedConnectionCount - The number of connections that were rejected + // because the load balancer had reached its maximum number of connections. + // Statistics: The most useful statistic is Sum. + // + // * RequestCount - The number of requests processed over IPv4. This count + // includes only the requests with a response generated by a target instance + // of the load balancer. Statistics: The most useful statistic is Sum. Note + // that Minimum, Maximum, and Average all return 1. + MetricName *string `locationName:"metricName" type:"string" enum:"LoadBalancerMetricName"` +} + +// String returns the string representation +func (s GetLoadBalancerMetricDataOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLoadBalancerMetricDataOutput) GoString() string { + return s.String() +} + +// SetMetricData sets the MetricData field's value. +func (s *GetLoadBalancerMetricDataOutput) SetMetricData(v []*MetricDatapoint) *GetLoadBalancerMetricDataOutput { + s.MetricData = v + return s +} + +// SetMetricName sets the MetricName field's value. +func (s *GetLoadBalancerMetricDataOutput) SetMetricName(v string) *GetLoadBalancerMetricDataOutput { + s.MetricName = &v + return s +} + +type GetLoadBalancerOutput struct { + _ struct{} `type:"structure"` + + // An object containing information about your load balancer. + LoadBalancer *LoadBalancer `locationName:"loadBalancer" type:"structure"` +} + +// String returns the string representation +func (s GetLoadBalancerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLoadBalancerOutput) GoString() string { + return s.String() +} + +// SetLoadBalancer sets the LoadBalancer field's value. +func (s *GetLoadBalancerOutput) SetLoadBalancer(v *LoadBalancer) *GetLoadBalancerOutput { + s.LoadBalancer = v + return s +} + +type GetLoadBalancerTlsCertificatesInput struct { + _ struct{} `type:"structure"` + + // The name of the load balancer you associated with your SSL/TLS certificate. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetLoadBalancerTlsCertificatesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLoadBalancerTlsCertificatesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetLoadBalancerTlsCertificatesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetLoadBalancerTlsCertificatesInput"} + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *GetLoadBalancerTlsCertificatesInput) SetLoadBalancerName(v string) *GetLoadBalancerTlsCertificatesInput { + s.LoadBalancerName = &v + return s +} + +type GetLoadBalancerTlsCertificatesOutput struct { + _ struct{} `type:"structure"` + + // An array of LoadBalancerTlsCertificate objects describing your SSL/TLS certificates. + TlsCertificates []*LoadBalancerTlsCertificate `locationName:"tlsCertificates" type:"list"` +} + +// String returns the string representation +func (s GetLoadBalancerTlsCertificatesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLoadBalancerTlsCertificatesOutput) GoString() string { + return s.String() +} + +// SetTlsCertificates sets the TlsCertificates field's value. +func (s *GetLoadBalancerTlsCertificatesOutput) SetTlsCertificates(v []*LoadBalancerTlsCertificate) *GetLoadBalancerTlsCertificatesOutput { + s.TlsCertificates = v + return s +} + +type GetLoadBalancersInput struct { + _ struct{} `type:"structure"` + + // A token used for paginating the results from your GetLoadBalancers request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetLoadBalancersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLoadBalancersInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetLoadBalancersInput) SetPageToken(v string) *GetLoadBalancersInput { + s.PageToken = &v + return s +} + +type GetLoadBalancersOutput struct { + _ struct{} `type:"structure"` + + // An array of LoadBalancer objects describing your load balancers. + LoadBalancers []*LoadBalancer `locationName:"loadBalancers" type:"list"` + + // A token used for advancing to the next page of results from your GetLoadBalancers + // request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetLoadBalancersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetLoadBalancersOutput) GoString() string { + return s.String() +} + +// SetLoadBalancers sets the LoadBalancers field's value. +func (s *GetLoadBalancersOutput) SetLoadBalancers(v []*LoadBalancer) *GetLoadBalancersOutput { + s.LoadBalancers = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetLoadBalancersOutput) SetNextPageToken(v string) *GetLoadBalancersOutput { + s.NextPageToken = &v + return s +} + +type GetOperationInput struct { + _ struct{} `type:"structure"` + + // A GUID used to identify the operation. + // + // OperationId is a required field + OperationId *string `locationName:"operationId" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetOperationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetOperationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetOperationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetOperationInput"} + if s.OperationId == nil { + invalidParams.Add(request.NewErrParamRequired("OperationId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetOperationId sets the OperationId field's value. +func (s *GetOperationInput) SetOperationId(v string) *GetOperationInput { + s.OperationId = &v + return s +} + +type GetOperationOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the results of your + // get operation request. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s GetOperationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetOperationOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *GetOperationOutput) SetOperation(v *Operation) *GetOperationOutput { + s.Operation = v + return s +} + +type GetOperationsForResourceInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get operations + // for resource request. + PageToken *string `locationName:"pageToken" type:"string"` + + // The name of the resource for which you are requesting information. + // + // ResourceName is a required field + ResourceName *string `locationName:"resourceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetOperationsForResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetOperationsForResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetOperationsForResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetOperationsForResourceInput"} + if s.ResourceName == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetPageToken sets the PageToken field's value. +func (s *GetOperationsForResourceInput) SetPageToken(v string) *GetOperationsForResourceInput { + s.PageToken = &v + return s +} + +// SetResourceName sets the ResourceName field's value. +func (s *GetOperationsForResourceInput) SetResourceName(v string) *GetOperationsForResourceInput { + s.ResourceName = &v + return s +} + +type GetOperationsForResourceOutput struct { + _ struct{} `type:"structure"` + + // (Deprecated) Returns the number of pages of results that remain. + // + // In releases prior to June 12, 2017, this parameter returned null by the API. + // It is now deprecated, and the API returns the next page token parameter instead. + // + // Deprecated: NextPageCount has been deprecated + NextPageCount *string `locationName:"nextPageCount" deprecated:"true" type:"string"` + + // An identifier that was returned from the previous call to this operation, + // which can be used to return the next set of items in the list. + NextPageToken *string `locationName:"nextPageToken" type:"string"` + + // An array of key-value pairs containing information about the results of your + // get operations for resource request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s GetOperationsForResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetOperationsForResourceOutput) GoString() string { + return s.String() +} + +// SetNextPageCount sets the NextPageCount field's value. +func (s *GetOperationsForResourceOutput) SetNextPageCount(v string) *GetOperationsForResourceOutput { + s.NextPageCount = &v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetOperationsForResourceOutput) SetNextPageToken(v string) *GetOperationsForResourceOutput { + s.NextPageToken = &v + return s +} + +// SetOperations sets the Operations field's value. +func (s *GetOperationsForResourceOutput) SetOperations(v []*Operation) *GetOperationsForResourceOutput { + s.Operations = v + return s +} + +type GetOperationsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get operations + // request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetOperationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetOperationsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetOperationsInput) SetPageToken(v string) *GetOperationsInput { + s.PageToken = &v + return s +} + +type GetOperationsOutput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get operations + // request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` + + // An array of key-value pairs containing information about the results of your + // get operations request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s GetOperationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetOperationsOutput) GoString() string { + return s.String() +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetOperationsOutput) SetNextPageToken(v string) *GetOperationsOutput { + s.NextPageToken = &v + return s +} + +// SetOperations sets the Operations field's value. +func (s *GetOperationsOutput) SetOperations(v []*Operation) *GetOperationsOutput { + s.Operations = v + return s +} + +type GetRegionsInput struct { + _ struct{} `type:"structure"` + + // A Boolean value indicating whether to also include Availability Zones in + // your get regions request. Availability Zones are indicated with a letter: + // e.g., us-east-2a. + IncludeAvailabilityZones *bool `locationName:"includeAvailabilityZones" type:"boolean"` + + // >A Boolean value indicating whether to also include Availability Zones for + // databases in your get regions request. Availability Zones are indicated with + // a letter (e.g., us-east-2a). + IncludeRelationalDatabaseAvailabilityZones *bool `locationName:"includeRelationalDatabaseAvailabilityZones" type:"boolean"` +} + +// String returns the string representation +func (s GetRegionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRegionsInput) GoString() string { + return s.String() +} + +// SetIncludeAvailabilityZones sets the IncludeAvailabilityZones field's value. +func (s *GetRegionsInput) SetIncludeAvailabilityZones(v bool) *GetRegionsInput { + s.IncludeAvailabilityZones = &v + return s +} + +// SetIncludeRelationalDatabaseAvailabilityZones sets the IncludeRelationalDatabaseAvailabilityZones field's value. +func (s *GetRegionsInput) SetIncludeRelationalDatabaseAvailabilityZones(v bool) *GetRegionsInput { + s.IncludeRelationalDatabaseAvailabilityZones = &v + return s +} + +type GetRegionsOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about your get regions + // request. + Regions []*Region `locationName:"regions" type:"list"` +} + +// String returns the string representation +func (s GetRegionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRegionsOutput) GoString() string { + return s.String() +} + +// SetRegions sets the Regions field's value. +func (s *GetRegionsOutput) SetRegions(v []*Region) *GetRegionsOutput { + s.Regions = v + return s +} + +type GetRelationalDatabaseBlueprintsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to a specific page of results for your get relational + // database blueprints request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetRelationalDatabaseBlueprintsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseBlueprintsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetRelationalDatabaseBlueprintsInput) SetPageToken(v string) *GetRelationalDatabaseBlueprintsInput { + s.PageToken = &v + return s +} + +type GetRelationalDatabaseBlueprintsOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your get relational database blueprints + // request. + Blueprints []*RelationalDatabaseBlueprint `locationName:"blueprints" type:"list"` + + // A token used for advancing to the next page of results of your get relational + // database blueprints request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetRelationalDatabaseBlueprintsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseBlueprintsOutput) GoString() string { + return s.String() +} + +// SetBlueprints sets the Blueprints field's value. +func (s *GetRelationalDatabaseBlueprintsOutput) SetBlueprints(v []*RelationalDatabaseBlueprint) *GetRelationalDatabaseBlueprintsOutput { + s.Blueprints = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetRelationalDatabaseBlueprintsOutput) SetNextPageToken(v string) *GetRelationalDatabaseBlueprintsOutput { + s.NextPageToken = &v + return s +} + +type GetRelationalDatabaseBundlesInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to a specific page of results for your get relational + // database bundles request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetRelationalDatabaseBundlesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseBundlesInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetRelationalDatabaseBundlesInput) SetPageToken(v string) *GetRelationalDatabaseBundlesInput { + s.PageToken = &v + return s +} + +type GetRelationalDatabaseBundlesOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your get relational database bundles request. + Bundles []*RelationalDatabaseBundle `locationName:"bundles" type:"list"` + + // A token used for advancing to the next page of results of your get relational + // database bundles request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` +} + +// String returns the string representation +func (s GetRelationalDatabaseBundlesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseBundlesOutput) GoString() string { + return s.String() +} + +// SetBundles sets the Bundles field's value. +func (s *GetRelationalDatabaseBundlesOutput) SetBundles(v []*RelationalDatabaseBundle) *GetRelationalDatabaseBundlesOutput { + s.Bundles = v + return s +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetRelationalDatabaseBundlesOutput) SetNextPageToken(v string) *GetRelationalDatabaseBundlesOutput { + s.NextPageToken = &v + return s +} + +type GetRelationalDatabaseEventsInput struct { + _ struct{} `type:"structure"` + + // The number of minutes in the past from which to retrieve events. For example, + // to get all events from the past 2 hours, enter 120. + // + // Default: 60 + // + // The minimum is 1 and the maximum is 14 days (20160 minutes). + DurationInMinutes *int64 `locationName:"durationInMinutes" type:"integer"` + + // A token used for advancing to a specific page of results from for get relational + // database events request. + PageToken *string `locationName:"pageToken" type:"string"` + + // The name of the database from which to get events. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetRelationalDatabaseEventsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseEventsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetRelationalDatabaseEventsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetRelationalDatabaseEventsInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationInMinutes sets the DurationInMinutes field's value. +func (s *GetRelationalDatabaseEventsInput) SetDurationInMinutes(v int64) *GetRelationalDatabaseEventsInput { + s.DurationInMinutes = &v + return s +} + +// SetPageToken sets the PageToken field's value. +func (s *GetRelationalDatabaseEventsInput) SetPageToken(v string) *GetRelationalDatabaseEventsInput { + s.PageToken = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *GetRelationalDatabaseEventsInput) SetRelationalDatabaseName(v string) *GetRelationalDatabaseEventsInput { + s.RelationalDatabaseName = &v + return s +} + +type GetRelationalDatabaseEventsOutput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get relational + // database events request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` + + // An object describing the result of your get relational database events request. + RelationalDatabaseEvents []*RelationalDatabaseEvent `locationName:"relationalDatabaseEvents" type:"list"` +} + +// String returns the string representation +func (s GetRelationalDatabaseEventsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseEventsOutput) GoString() string { + return s.String() +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetRelationalDatabaseEventsOutput) SetNextPageToken(v string) *GetRelationalDatabaseEventsOutput { + s.NextPageToken = &v + return s +} + +// SetRelationalDatabaseEvents sets the RelationalDatabaseEvents field's value. +func (s *GetRelationalDatabaseEventsOutput) SetRelationalDatabaseEvents(v []*RelationalDatabaseEvent) *GetRelationalDatabaseEventsOutput { + s.RelationalDatabaseEvents = v + return s +} + +type GetRelationalDatabaseInput struct { + _ struct{} `type:"structure"` + + // The name of the database that you are looking up. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetRelationalDatabaseInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetRelationalDatabaseInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetRelationalDatabaseInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *GetRelationalDatabaseInput) SetRelationalDatabaseName(v string) *GetRelationalDatabaseInput { + s.RelationalDatabaseName = &v + return s +} + +type GetRelationalDatabaseLogEventsInput struct { + _ struct{} `type:"structure"` + + // The end of the time interval from which to get log events. + // + // Constraints: + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Specified in the Unix time format. For example, if you wish to use an + // end time of October 1, 2018, at 8 PM UTC, then you input 1538424000 as + // the end time. + EndTime *time.Time `locationName:"endTime" type:"timestamp"` + + // The name of the log stream. + // + // Use the get relational database log streams operation to get a list of available + // log streams. + // + // LogStreamName is a required field + LogStreamName *string `locationName:"logStreamName" type:"string" required:"true"` + + // A token used for advancing to a specific page of results for your get relational + // database log events request. + PageToken *string `locationName:"pageToken" type:"string"` + + // The name of your database for which to get log events. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` + + // Parameter to specify if the log should start from head or tail. If true is + // specified, the log event starts from the head of the log. If false is specified, + // the log event starts from the tail of the log. + // + // Default: false + StartFromHead *bool `locationName:"startFromHead" type:"boolean"` + + // The start of the time interval from which to get log events. + // + // Constraints: + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Specified in the Unix time format. For example, if you wish to use a + // start time of October 1, 2018, at 8 PM UTC, then you input 1538424000 + // as the start time. + StartTime *time.Time `locationName:"startTime" type:"timestamp"` +} + +// String returns the string representation +func (s GetRelationalDatabaseLogEventsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseLogEventsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetRelationalDatabaseLogEventsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetRelationalDatabaseLogEventsInput"} + if s.LogStreamName == nil { + invalidParams.Add(request.NewErrParamRequired("LogStreamName")) + } + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEndTime sets the EndTime field's value. +func (s *GetRelationalDatabaseLogEventsInput) SetEndTime(v time.Time) *GetRelationalDatabaseLogEventsInput { + s.EndTime = &v + return s +} + +// SetLogStreamName sets the LogStreamName field's value. +func (s *GetRelationalDatabaseLogEventsInput) SetLogStreamName(v string) *GetRelationalDatabaseLogEventsInput { + s.LogStreamName = &v + return s +} + +// SetPageToken sets the PageToken field's value. +func (s *GetRelationalDatabaseLogEventsInput) SetPageToken(v string) *GetRelationalDatabaseLogEventsInput { + s.PageToken = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *GetRelationalDatabaseLogEventsInput) SetRelationalDatabaseName(v string) *GetRelationalDatabaseLogEventsInput { + s.RelationalDatabaseName = &v + return s +} + +// SetStartFromHead sets the StartFromHead field's value. +func (s *GetRelationalDatabaseLogEventsInput) SetStartFromHead(v bool) *GetRelationalDatabaseLogEventsInput { + s.StartFromHead = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *GetRelationalDatabaseLogEventsInput) SetStartTime(v time.Time) *GetRelationalDatabaseLogEventsInput { + s.StartTime = &v + return s +} + +type GetRelationalDatabaseLogEventsOutput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the previous page of results from your get + // relational database log events request. + NextBackwardToken *string `locationName:"nextBackwardToken" type:"string"` + + // A token used for advancing to the next page of results from your get relational + // database log events request. + NextForwardToken *string `locationName:"nextForwardToken" type:"string"` + + // An object describing the result of your get relational database log events + // request. + ResourceLogEvents []*LogEvent `locationName:"resourceLogEvents" type:"list"` +} + +// String returns the string representation +func (s GetRelationalDatabaseLogEventsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseLogEventsOutput) GoString() string { + return s.String() +} + +// SetNextBackwardToken sets the NextBackwardToken field's value. +func (s *GetRelationalDatabaseLogEventsOutput) SetNextBackwardToken(v string) *GetRelationalDatabaseLogEventsOutput { + s.NextBackwardToken = &v + return s +} + +// SetNextForwardToken sets the NextForwardToken field's value. +func (s *GetRelationalDatabaseLogEventsOutput) SetNextForwardToken(v string) *GetRelationalDatabaseLogEventsOutput { + s.NextForwardToken = &v + return s +} + +// SetResourceLogEvents sets the ResourceLogEvents field's value. +func (s *GetRelationalDatabaseLogEventsOutput) SetResourceLogEvents(v []*LogEvent) *GetRelationalDatabaseLogEventsOutput { + s.ResourceLogEvents = v + return s +} + +type GetRelationalDatabaseLogStreamsInput struct { + _ struct{} `type:"structure"` + + // The name of your database for which to get log streams. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetRelationalDatabaseLogStreamsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseLogStreamsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetRelationalDatabaseLogStreamsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetRelationalDatabaseLogStreamsInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *GetRelationalDatabaseLogStreamsInput) SetRelationalDatabaseName(v string) *GetRelationalDatabaseLogStreamsInput { + s.RelationalDatabaseName = &v + return s +} + +type GetRelationalDatabaseLogStreamsOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your get relational database log streams + // request. + LogStreams []*string `locationName:"logStreams" type:"list"` +} + +// String returns the string representation +func (s GetRelationalDatabaseLogStreamsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseLogStreamsOutput) GoString() string { + return s.String() +} + +// SetLogStreams sets the LogStreams field's value. +func (s *GetRelationalDatabaseLogStreamsOutput) SetLogStreams(v []*string) *GetRelationalDatabaseLogStreamsOutput { + s.LogStreams = v + return s +} + +type GetRelationalDatabaseMasterUserPasswordInput struct { + _ struct{} `type:"structure"` + + // The password version to return. + // + // Specifying CURRENT or PREVIOUS returns the current or previous passwords + // respectively. Specifying PENDING returns the newest version of the password + // that will rotate to CURRENT. After the PENDING password rotates to CURRENT, + // the PENDING password is no longer available. + // + // Default: CURRENT + PasswordVersion *string `locationName:"passwordVersion" type:"string" enum:"RelationalDatabasePasswordVersion"` + + // The name of your database for which to get the master user password. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetRelationalDatabaseMasterUserPasswordInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseMasterUserPasswordInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetRelationalDatabaseMasterUserPasswordInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetRelationalDatabaseMasterUserPasswordInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetPasswordVersion sets the PasswordVersion field's value. +func (s *GetRelationalDatabaseMasterUserPasswordInput) SetPasswordVersion(v string) *GetRelationalDatabaseMasterUserPasswordInput { + s.PasswordVersion = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *GetRelationalDatabaseMasterUserPasswordInput) SetRelationalDatabaseName(v string) *GetRelationalDatabaseMasterUserPasswordInput { + s.RelationalDatabaseName = &v + return s +} + +type GetRelationalDatabaseMasterUserPasswordOutput struct { + _ struct{} `type:"structure"` + + // The timestamp when the specified version of the master user password was + // created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The master user password for the password version specified. + MasterUserPassword *string `locationName:"masterUserPassword" type:"string" sensitive:"true"` +} + +// String returns the string representation +func (s GetRelationalDatabaseMasterUserPasswordOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseMasterUserPasswordOutput) GoString() string { + return s.String() +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *GetRelationalDatabaseMasterUserPasswordOutput) SetCreatedAt(v time.Time) *GetRelationalDatabaseMasterUserPasswordOutput { + s.CreatedAt = &v + return s +} + +// SetMasterUserPassword sets the MasterUserPassword field's value. +func (s *GetRelationalDatabaseMasterUserPasswordOutput) SetMasterUserPassword(v string) *GetRelationalDatabaseMasterUserPasswordOutput { + s.MasterUserPassword = &v + return s +} + +type GetRelationalDatabaseMetricDataInput struct { + _ struct{} `type:"structure"` + + // The end of the time interval from which to get metric data. + // + // Constraints: + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Specified in the Unix time format. For example, if you wish to use an + // end time of October 1, 2018, at 8 PM UTC, then you input 1538424000 as + // the end time. + // + // EndTime is a required field + EndTime *time.Time `locationName:"endTime" type:"timestamp" required:"true"` + + // The name of the metric data to return. + // + // MetricName is a required field + MetricName *string `locationName:"metricName" type:"string" required:"true" enum:"RelationalDatabaseMetricName"` + + // The granularity, in seconds, of the returned data points. + // + // Period is a required field + Period *int64 `locationName:"period" min:"60" type:"integer" required:"true"` + + // The name of your database from which to get metric data. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` + + // The start of the time interval from which to get metric data. + // + // Constraints: + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Specified in the Unix time format. For example, if you wish to use a + // start time of October 1, 2018, at 8 PM UTC, then you input 1538424000 + // as the start time. + // + // StartTime is a required field + StartTime *time.Time `locationName:"startTime" type:"timestamp" required:"true"` + + // The array of statistics for your metric data request. + // + // Statistics is a required field + Statistics []*string `locationName:"statistics" type:"list" required:"true"` + + // The unit for the metric data request. + // + // Unit is a required field + Unit *string `locationName:"unit" type:"string" required:"true" enum:"MetricUnit"` +} + +// String returns the string representation +func (s GetRelationalDatabaseMetricDataInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseMetricDataInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetRelationalDatabaseMetricDataInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetRelationalDatabaseMetricDataInput"} + if s.EndTime == nil { + invalidParams.Add(request.NewErrParamRequired("EndTime")) + } + if s.MetricName == nil { + invalidParams.Add(request.NewErrParamRequired("MetricName")) + } + if s.Period == nil { + invalidParams.Add(request.NewErrParamRequired("Period")) + } + if s.Period != nil && *s.Period < 60 { + invalidParams.Add(request.NewErrParamMinValue("Period", 60)) + } + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + if s.StartTime == nil { + invalidParams.Add(request.NewErrParamRequired("StartTime")) + } + if s.Statistics == nil { + invalidParams.Add(request.NewErrParamRequired("Statistics")) + } + if s.Unit == nil { + invalidParams.Add(request.NewErrParamRequired("Unit")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEndTime sets the EndTime field's value. +func (s *GetRelationalDatabaseMetricDataInput) SetEndTime(v time.Time) *GetRelationalDatabaseMetricDataInput { + s.EndTime = &v + return s +} + +// SetMetricName sets the MetricName field's value. +func (s *GetRelationalDatabaseMetricDataInput) SetMetricName(v string) *GetRelationalDatabaseMetricDataInput { + s.MetricName = &v + return s +} + +// SetPeriod sets the Period field's value. +func (s *GetRelationalDatabaseMetricDataInput) SetPeriod(v int64) *GetRelationalDatabaseMetricDataInput { + s.Period = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *GetRelationalDatabaseMetricDataInput) SetRelationalDatabaseName(v string) *GetRelationalDatabaseMetricDataInput { + s.RelationalDatabaseName = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *GetRelationalDatabaseMetricDataInput) SetStartTime(v time.Time) *GetRelationalDatabaseMetricDataInput { + s.StartTime = &v + return s +} + +// SetStatistics sets the Statistics field's value. +func (s *GetRelationalDatabaseMetricDataInput) SetStatistics(v []*string) *GetRelationalDatabaseMetricDataInput { + s.Statistics = v + return s +} + +// SetUnit sets the Unit field's value. +func (s *GetRelationalDatabaseMetricDataInput) SetUnit(v string) *GetRelationalDatabaseMetricDataInput { + s.Unit = &v + return s +} + +type GetRelationalDatabaseMetricDataOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your get relational database metric data + // request. + MetricData []*MetricDatapoint `locationName:"metricData" type:"list"` + + // The name of the metric. + MetricName *string `locationName:"metricName" type:"string" enum:"RelationalDatabaseMetricName"` +} + +// String returns the string representation +func (s GetRelationalDatabaseMetricDataOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseMetricDataOutput) GoString() string { + return s.String() +} + +// SetMetricData sets the MetricData field's value. +func (s *GetRelationalDatabaseMetricDataOutput) SetMetricData(v []*MetricDatapoint) *GetRelationalDatabaseMetricDataOutput { + s.MetricData = v + return s +} + +// SetMetricName sets the MetricName field's value. +func (s *GetRelationalDatabaseMetricDataOutput) SetMetricName(v string) *GetRelationalDatabaseMetricDataOutput { + s.MetricName = &v + return s +} + +type GetRelationalDatabaseOutput struct { + _ struct{} `type:"structure"` + + // An object describing the specified database. + RelationalDatabase *RelationalDatabase `locationName:"relationalDatabase" type:"structure"` +} + +// String returns the string representation +func (s GetRelationalDatabaseOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseOutput) GoString() string { + return s.String() +} + +// SetRelationalDatabase sets the RelationalDatabase field's value. +func (s *GetRelationalDatabaseOutput) SetRelationalDatabase(v *RelationalDatabase) *GetRelationalDatabaseOutput { + s.RelationalDatabase = v + return s +} + +type GetRelationalDatabaseParametersInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to a specific page of results for your get relational + // database parameters request. + PageToken *string `locationName:"pageToken" type:"string"` + + // The name of your database for which to get parameters. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetRelationalDatabaseParametersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseParametersInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetRelationalDatabaseParametersInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetRelationalDatabaseParametersInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetPageToken sets the PageToken field's value. +func (s *GetRelationalDatabaseParametersInput) SetPageToken(v string) *GetRelationalDatabaseParametersInput { + s.PageToken = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *GetRelationalDatabaseParametersInput) SetRelationalDatabaseName(v string) *GetRelationalDatabaseParametersInput { + s.RelationalDatabaseName = &v + return s +} + +type GetRelationalDatabaseParametersOutput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get static + // IPs request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` + + // An object describing the result of your get relational database parameters + // request. + Parameters []*RelationalDatabaseParameter `locationName:"parameters" type:"list"` +} + +// String returns the string representation +func (s GetRelationalDatabaseParametersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseParametersOutput) GoString() string { + return s.String() +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetRelationalDatabaseParametersOutput) SetNextPageToken(v string) *GetRelationalDatabaseParametersOutput { + s.NextPageToken = &v + return s +} + +// SetParameters sets the Parameters field's value. +func (s *GetRelationalDatabaseParametersOutput) SetParameters(v []*RelationalDatabaseParameter) *GetRelationalDatabaseParametersOutput { + s.Parameters = v + return s +} + +type GetRelationalDatabaseSnapshotInput struct { + _ struct{} `type:"structure"` + + // The name of the database snapshot for which to get information. + // + // RelationalDatabaseSnapshotName is a required field + RelationalDatabaseSnapshotName *string `locationName:"relationalDatabaseSnapshotName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetRelationalDatabaseSnapshotInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseSnapshotInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetRelationalDatabaseSnapshotInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetRelationalDatabaseSnapshotInput"} + if s.RelationalDatabaseSnapshotName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseSnapshotName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRelationalDatabaseSnapshotName sets the RelationalDatabaseSnapshotName field's value. +func (s *GetRelationalDatabaseSnapshotInput) SetRelationalDatabaseSnapshotName(v string) *GetRelationalDatabaseSnapshotInput { + s.RelationalDatabaseSnapshotName = &v + return s +} + +type GetRelationalDatabaseSnapshotOutput struct { + _ struct{} `type:"structure"` + + // An object describing the specified database snapshot. + RelationalDatabaseSnapshot *RelationalDatabaseSnapshot `locationName:"relationalDatabaseSnapshot" type:"structure"` +} + +// String returns the string representation +func (s GetRelationalDatabaseSnapshotOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseSnapshotOutput) GoString() string { + return s.String() +} + +// SetRelationalDatabaseSnapshot sets the RelationalDatabaseSnapshot field's value. +func (s *GetRelationalDatabaseSnapshotOutput) SetRelationalDatabaseSnapshot(v *RelationalDatabaseSnapshot) *GetRelationalDatabaseSnapshotOutput { + s.RelationalDatabaseSnapshot = v + return s +} + +type GetRelationalDatabaseSnapshotsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to a specific page of results for your get relational + // database snapshots request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetRelationalDatabaseSnapshotsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseSnapshotsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetRelationalDatabaseSnapshotsInput) SetPageToken(v string) *GetRelationalDatabaseSnapshotsInput { + s.PageToken = &v + return s +} + +type GetRelationalDatabaseSnapshotsOutput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get relational + // database snapshots request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` + + // An object describing the result of your get relational database snapshots + // request. + RelationalDatabaseSnapshots []*RelationalDatabaseSnapshot `locationName:"relationalDatabaseSnapshots" type:"list"` +} + +// String returns the string representation +func (s GetRelationalDatabaseSnapshotsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabaseSnapshotsOutput) GoString() string { + return s.String() +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetRelationalDatabaseSnapshotsOutput) SetNextPageToken(v string) *GetRelationalDatabaseSnapshotsOutput { + s.NextPageToken = &v + return s +} + +// SetRelationalDatabaseSnapshots sets the RelationalDatabaseSnapshots field's value. +func (s *GetRelationalDatabaseSnapshotsOutput) SetRelationalDatabaseSnapshots(v []*RelationalDatabaseSnapshot) *GetRelationalDatabaseSnapshotsOutput { + s.RelationalDatabaseSnapshots = v + return s +} + +type GetRelationalDatabasesInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to a specific page of results for your get relational + // database request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetRelationalDatabasesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabasesInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetRelationalDatabasesInput) SetPageToken(v string) *GetRelationalDatabasesInput { + s.PageToken = &v + return s +} + +type GetRelationalDatabasesOutput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get relational + // databases request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` + + // An object describing the result of your get relational databases request. + RelationalDatabases []*RelationalDatabase `locationName:"relationalDatabases" type:"list"` +} + +// String returns the string representation +func (s GetRelationalDatabasesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetRelationalDatabasesOutput) GoString() string { + return s.String() +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetRelationalDatabasesOutput) SetNextPageToken(v string) *GetRelationalDatabasesOutput { + s.NextPageToken = &v + return s +} + +// SetRelationalDatabases sets the RelationalDatabases field's value. +func (s *GetRelationalDatabasesOutput) SetRelationalDatabases(v []*RelationalDatabase) *GetRelationalDatabasesOutput { + s.RelationalDatabases = v + return s +} + +type GetStaticIpInput struct { + _ struct{} `type:"structure"` + + // The name of the static IP in Lightsail. + // + // StaticIpName is a required field + StaticIpName *string `locationName:"staticIpName" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetStaticIpInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetStaticIpInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetStaticIpInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetStaticIpInput"} + if s.StaticIpName == nil { + invalidParams.Add(request.NewErrParamRequired("StaticIpName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetStaticIpName sets the StaticIpName field's value. +func (s *GetStaticIpInput) SetStaticIpName(v string) *GetStaticIpInput { + s.StaticIpName = &v + return s +} + +type GetStaticIpOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the requested static + // IP. + StaticIp *StaticIp `locationName:"staticIp" type:"structure"` +} + +// String returns the string representation +func (s GetStaticIpOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetStaticIpOutput) GoString() string { + return s.String() +} + +// SetStaticIp sets the StaticIp field's value. +func (s *GetStaticIpOutput) SetStaticIp(v *StaticIp) *GetStaticIpOutput { + s.StaticIp = v + return s +} + +type GetStaticIpsInput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get static + // IPs request. + PageToken *string `locationName:"pageToken" type:"string"` +} + +// String returns the string representation +func (s GetStaticIpsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetStaticIpsInput) GoString() string { + return s.String() +} + +// SetPageToken sets the PageToken field's value. +func (s *GetStaticIpsInput) SetPageToken(v string) *GetStaticIpsInput { + s.PageToken = &v + return s +} + +type GetStaticIpsOutput struct { + _ struct{} `type:"structure"` + + // A token used for advancing to the next page of results from your get static + // IPs request. + NextPageToken *string `locationName:"nextPageToken" type:"string"` + + // An array of key-value pairs containing information about your get static + // IPs request. + StaticIps []*StaticIp `locationName:"staticIps" type:"list"` +} + +// String returns the string representation +func (s GetStaticIpsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetStaticIpsOutput) GoString() string { + return s.String() +} + +// SetNextPageToken sets the NextPageToken field's value. +func (s *GetStaticIpsOutput) SetNextPageToken(v string) *GetStaticIpsOutput { + s.NextPageToken = &v + return s +} + +// SetStaticIps sets the StaticIps field's value. +func (s *GetStaticIpsOutput) SetStaticIps(v []*StaticIp) *GetStaticIpsOutput { + s.StaticIps = v + return s +} + +// Describes the public SSH host keys or the RDP certificate. +type HostKeyAttributes struct { + _ struct{} `type:"structure"` + + // The SSH host key algorithm or the RDP certificate format. + // + // For SSH host keys, the algorithm may be ssh-rsa, ecdsa-sha2-nistp256, ssh-ed25519, + // etc. For RDP certificates, the algorithm is always x509-cert. + Algorithm *string `locationName:"algorithm" type:"string"` + + // The SHA-1 fingerprint of the returned SSH host key or RDP certificate. + // + // * Example of an SHA-1 SSH fingerprint: SHA1:1CHH6FaAaXjtFOsR/t83vf91SR0 + // + // * Example of an SHA-1 RDP fingerprint: af:34:51:fe:09:f0:e0:da:b8:4e:56:ca:60:c2:10:ff:38:06:db:45 + FingerprintSHA1 *string `locationName:"fingerprintSHA1" type:"string"` + + // The SHA-256 fingerprint of the returned SSH host key or RDP certificate. + // + // * Example of an SHA-256 SSH fingerprint: SHA256:KTsMnRBh1IhD17HpdfsbzeGA4jOijm5tyXsMjKVbB8o + // + // * Example of an SHA-256 RDP fingerprint: 03:9b:36:9f:4b:de:4e:61:70:fc:7c:c9:78:e7:d2:1a:1c:25:a8:0c:91:f6:7c:e4:d6:a0:85:c8:b4:53:99:68 + FingerprintSHA256 *string `locationName:"fingerprintSHA256" type:"string"` + + // The returned RDP certificate is not valid after this point in time. + // + // This value is listed only for RDP certificates. + NotValidAfter *time.Time `locationName:"notValidAfter" type:"timestamp"` + + // The returned RDP certificate is valid after this point in time. + // + // This value is listed only for RDP certificates. + NotValidBefore *time.Time `locationName:"notValidBefore" type:"timestamp"` + + // The public SSH host key or the RDP certificate. + PublicKey *string `locationName:"publicKey" type:"string"` + + // The time that the SSH host key or RDP certificate was recorded by Lightsail. + WitnessedAt *time.Time `locationName:"witnessedAt" type:"timestamp"` +} + +// String returns the string representation +func (s HostKeyAttributes) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostKeyAttributes) GoString() string { + return s.String() +} + +// SetAlgorithm sets the Algorithm field's value. +func (s *HostKeyAttributes) SetAlgorithm(v string) *HostKeyAttributes { + s.Algorithm = &v + return s +} + +// SetFingerprintSHA1 sets the FingerprintSHA1 field's value. +func (s *HostKeyAttributes) SetFingerprintSHA1(v string) *HostKeyAttributes { + s.FingerprintSHA1 = &v + return s +} + +// SetFingerprintSHA256 sets the FingerprintSHA256 field's value. +func (s *HostKeyAttributes) SetFingerprintSHA256(v string) *HostKeyAttributes { + s.FingerprintSHA256 = &v + return s +} + +// SetNotValidAfter sets the NotValidAfter field's value. +func (s *HostKeyAttributes) SetNotValidAfter(v time.Time) *HostKeyAttributes { + s.NotValidAfter = &v + return s +} + +// SetNotValidBefore sets the NotValidBefore field's value. +func (s *HostKeyAttributes) SetNotValidBefore(v time.Time) *HostKeyAttributes { + s.NotValidBefore = &v + return s +} + +// SetPublicKey sets the PublicKey field's value. +func (s *HostKeyAttributes) SetPublicKey(v string) *HostKeyAttributes { + s.PublicKey = &v + return s +} + +// SetWitnessedAt sets the WitnessedAt field's value. +func (s *HostKeyAttributes) SetWitnessedAt(v time.Time) *HostKeyAttributes { + s.WitnessedAt = &v + return s +} + +type ImportKeyPairInput struct { + _ struct{} `type:"structure"` + + // The name of the key pair for which you want to import the public key. + // + // KeyPairName is a required field + KeyPairName *string `locationName:"keyPairName" type:"string" required:"true"` + + // A base64-encoded public key of the ssh-rsa type. + // + // PublicKeyBase64 is a required field + PublicKeyBase64 *string `locationName:"publicKeyBase64" type:"string" required:"true"` +} + +// String returns the string representation +func (s ImportKeyPairInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportKeyPairInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ImportKeyPairInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ImportKeyPairInput"} + if s.KeyPairName == nil { + invalidParams.Add(request.NewErrParamRequired("KeyPairName")) + } + if s.PublicKeyBase64 == nil { + invalidParams.Add(request.NewErrParamRequired("PublicKeyBase64")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKeyPairName sets the KeyPairName field's value. +func (s *ImportKeyPairInput) SetKeyPairName(v string) *ImportKeyPairInput { + s.KeyPairName = &v + return s +} + +// SetPublicKeyBase64 sets the PublicKeyBase64 field's value. +func (s *ImportKeyPairInput) SetPublicKeyBase64(v string) *ImportKeyPairInput { + s.PublicKeyBase64 = &v + return s +} + +type ImportKeyPairOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operation. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s ImportKeyPairOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ImportKeyPairOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *ImportKeyPairOutput) SetOperation(v *Operation) *ImportKeyPairOutput { + s.Operation = v + return s +} + +// Describes an instance (a virtual private server). +type Instance struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the instance (e.g., arn:aws:lightsail:us-east-2:123456789101:Instance/244ad76f-8aad-4741-809f-12345EXAMPLE). + Arn *string `locationName:"arn" type:"string"` + + // The blueprint ID (e.g., os_amlinux_2016_03). + BlueprintId *string `locationName:"blueprintId" type:"string"` + + // The friendly name of the blueprint (e.g., Amazon Linux). + BlueprintName *string `locationName:"blueprintName" type:"string"` + + // The bundle for the instance (e.g., micro_1_0). + BundleId *string `locationName:"bundleId" type:"string"` + + // The timestamp when the instance was created (e.g., 1479734909.17). + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The size of the vCPU and the amount of RAM for the instance. + Hardware *InstanceHardware `locationName:"hardware" type:"structure"` + + // The IPv6 address of the instance. + Ipv6Address *string `locationName:"ipv6Address" type:"string"` + + // A Boolean value indicating whether this instance has a static IP assigned + // to it. + IsStaticIp *bool `locationName:"isStaticIp" type:"boolean"` + + // The region name and Availability Zone where the instance is located. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name the user gave the instance (e.g., Amazon_Linux-1GB-Ohio-1). + Name *string `locationName:"name" type:"string"` + + // Information about the public ports and monthly data transfer rates for the + // instance. + Networking *InstanceNetworking `locationName:"networking" type:"structure"` + + // The private IP address of the instance. + PrivateIpAddress *string `locationName:"privateIpAddress" type:"string"` + + // The public IP address of the instance. + PublicIpAddress *string `locationName:"publicIpAddress" type:"string"` + + // The type of resource (usually Instance). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The name of the SSH key being used to connect to the instance (e.g., LightsailDefaultKeyPair). + SshKeyName *string `locationName:"sshKeyName" type:"string"` + + // The status code and the state (e.g., running) for the instance. + State *InstanceState `locationName:"state" type:"structure"` + + // The support code. Include this code in your email to support when you have + // questions about an instance or another resource in Lightsail. This code enables + // our support team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` + + // The user name for connecting to the instance (e.g., ec2-user). + Username *string `locationName:"username" type:"string"` +} + +// String returns the string representation +func (s Instance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Instance) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *Instance) SetArn(v string) *Instance { + s.Arn = &v + return s +} + +// SetBlueprintId sets the BlueprintId field's value. +func (s *Instance) SetBlueprintId(v string) *Instance { + s.BlueprintId = &v + return s +} + +// SetBlueprintName sets the BlueprintName field's value. +func (s *Instance) SetBlueprintName(v string) *Instance { + s.BlueprintName = &v + return s +} + +// SetBundleId sets the BundleId field's value. +func (s *Instance) SetBundleId(v string) *Instance { + s.BundleId = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *Instance) SetCreatedAt(v time.Time) *Instance { + s.CreatedAt = &v + return s +} + +// SetHardware sets the Hardware field's value. +func (s *Instance) SetHardware(v *InstanceHardware) *Instance { + s.Hardware = v + return s +} + +// SetIpv6Address sets the Ipv6Address field's value. +func (s *Instance) SetIpv6Address(v string) *Instance { + s.Ipv6Address = &v + return s +} + +// SetIsStaticIp sets the IsStaticIp field's value. +func (s *Instance) SetIsStaticIp(v bool) *Instance { + s.IsStaticIp = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *Instance) SetLocation(v *ResourceLocation) *Instance { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *Instance) SetName(v string) *Instance { + s.Name = &v + return s +} + +// SetNetworking sets the Networking field's value. +func (s *Instance) SetNetworking(v *InstanceNetworking) *Instance { + s.Networking = v + return s +} + +// SetPrivateIpAddress sets the PrivateIpAddress field's value. +func (s *Instance) SetPrivateIpAddress(v string) *Instance { + s.PrivateIpAddress = &v + return s +} + +// SetPublicIpAddress sets the PublicIpAddress field's value. +func (s *Instance) SetPublicIpAddress(v string) *Instance { + s.PublicIpAddress = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *Instance) SetResourceType(v string) *Instance { + s.ResourceType = &v + return s +} + +// SetSshKeyName sets the SshKeyName field's value. +func (s *Instance) SetSshKeyName(v string) *Instance { + s.SshKeyName = &v + return s +} + +// SetState sets the State field's value. +func (s *Instance) SetState(v *InstanceState) *Instance { + s.State = v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *Instance) SetSupportCode(v string) *Instance { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *Instance) SetTags(v []*Tag) *Instance { + s.Tags = v + return s +} + +// SetUsername sets the Username field's value. +func (s *Instance) SetUsername(v string) *Instance { + s.Username = &v + return s +} + +// The parameters for gaining temporary access to one of your Amazon Lightsail +// instances. +type InstanceAccessDetails struct { + _ struct{} `type:"structure"` + + // For SSH access, the public key to use when accessing your instance For OpenSSH + // clients (e.g., command line SSH), you should save this value to tempkey-cert.pub. + CertKey *string `locationName:"certKey" type:"string"` + + // For SSH access, the date on which the temporary keys expire. + ExpiresAt *time.Time `locationName:"expiresAt" type:"timestamp"` + + // Describes the public SSH host keys or the RDP certificate. + HostKeys []*HostKeyAttributes `locationName:"hostKeys" type:"list"` + + // The name of this Amazon Lightsail instance. + InstanceName *string `locationName:"instanceName" type:"string"` + + // The public IP address of the Amazon Lightsail instance. + IpAddress *string `locationName:"ipAddress" type:"string"` + + // For RDP access, the password for your Amazon Lightsail instance. Password + // will be an empty string if the password for your new instance is not ready + // yet. When you create an instance, it can take up to 15 minutes for the instance + // to be ready. + // + // If you create an instance using any key pair other than the default (LightsailDefaultKeyPair), + // password will always be an empty string. + // + // If you change the Administrator password on the instance, Lightsail will + // continue to return the original password value. When accessing the instance + // using RDP, you need to manually enter the Administrator password after changing + // it from the default. + Password *string `locationName:"password" type:"string"` + + // For a Windows Server-based instance, an object with the data you can use + // to retrieve your password. This is only needed if password is empty and the + // instance is not new (and therefore the password is not ready yet). When you + // create an instance, it can take up to 15 minutes for the instance to be ready. + PasswordData *PasswordData `locationName:"passwordData" type:"structure"` + + // For SSH access, the temporary private key. For OpenSSH clients (e.g., command + // line SSH), you should save this value to tempkey). + PrivateKey *string `locationName:"privateKey" type:"string"` + + // The protocol for these Amazon Lightsail instance access details. + Protocol *string `locationName:"protocol" type:"string" enum:"InstanceAccessProtocol"` + + // The user name to use when logging in to the Amazon Lightsail instance. + Username *string `locationName:"username" type:"string"` +} + +// String returns the string representation +func (s InstanceAccessDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceAccessDetails) GoString() string { + return s.String() +} + +// SetCertKey sets the CertKey field's value. +func (s *InstanceAccessDetails) SetCertKey(v string) *InstanceAccessDetails { + s.CertKey = &v + return s +} + +// SetExpiresAt sets the ExpiresAt field's value. +func (s *InstanceAccessDetails) SetExpiresAt(v time.Time) *InstanceAccessDetails { + s.ExpiresAt = &v + return s +} + +// SetHostKeys sets the HostKeys field's value. +func (s *InstanceAccessDetails) SetHostKeys(v []*HostKeyAttributes) *InstanceAccessDetails { + s.HostKeys = v + return s +} + +// SetInstanceName sets the InstanceName field's value. +func (s *InstanceAccessDetails) SetInstanceName(v string) *InstanceAccessDetails { + s.InstanceName = &v + return s +} + +// SetIpAddress sets the IpAddress field's value. +func (s *InstanceAccessDetails) SetIpAddress(v string) *InstanceAccessDetails { + s.IpAddress = &v + return s +} + +// SetPassword sets the Password field's value. +func (s *InstanceAccessDetails) SetPassword(v string) *InstanceAccessDetails { + s.Password = &v + return s +} + +// SetPasswordData sets the PasswordData field's value. +func (s *InstanceAccessDetails) SetPasswordData(v *PasswordData) *InstanceAccessDetails { + s.PasswordData = v + return s +} + +// SetPrivateKey sets the PrivateKey field's value. +func (s *InstanceAccessDetails) SetPrivateKey(v string) *InstanceAccessDetails { + s.PrivateKey = &v + return s +} + +// SetProtocol sets the Protocol field's value. +func (s *InstanceAccessDetails) SetProtocol(v string) *InstanceAccessDetails { + s.Protocol = &v + return s +} + +// SetUsername sets the Username field's value. +func (s *InstanceAccessDetails) SetUsername(v string) *InstanceAccessDetails { + s.Username = &v + return s +} + +// Describes the Amazon Elastic Compute Cloud instance and related resources +// to be created using the create cloud formation stack operation. +type InstanceEntry struct { + _ struct{} `type:"structure"` + + // The Availability Zone for the new Amazon EC2 instance. + // + // AvailabilityZone is a required field + AvailabilityZone *string `locationName:"availabilityZone" type:"string" required:"true"` + + // The instance type (e.g., t2.micro) to use for the new Amazon EC2 instance. + // + // InstanceType is a required field + InstanceType *string `locationName:"instanceType" type:"string" required:"true"` + + // The port configuration to use for the new Amazon EC2 instance. + // + // The following configuration options are available: + // + // * DEFAULT — Use the default firewall settings from the image. + // + // * INSTANCE — Use the firewall settings from the source Lightsail instance. + // + // * NONE — Default to Amazon EC2. + // + // * CLOSED — All ports closed. + // + // PortInfoSource is a required field + PortInfoSource *string `locationName:"portInfoSource" type:"string" required:"true" enum:"PortInfoSourceType"` + + // The name of the export snapshot record, which contains the exported Lightsail + // instance snapshot that will be used as the source of the new Amazon EC2 instance. + // + // Use the get export snapshot records operation to get a list of export snapshot + // records that you can use to create a CloudFormation stack. + // + // SourceName is a required field + SourceName *string `locationName:"sourceName" type:"string" required:"true"` + + // A launch script you can create that configures a server with additional user + // data. For example, you might want to run apt-get -y update. + // + // Depending on the machine image you choose, the command to get software on + // your instance varies. Amazon Linux and CentOS use yum, Debian and Ubuntu + // use apt-get, and FreeBSD uses pkg. + UserData *string `locationName:"userData" type:"string"` +} + +// String returns the string representation +func (s InstanceEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceEntry) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *InstanceEntry) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "InstanceEntry"} + if s.AvailabilityZone == nil { + invalidParams.Add(request.NewErrParamRequired("AvailabilityZone")) + } + if s.InstanceType == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceType")) + } + if s.PortInfoSource == nil { + invalidParams.Add(request.NewErrParamRequired("PortInfoSource")) + } + if s.SourceName == nil { + invalidParams.Add(request.NewErrParamRequired("SourceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *InstanceEntry) SetAvailabilityZone(v string) *InstanceEntry { + s.AvailabilityZone = &v + return s +} + +// SetInstanceType sets the InstanceType field's value. +func (s *InstanceEntry) SetInstanceType(v string) *InstanceEntry { + s.InstanceType = &v + return s +} + +// SetPortInfoSource sets the PortInfoSource field's value. +func (s *InstanceEntry) SetPortInfoSource(v string) *InstanceEntry { + s.PortInfoSource = &v + return s +} + +// SetSourceName sets the SourceName field's value. +func (s *InstanceEntry) SetSourceName(v string) *InstanceEntry { + s.SourceName = &v + return s +} + +// SetUserData sets the UserData field's value. +func (s *InstanceEntry) SetUserData(v string) *InstanceEntry { + s.UserData = &v + return s +} + +// Describes the hardware for the instance. +type InstanceHardware struct { + _ struct{} `type:"structure"` + + // The number of vCPUs the instance has. + CpuCount *int64 `locationName:"cpuCount" type:"integer"` + + // The disks attached to the instance. + Disks []*Disk `locationName:"disks" type:"list"` + + // The amount of RAM in GB on the instance (e.g., 1.0). + RamSizeInGb *float64 `locationName:"ramSizeInGb" type:"float"` +} + +// String returns the string representation +func (s InstanceHardware) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceHardware) GoString() string { + return s.String() +} + +// SetCpuCount sets the CpuCount field's value. +func (s *InstanceHardware) SetCpuCount(v int64) *InstanceHardware { + s.CpuCount = &v + return s +} + +// SetDisks sets the Disks field's value. +func (s *InstanceHardware) SetDisks(v []*Disk) *InstanceHardware { + s.Disks = v + return s +} + +// SetRamSizeInGb sets the RamSizeInGb field's value. +func (s *InstanceHardware) SetRamSizeInGb(v float64) *InstanceHardware { + s.RamSizeInGb = &v + return s +} + +// Describes information about the health of the instance. +type InstanceHealthSummary struct { + _ struct{} `type:"structure"` + + // Describes the overall instance health. Valid values are below. + InstanceHealth *string `locationName:"instanceHealth" type:"string" enum:"InstanceHealthState"` + + // More information about the instance health. If the instanceHealth is healthy, + // then an instanceHealthReason value is not provided. + // + // If instanceHealth is initial, the instanceHealthReason value can be one of + // the following: + // + // * Lb.RegistrationInProgress - The target instance is in the process of + // being registered with the load balancer. + // + // * Lb.InitialHealthChecking - The Lightsail load balancer is still sending + // the target instance the minimum number of health checks required to determine + // its health status. + // + // If instanceHealth is unhealthy, the instanceHealthReason value can be one + // of the following: + // + // * Instance.ResponseCodeMismatch - The health checks did not return an + // expected HTTP code. + // + // * Instance.Timeout - The health check requests timed out. + // + // * Instance.FailedHealthChecks - The health checks failed because the connection + // to the target instance timed out, the target instance response was malformed, + // or the target instance failed the health check for an unknown reason. + // + // * Lb.InternalError - The health checks failed due to an internal error. + // + // If instanceHealth is unused, the instanceHealthReason value can be one of + // the following: + // + // * Instance.NotRegistered - The target instance is not registered with + // the target group. + // + // * Instance.NotInUse - The target group is not used by any load balancer, + // or the target instance is in an Availability Zone that is not enabled + // for its load balancer. + // + // * Instance.IpUnusable - The target IP address is reserved for use by a + // Lightsail load balancer. + // + // * Instance.InvalidState - The target is in the stopped or terminated state. + // + // If instanceHealth is draining, the instanceHealthReason value can be one + // of the following: + // + // * Instance.DeregistrationInProgress - The target instance is in the process + // of being deregistered and the deregistration delay period has not expired. + InstanceHealthReason *string `locationName:"instanceHealthReason" type:"string" enum:"InstanceHealthReason"` + + // The name of the Lightsail instance for which you are requesting health check + // data. + InstanceName *string `locationName:"instanceName" type:"string"` +} + +// String returns the string representation +func (s InstanceHealthSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceHealthSummary) GoString() string { + return s.String() +} + +// SetInstanceHealth sets the InstanceHealth field's value. +func (s *InstanceHealthSummary) SetInstanceHealth(v string) *InstanceHealthSummary { + s.InstanceHealth = &v + return s +} + +// SetInstanceHealthReason sets the InstanceHealthReason field's value. +func (s *InstanceHealthSummary) SetInstanceHealthReason(v string) *InstanceHealthSummary { + s.InstanceHealthReason = &v + return s +} + +// SetInstanceName sets the InstanceName field's value. +func (s *InstanceHealthSummary) SetInstanceName(v string) *InstanceHealthSummary { + s.InstanceName = &v + return s +} + +// Describes monthly data transfer rates and port information for an instance. +type InstanceNetworking struct { + _ struct{} `type:"structure"` + + // The amount of data in GB allocated for monthly data transfers. + MonthlyTransfer *MonthlyTransfer `locationName:"monthlyTransfer" type:"structure"` + + // An array of key-value pairs containing information about the ports on the + // instance. + Ports []*InstancePortInfo `locationName:"ports" type:"list"` +} + +// String returns the string representation +func (s InstanceNetworking) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceNetworking) GoString() string { + return s.String() +} + +// SetMonthlyTransfer sets the MonthlyTransfer field's value. +func (s *InstanceNetworking) SetMonthlyTransfer(v *MonthlyTransfer) *InstanceNetworking { + s.MonthlyTransfer = v + return s +} + +// SetPorts sets the Ports field's value. +func (s *InstanceNetworking) SetPorts(v []*InstancePortInfo) *InstanceNetworking { + s.Ports = v + return s +} + +// Describes information about the instance ports. +type InstancePortInfo struct { + _ struct{} `type:"structure"` + + // The access direction (inbound or outbound). + AccessDirection *string `locationName:"accessDirection" type:"string" enum:"AccessDirection"` + + // The location from which access is allowed (e.g., Anywhere (0.0.0.0/0)). + AccessFrom *string `locationName:"accessFrom" type:"string"` + + // The type of access (Public or Private). + AccessType *string `locationName:"accessType" type:"string" enum:"PortAccessType"` + + // The common name. + CommonName *string `locationName:"commonName" type:"string"` + + // The first port in the range. + FromPort *int64 `locationName:"fromPort" type:"integer"` + + // The protocol being used. Can be one of the following. + // + // * tcp - Transmission Control Protocol (TCP) provides reliable, ordered, + // and error-checked delivery of streamed data between applications running + // on hosts communicating by an IP network. If you have an application that + // doesn't require reliable data stream service, use UDP instead. + // + // * all - All transport layer protocol types. For more general information, + // see Transport layer (https://en.wikipedia.org/wiki/Transport_layer) on + // Wikipedia. + // + // * udp - With User Datagram Protocol (UDP), computer applications can send + // messages (or datagrams) to other hosts on an Internet Protocol (IP) network. + // Prior communications are not required to set up transmission channels + // or data paths. Applications that don't require reliable data stream service + // can use UDP, which provides a connectionless datagram service that emphasizes + // reduced latency over reliability. If you do require reliable data stream + // service, use TCP instead. + Protocol *string `locationName:"protocol" type:"string" enum:"NetworkProtocol"` + + // The last port in the range. + ToPort *int64 `locationName:"toPort" type:"integer"` +} + +// String returns the string representation +func (s InstancePortInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstancePortInfo) GoString() string { + return s.String() +} + +// SetAccessDirection sets the AccessDirection field's value. +func (s *InstancePortInfo) SetAccessDirection(v string) *InstancePortInfo { + s.AccessDirection = &v + return s +} + +// SetAccessFrom sets the AccessFrom field's value. +func (s *InstancePortInfo) SetAccessFrom(v string) *InstancePortInfo { + s.AccessFrom = &v + return s +} + +// SetAccessType sets the AccessType field's value. +func (s *InstancePortInfo) SetAccessType(v string) *InstancePortInfo { + s.AccessType = &v + return s +} + +// SetCommonName sets the CommonName field's value. +func (s *InstancePortInfo) SetCommonName(v string) *InstancePortInfo { + s.CommonName = &v + return s +} + +// SetFromPort sets the FromPort field's value. +func (s *InstancePortInfo) SetFromPort(v int64) *InstancePortInfo { + s.FromPort = &v + return s +} + +// SetProtocol sets the Protocol field's value. +func (s *InstancePortInfo) SetProtocol(v string) *InstancePortInfo { + s.Protocol = &v + return s +} + +// SetToPort sets the ToPort field's value. +func (s *InstancePortInfo) SetToPort(v int64) *InstancePortInfo { + s.ToPort = &v + return s +} + +// Describes the port state. +type InstancePortState struct { + _ struct{} `type:"structure"` + + // The first port in the range. + FromPort *int64 `locationName:"fromPort" type:"integer"` + + // The protocol being used. Can be one of the following. + // + // * tcp - Transmission Control Protocol (TCP) provides reliable, ordered, + // and error-checked delivery of streamed data between applications running + // on hosts communicating by an IP network. If you have an application that + // doesn't require reliable data stream service, use UDP instead. + // + // * all - All transport layer protocol types. For more general information, + // see Transport layer (https://en.wikipedia.org/wiki/Transport_layer) on + // Wikipedia. + // + // * udp - With User Datagram Protocol (UDP), computer applications can send + // messages (or datagrams) to other hosts on an Internet Protocol (IP) network. + // Prior communications are not required to set up transmission channels + // or data paths. Applications that don't require reliable data stream service + // can use UDP, which provides a connectionless datagram service that emphasizes + // reduced latency over reliability. If you do require reliable data stream + // service, use TCP instead. + Protocol *string `locationName:"protocol" type:"string" enum:"NetworkProtocol"` + + // Specifies whether the instance port is open or closed. + State *string `locationName:"state" type:"string" enum:"PortState"` + + // The last port in the range. + ToPort *int64 `locationName:"toPort" type:"integer"` +} + +// String returns the string representation +func (s InstancePortState) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstancePortState) GoString() string { + return s.String() +} + +// SetFromPort sets the FromPort field's value. +func (s *InstancePortState) SetFromPort(v int64) *InstancePortState { + s.FromPort = &v + return s +} + +// SetProtocol sets the Protocol field's value. +func (s *InstancePortState) SetProtocol(v string) *InstancePortState { + s.Protocol = &v + return s +} + +// SetState sets the State field's value. +func (s *InstancePortState) SetState(v string) *InstancePortState { + s.State = &v + return s +} + +// SetToPort sets the ToPort field's value. +func (s *InstancePortState) SetToPort(v int64) *InstancePortState { + s.ToPort = &v + return s +} + +// Describes the snapshot of the virtual private server, or instance. +type InstanceSnapshot struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the snapshot (e.g., arn:aws:lightsail:us-east-2:123456789101:InstanceSnapshot/d23b5706-3322-4d83-81e5-12345EXAMPLE). + Arn *string `locationName:"arn" type:"string"` + + // The timestamp when the snapshot was created (e.g., 1479907467.024). + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // An array of disk objects containing information about all block storage disks. + FromAttachedDisks []*Disk `locationName:"fromAttachedDisks" type:"list"` + + // The blueprint ID from which you created the snapshot (e.g., os_debian_8_3). + // A blueprint is a virtual private server (or instance) image used to create + // instances quickly. + FromBlueprintId *string `locationName:"fromBlueprintId" type:"string"` + + // The bundle ID from which you created the snapshot (e.g., micro_1_0). + FromBundleId *string `locationName:"fromBundleId" type:"string"` + + // The Amazon Resource Name (ARN) of the instance from which the snapshot was + // created (e.g., arn:aws:lightsail:us-east-2:123456789101:Instance/64b8404c-ccb1-430b-8daf-12345EXAMPLE). + FromInstanceArn *string `locationName:"fromInstanceArn" type:"string"` + + // The instance from which the snapshot was created. + FromInstanceName *string `locationName:"fromInstanceName" type:"string"` + + // The region name and Availability Zone where you created the snapshot. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the snapshot. + Name *string `locationName:"name" type:"string"` + + // The progress of the snapshot. + Progress *string `locationName:"progress" type:"string"` + + // The type of resource (usually InstanceSnapshot). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The size in GB of the SSD. + SizeInGb *int64 `locationName:"sizeInGb" type:"integer"` + + // The state the snapshot is in. + State *string `locationName:"state" type:"string" enum:"InstanceSnapshotState"` + + // The support code. Include this code in your email to support when you have + // questions about an instance or another resource in Lightsail. This code enables + // our support team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s InstanceSnapshot) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceSnapshot) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *InstanceSnapshot) SetArn(v string) *InstanceSnapshot { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *InstanceSnapshot) SetCreatedAt(v time.Time) *InstanceSnapshot { + s.CreatedAt = &v + return s +} + +// SetFromAttachedDisks sets the FromAttachedDisks field's value. +func (s *InstanceSnapshot) SetFromAttachedDisks(v []*Disk) *InstanceSnapshot { + s.FromAttachedDisks = v + return s +} + +// SetFromBlueprintId sets the FromBlueprintId field's value. +func (s *InstanceSnapshot) SetFromBlueprintId(v string) *InstanceSnapshot { + s.FromBlueprintId = &v + return s +} + +// SetFromBundleId sets the FromBundleId field's value. +func (s *InstanceSnapshot) SetFromBundleId(v string) *InstanceSnapshot { + s.FromBundleId = &v + return s +} + +// SetFromInstanceArn sets the FromInstanceArn field's value. +func (s *InstanceSnapshot) SetFromInstanceArn(v string) *InstanceSnapshot { + s.FromInstanceArn = &v + return s +} + +// SetFromInstanceName sets the FromInstanceName field's value. +func (s *InstanceSnapshot) SetFromInstanceName(v string) *InstanceSnapshot { + s.FromInstanceName = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *InstanceSnapshot) SetLocation(v *ResourceLocation) *InstanceSnapshot { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *InstanceSnapshot) SetName(v string) *InstanceSnapshot { + s.Name = &v + return s +} + +// SetProgress sets the Progress field's value. +func (s *InstanceSnapshot) SetProgress(v string) *InstanceSnapshot { + s.Progress = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *InstanceSnapshot) SetResourceType(v string) *InstanceSnapshot { + s.ResourceType = &v + return s +} + +// SetSizeInGb sets the SizeInGb field's value. +func (s *InstanceSnapshot) SetSizeInGb(v int64) *InstanceSnapshot { + s.SizeInGb = &v + return s +} + +// SetState sets the State field's value. +func (s *InstanceSnapshot) SetState(v string) *InstanceSnapshot { + s.State = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *InstanceSnapshot) SetSupportCode(v string) *InstanceSnapshot { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *InstanceSnapshot) SetTags(v []*Tag) *InstanceSnapshot { + s.Tags = v + return s +} + +// Describes an instance snapshot. +type InstanceSnapshotInfo struct { + _ struct{} `type:"structure"` + + // The blueprint ID from which the source instance (e.g., os_debian_8_3). + FromBlueprintId *string `locationName:"fromBlueprintId" type:"string"` + + // The bundle ID from which the source instance was created (e.g., micro_1_0). + FromBundleId *string `locationName:"fromBundleId" type:"string"` + + // A list of objects describing the disks that were attached to the source instance. + FromDiskInfo []*DiskInfo `locationName:"fromDiskInfo" type:"list"` +} + +// String returns the string representation +func (s InstanceSnapshotInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceSnapshotInfo) GoString() string { + return s.String() +} + +// SetFromBlueprintId sets the FromBlueprintId field's value. +func (s *InstanceSnapshotInfo) SetFromBlueprintId(v string) *InstanceSnapshotInfo { + s.FromBlueprintId = &v + return s +} + +// SetFromBundleId sets the FromBundleId field's value. +func (s *InstanceSnapshotInfo) SetFromBundleId(v string) *InstanceSnapshotInfo { + s.FromBundleId = &v + return s +} + +// SetFromDiskInfo sets the FromDiskInfo field's value. +func (s *InstanceSnapshotInfo) SetFromDiskInfo(v []*DiskInfo) *InstanceSnapshotInfo { + s.FromDiskInfo = v + return s +} + +// Describes the virtual private server (or instance) status. +type InstanceState struct { + _ struct{} `type:"structure"` + + // The status code for the instance. + Code *int64 `locationName:"code" type:"integer"` + + // The state of the instance (e.g., running or pending). + Name *string `locationName:"name" type:"string"` +} + +// String returns the string representation +func (s InstanceState) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceState) GoString() string { + return s.String() +} + +// SetCode sets the Code field's value. +func (s *InstanceState) SetCode(v int64) *InstanceState { + s.Code = &v + return s +} + +// SetName sets the Name field's value. +func (s *InstanceState) SetName(v string) *InstanceState { + s.Name = &v + return s +} + +type IsVpcPeeredInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s IsVpcPeeredInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IsVpcPeeredInput) GoString() string { + return s.String() +} + +type IsVpcPeeredOutput struct { + _ struct{} `type:"structure"` + + // Returns true if the Lightsail VPC is peered; otherwise, false. + IsPeered *bool `locationName:"isPeered" type:"boolean"` +} + +// String returns the string representation +func (s IsVpcPeeredOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s IsVpcPeeredOutput) GoString() string { + return s.String() +} + +// SetIsPeered sets the IsPeered field's value. +func (s *IsVpcPeeredOutput) SetIsPeered(v bool) *IsVpcPeeredOutput { + s.IsPeered = &v + return s +} + +// Describes the SSH key pair. +type KeyPair struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the key pair (e.g., arn:aws:lightsail:us-east-2:123456789101:KeyPair/05859e3d-331d-48ba-9034-12345EXAMPLE). + Arn *string `locationName:"arn" type:"string"` + + // The timestamp when the key pair was created (e.g., 1479816991.349). + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The RSA fingerprint of the key pair. + Fingerprint *string `locationName:"fingerprint" type:"string"` + + // The region name and Availability Zone where the key pair was created. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The friendly name of the SSH key pair. + Name *string `locationName:"name" type:"string"` + + // The resource type (usually KeyPair). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The support code. Include this code in your email to support when you have + // questions about an instance or another resource in Lightsail. This code enables + // our support team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s KeyPair) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s KeyPair) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *KeyPair) SetArn(v string) *KeyPair { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *KeyPair) SetCreatedAt(v time.Time) *KeyPair { + s.CreatedAt = &v + return s +} + +// SetFingerprint sets the Fingerprint field's value. +func (s *KeyPair) SetFingerprint(v string) *KeyPair { + s.Fingerprint = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *KeyPair) SetLocation(v *ResourceLocation) *KeyPair { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *KeyPair) SetName(v string) *KeyPair { + s.Name = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *KeyPair) SetResourceType(v string) *KeyPair { + s.ResourceType = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *KeyPair) SetSupportCode(v string) *KeyPair { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *KeyPair) SetTags(v []*Tag) *KeyPair { + s.Tags = v + return s +} + +// Describes the Lightsail load balancer. +type LoadBalancer struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the load balancer. + Arn *string `locationName:"arn" type:"string"` + + // A string to string map of the configuration options for your load balancer. + // Valid values are listed below. + ConfigurationOptions map[string]*string `locationName:"configurationOptions" type:"map"` + + // The date when your load balancer was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The DNS name of your Lightsail load balancer. + DnsName *string `locationName:"dnsName" type:"string"` + + // The path you specified to perform your health checks. If no path is specified, + // the load balancer tries to make a request to the default (root) page. + HealthCheckPath *string `locationName:"healthCheckPath" type:"string"` + + // An array of InstanceHealthSummary objects describing the health of the load + // balancer. + InstanceHealthSummary []*InstanceHealthSummary `locationName:"instanceHealthSummary" type:"list"` + + // The port where the load balancer will direct traffic to your Lightsail instances. + // For HTTP traffic, it's port 80. For HTTPS traffic, it's port 443. + InstancePort *int64 `locationName:"instancePort" type:"integer"` + + // The AWS Region where your load balancer was created (e.g., us-east-2a). Lightsail + // automatically creates your load balancer across Availability Zones. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the load balancer (e.g., my-load-balancer). + Name *string `locationName:"name" type:"string"` + + // The protocol you have enabled for your load balancer. Valid values are below. + // + // You can't just have HTTP_HTTPS, but you can have just HTTP. + Protocol *string `locationName:"protocol" type:"string" enum:"LoadBalancerProtocol"` + + // An array of public port settings for your load balancer. For HTTP, use port + // 80. For HTTPS, use port 443. + PublicPorts []*int64 `locationName:"publicPorts" type:"list"` + + // The resource type (e.g., LoadBalancer. + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The status of your load balancer. Valid values are below. + State *string `locationName:"state" type:"string" enum:"LoadBalancerState"` + + // The support code. Include this code in your email to support when you have + // questions about your Lightsail load balancer. This code enables our support + // team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` + + // An array of LoadBalancerTlsCertificateSummary objects that provide additional + // information about the SSL/TLS certificates. For example, if true, the certificate + // is attached to the load balancer. + TlsCertificateSummaries []*LoadBalancerTlsCertificateSummary `locationName:"tlsCertificateSummaries" type:"list"` +} + +// String returns the string representation +func (s LoadBalancer) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancer) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *LoadBalancer) SetArn(v string) *LoadBalancer { + s.Arn = &v + return s +} + +// SetConfigurationOptions sets the ConfigurationOptions field's value. +func (s *LoadBalancer) SetConfigurationOptions(v map[string]*string) *LoadBalancer { + s.ConfigurationOptions = v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *LoadBalancer) SetCreatedAt(v time.Time) *LoadBalancer { + s.CreatedAt = &v + return s +} + +// SetDnsName sets the DnsName field's value. +func (s *LoadBalancer) SetDnsName(v string) *LoadBalancer { + s.DnsName = &v + return s +} + +// SetHealthCheckPath sets the HealthCheckPath field's value. +func (s *LoadBalancer) SetHealthCheckPath(v string) *LoadBalancer { + s.HealthCheckPath = &v + return s +} + +// SetInstanceHealthSummary sets the InstanceHealthSummary field's value. +func (s *LoadBalancer) SetInstanceHealthSummary(v []*InstanceHealthSummary) *LoadBalancer { + s.InstanceHealthSummary = v + return s +} + +// SetInstancePort sets the InstancePort field's value. +func (s *LoadBalancer) SetInstancePort(v int64) *LoadBalancer { + s.InstancePort = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *LoadBalancer) SetLocation(v *ResourceLocation) *LoadBalancer { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *LoadBalancer) SetName(v string) *LoadBalancer { + s.Name = &v + return s +} + +// SetProtocol sets the Protocol field's value. +func (s *LoadBalancer) SetProtocol(v string) *LoadBalancer { + s.Protocol = &v + return s +} + +// SetPublicPorts sets the PublicPorts field's value. +func (s *LoadBalancer) SetPublicPorts(v []*int64) *LoadBalancer { + s.PublicPorts = v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *LoadBalancer) SetResourceType(v string) *LoadBalancer { + s.ResourceType = &v + return s +} + +// SetState sets the State field's value. +func (s *LoadBalancer) SetState(v string) *LoadBalancer { + s.State = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *LoadBalancer) SetSupportCode(v string) *LoadBalancer { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *LoadBalancer) SetTags(v []*Tag) *LoadBalancer { + s.Tags = v + return s +} + +// SetTlsCertificateSummaries sets the TlsCertificateSummaries field's value. +func (s *LoadBalancer) SetTlsCertificateSummaries(v []*LoadBalancerTlsCertificateSummary) *LoadBalancer { + s.TlsCertificateSummaries = v + return s +} + +// Describes a load balancer SSL/TLS certificate. +// +// TLS is just an updated, more secure version of Secure Socket Layer (SSL). +type LoadBalancerTlsCertificate struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the SSL/TLS certificate. + Arn *string `locationName:"arn" type:"string"` + + // The time when you created your SSL/TLS certificate. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The domain name for your SSL/TLS certificate. + DomainName *string `locationName:"domainName" type:"string"` + + // An array of LoadBalancerTlsCertificateDomainValidationRecord objects describing + // the records. + DomainValidationRecords []*LoadBalancerTlsCertificateDomainValidationRecord `locationName:"domainValidationRecords" type:"list"` + + // The reason for the SSL/TLS certificate validation failure. + FailureReason *string `locationName:"failureReason" type:"string" enum:"LoadBalancerTlsCertificateFailureReason"` + + // When true, the SSL/TLS certificate is attached to the Lightsail load balancer. + IsAttached *bool `locationName:"isAttached" type:"boolean"` + + // The time when the SSL/TLS certificate was issued. + IssuedAt *time.Time `locationName:"issuedAt" type:"timestamp"` + + // The issuer of the certificate. + Issuer *string `locationName:"issuer" type:"string"` + + // The algorithm that was used to generate the key pair (the public and private + // key). + KeyAlgorithm *string `locationName:"keyAlgorithm" type:"string"` + + // The load balancer name where your SSL/TLS certificate is attached. + LoadBalancerName *string `locationName:"loadBalancerName" type:"string"` + + // The AWS Region and Availability Zone where you created your certificate. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the SSL/TLS certificate (e.g., my-certificate). + Name *string `locationName:"name" type:"string"` + + // The timestamp when the SSL/TLS certificate expires. + NotAfter *time.Time `locationName:"notAfter" type:"timestamp"` + + // The timestamp when the SSL/TLS certificate is first valid. + NotBefore *time.Time `locationName:"notBefore" type:"timestamp"` + + // An object containing information about the status of Lightsail's managed + // renewal for the certificate. + RenewalSummary *LoadBalancerTlsCertificateRenewalSummary `locationName:"renewalSummary" type:"structure"` + + // The resource type (e.g., LoadBalancerTlsCertificate). + // + // * Instance - A Lightsail instance (a virtual private server) + // + // * StaticIp - A static IP address + // + // * KeyPair - The key pair used to connect to a Lightsail instance + // + // * InstanceSnapshot - A Lightsail instance snapshot + // + // * Domain - A DNS zone + // + // * PeeredVpc - A peered VPC + // + // * LoadBalancer - A Lightsail load balancer + // + // * LoadBalancerTlsCertificate - An SSL/TLS certificate associated with + // a Lightsail load balancer + // + // * Disk - A Lightsail block storage disk + // + // * DiskSnapshot - A block storage disk snapshot + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The reason the certificate was revoked. Valid values are below. + RevocationReason *string `locationName:"revocationReason" type:"string" enum:"LoadBalancerTlsCertificateRevocationReason"` + + // The timestamp when the SSL/TLS certificate was revoked. + RevokedAt *time.Time `locationName:"revokedAt" type:"timestamp"` + + // The serial number of the certificate. + Serial *string `locationName:"serial" type:"string"` + + // The algorithm that was used to sign the certificate. + SignatureAlgorithm *string `locationName:"signatureAlgorithm" type:"string"` + + // The status of the SSL/TLS certificate. Valid values are below. + Status *string `locationName:"status" type:"string" enum:"LoadBalancerTlsCertificateStatus"` + + // The name of the entity that is associated with the public key contained in + // the certificate. + Subject *string `locationName:"subject" type:"string"` + + // One or more domains or subdomains included in the certificate. This list + // contains the domain names that are bound to the public key that is contained + // in the certificate. The subject alternative names include the canonical domain + // name (CNAME) of the certificate and additional domain names that can be used + // to connect to the website, such as example.com, www.example.com, or m.example.com. + SubjectAlternativeNames []*string `locationName:"subjectAlternativeNames" type:"list"` + + // The support code. Include this code in your email to support when you have + // questions about your Lightsail load balancer or SSL/TLS certificate. This + // code enables our support team to look up your Lightsail information more + // easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s LoadBalancerTlsCertificate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancerTlsCertificate) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *LoadBalancerTlsCertificate) SetArn(v string) *LoadBalancerTlsCertificate { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *LoadBalancerTlsCertificate) SetCreatedAt(v time.Time) *LoadBalancerTlsCertificate { + s.CreatedAt = &v + return s +} + +// SetDomainName sets the DomainName field's value. +func (s *LoadBalancerTlsCertificate) SetDomainName(v string) *LoadBalancerTlsCertificate { + s.DomainName = &v + return s +} + +// SetDomainValidationRecords sets the DomainValidationRecords field's value. +func (s *LoadBalancerTlsCertificate) SetDomainValidationRecords(v []*LoadBalancerTlsCertificateDomainValidationRecord) *LoadBalancerTlsCertificate { + s.DomainValidationRecords = v + return s +} + +// SetFailureReason sets the FailureReason field's value. +func (s *LoadBalancerTlsCertificate) SetFailureReason(v string) *LoadBalancerTlsCertificate { + s.FailureReason = &v + return s +} + +// SetIsAttached sets the IsAttached field's value. +func (s *LoadBalancerTlsCertificate) SetIsAttached(v bool) *LoadBalancerTlsCertificate { + s.IsAttached = &v + return s +} + +// SetIssuedAt sets the IssuedAt field's value. +func (s *LoadBalancerTlsCertificate) SetIssuedAt(v time.Time) *LoadBalancerTlsCertificate { + s.IssuedAt = &v + return s +} + +// SetIssuer sets the Issuer field's value. +func (s *LoadBalancerTlsCertificate) SetIssuer(v string) *LoadBalancerTlsCertificate { + s.Issuer = &v + return s +} + +// SetKeyAlgorithm sets the KeyAlgorithm field's value. +func (s *LoadBalancerTlsCertificate) SetKeyAlgorithm(v string) *LoadBalancerTlsCertificate { + s.KeyAlgorithm = &v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *LoadBalancerTlsCertificate) SetLoadBalancerName(v string) *LoadBalancerTlsCertificate { + s.LoadBalancerName = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *LoadBalancerTlsCertificate) SetLocation(v *ResourceLocation) *LoadBalancerTlsCertificate { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *LoadBalancerTlsCertificate) SetName(v string) *LoadBalancerTlsCertificate { + s.Name = &v + return s +} + +// SetNotAfter sets the NotAfter field's value. +func (s *LoadBalancerTlsCertificate) SetNotAfter(v time.Time) *LoadBalancerTlsCertificate { + s.NotAfter = &v + return s +} + +// SetNotBefore sets the NotBefore field's value. +func (s *LoadBalancerTlsCertificate) SetNotBefore(v time.Time) *LoadBalancerTlsCertificate { + s.NotBefore = &v + return s +} + +// SetRenewalSummary sets the RenewalSummary field's value. +func (s *LoadBalancerTlsCertificate) SetRenewalSummary(v *LoadBalancerTlsCertificateRenewalSummary) *LoadBalancerTlsCertificate { + s.RenewalSummary = v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *LoadBalancerTlsCertificate) SetResourceType(v string) *LoadBalancerTlsCertificate { + s.ResourceType = &v + return s +} + +// SetRevocationReason sets the RevocationReason field's value. +func (s *LoadBalancerTlsCertificate) SetRevocationReason(v string) *LoadBalancerTlsCertificate { + s.RevocationReason = &v + return s +} + +// SetRevokedAt sets the RevokedAt field's value. +func (s *LoadBalancerTlsCertificate) SetRevokedAt(v time.Time) *LoadBalancerTlsCertificate { + s.RevokedAt = &v + return s +} + +// SetSerial sets the Serial field's value. +func (s *LoadBalancerTlsCertificate) SetSerial(v string) *LoadBalancerTlsCertificate { + s.Serial = &v + return s +} + +// SetSignatureAlgorithm sets the SignatureAlgorithm field's value. +func (s *LoadBalancerTlsCertificate) SetSignatureAlgorithm(v string) *LoadBalancerTlsCertificate { + s.SignatureAlgorithm = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *LoadBalancerTlsCertificate) SetStatus(v string) *LoadBalancerTlsCertificate { + s.Status = &v + return s +} + +// SetSubject sets the Subject field's value. +func (s *LoadBalancerTlsCertificate) SetSubject(v string) *LoadBalancerTlsCertificate { + s.Subject = &v + return s +} + +// SetSubjectAlternativeNames sets the SubjectAlternativeNames field's value. +func (s *LoadBalancerTlsCertificate) SetSubjectAlternativeNames(v []*string) *LoadBalancerTlsCertificate { + s.SubjectAlternativeNames = v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *LoadBalancerTlsCertificate) SetSupportCode(v string) *LoadBalancerTlsCertificate { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *LoadBalancerTlsCertificate) SetTags(v []*Tag) *LoadBalancerTlsCertificate { + s.Tags = v + return s +} + +// Contains information about the domain names on an SSL/TLS certificate that +// you will use to validate domain ownership. +type LoadBalancerTlsCertificateDomainValidationOption struct { + _ struct{} `type:"structure"` + + // The fully qualified domain name in the certificate request. + DomainName *string `locationName:"domainName" type:"string"` + + // The status of the domain validation. Valid values are listed below. + ValidationStatus *string `locationName:"validationStatus" type:"string" enum:"LoadBalancerTlsCertificateDomainStatus"` +} + +// String returns the string representation +func (s LoadBalancerTlsCertificateDomainValidationOption) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancerTlsCertificateDomainValidationOption) GoString() string { + return s.String() +} + +// SetDomainName sets the DomainName field's value. +func (s *LoadBalancerTlsCertificateDomainValidationOption) SetDomainName(v string) *LoadBalancerTlsCertificateDomainValidationOption { + s.DomainName = &v + return s +} + +// SetValidationStatus sets the ValidationStatus field's value. +func (s *LoadBalancerTlsCertificateDomainValidationOption) SetValidationStatus(v string) *LoadBalancerTlsCertificateDomainValidationOption { + s.ValidationStatus = &v + return s +} + +// Describes the validation record of each domain name in the SSL/TLS certificate. +type LoadBalancerTlsCertificateDomainValidationRecord struct { + _ struct{} `type:"structure"` + + // The domain name against which your SSL/TLS certificate was validated. + DomainName *string `locationName:"domainName" type:"string"` + + // A fully qualified domain name in the certificate. For example, example.com. + Name *string `locationName:"name" type:"string"` + + // The type of validation record. For example, CNAME for domain validation. + Type *string `locationName:"type" type:"string"` + + // The validation status. Valid values are listed below. + ValidationStatus *string `locationName:"validationStatus" type:"string" enum:"LoadBalancerTlsCertificateDomainStatus"` + + // The value for that type. + Value *string `locationName:"value" type:"string"` +} + +// String returns the string representation +func (s LoadBalancerTlsCertificateDomainValidationRecord) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancerTlsCertificateDomainValidationRecord) GoString() string { + return s.String() +} + +// SetDomainName sets the DomainName field's value. +func (s *LoadBalancerTlsCertificateDomainValidationRecord) SetDomainName(v string) *LoadBalancerTlsCertificateDomainValidationRecord { + s.DomainName = &v + return s +} + +// SetName sets the Name field's value. +func (s *LoadBalancerTlsCertificateDomainValidationRecord) SetName(v string) *LoadBalancerTlsCertificateDomainValidationRecord { + s.Name = &v + return s +} + +// SetType sets the Type field's value. +func (s *LoadBalancerTlsCertificateDomainValidationRecord) SetType(v string) *LoadBalancerTlsCertificateDomainValidationRecord { + s.Type = &v + return s +} + +// SetValidationStatus sets the ValidationStatus field's value. +func (s *LoadBalancerTlsCertificateDomainValidationRecord) SetValidationStatus(v string) *LoadBalancerTlsCertificateDomainValidationRecord { + s.ValidationStatus = &v + return s +} + +// SetValue sets the Value field's value. +func (s *LoadBalancerTlsCertificateDomainValidationRecord) SetValue(v string) *LoadBalancerTlsCertificateDomainValidationRecord { + s.Value = &v + return s +} + +// Contains information about the status of Lightsail's managed renewal for +// the certificate. +type LoadBalancerTlsCertificateRenewalSummary struct { + _ struct{} `type:"structure"` + + // Contains information about the validation of each domain name in the certificate, + // as it pertains to Lightsail's managed renewal. This is different from the + // initial validation that occurs as a result of the RequestCertificate request. + DomainValidationOptions []*LoadBalancerTlsCertificateDomainValidationOption `locationName:"domainValidationOptions" type:"list"` + + // The status of Lightsail's managed renewal of the certificate. Valid values + // are listed below. + RenewalStatus *string `locationName:"renewalStatus" type:"string" enum:"LoadBalancerTlsCertificateRenewalStatus"` +} + +// String returns the string representation +func (s LoadBalancerTlsCertificateRenewalSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancerTlsCertificateRenewalSummary) GoString() string { + return s.String() +} + +// SetDomainValidationOptions sets the DomainValidationOptions field's value. +func (s *LoadBalancerTlsCertificateRenewalSummary) SetDomainValidationOptions(v []*LoadBalancerTlsCertificateDomainValidationOption) *LoadBalancerTlsCertificateRenewalSummary { + s.DomainValidationOptions = v + return s +} + +// SetRenewalStatus sets the RenewalStatus field's value. +func (s *LoadBalancerTlsCertificateRenewalSummary) SetRenewalStatus(v string) *LoadBalancerTlsCertificateRenewalSummary { + s.RenewalStatus = &v + return s +} + +// Provides a summary of SSL/TLS certificate metadata. +type LoadBalancerTlsCertificateSummary struct { + _ struct{} `type:"structure"` + + // When true, the SSL/TLS certificate is attached to the Lightsail load balancer. + IsAttached *bool `locationName:"isAttached" type:"boolean"` + + // The name of the SSL/TLS certificate. + Name *string `locationName:"name" type:"string"` +} + +// String returns the string representation +func (s LoadBalancerTlsCertificateSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LoadBalancerTlsCertificateSummary) GoString() string { + return s.String() +} + +// SetIsAttached sets the IsAttached field's value. +func (s *LoadBalancerTlsCertificateSummary) SetIsAttached(v bool) *LoadBalancerTlsCertificateSummary { + s.IsAttached = &v + return s +} + +// SetName sets the Name field's value. +func (s *LoadBalancerTlsCertificateSummary) SetName(v string) *LoadBalancerTlsCertificateSummary { + s.Name = &v + return s +} + +// Describes a database log event. +type LogEvent struct { + _ struct{} `type:"structure"` + + // The timestamp when the database log event was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The message of the database log event. + Message *string `locationName:"message" type:"string"` +} + +// String returns the string representation +func (s LogEvent) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LogEvent) GoString() string { + return s.String() +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *LogEvent) SetCreatedAt(v time.Time) *LogEvent { + s.CreatedAt = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *LogEvent) SetMessage(v string) *LogEvent { + s.Message = &v + return s +} + +// Describes the metric data point. +type MetricDatapoint struct { + _ struct{} `type:"structure"` + + // The average. + Average *float64 `locationName:"average" type:"double"` + + // The maximum. + Maximum *float64 `locationName:"maximum" type:"double"` + + // The minimum. + Minimum *float64 `locationName:"minimum" type:"double"` + + // The sample count. + SampleCount *float64 `locationName:"sampleCount" type:"double"` + + // The sum. + Sum *float64 `locationName:"sum" type:"double"` + + // The timestamp (e.g., 1479816991.349). + Timestamp *time.Time `locationName:"timestamp" type:"timestamp"` + + // The unit. + Unit *string `locationName:"unit" type:"string" enum:"MetricUnit"` +} + +// String returns the string representation +func (s MetricDatapoint) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MetricDatapoint) GoString() string { + return s.String() +} + +// SetAverage sets the Average field's value. +func (s *MetricDatapoint) SetAverage(v float64) *MetricDatapoint { + s.Average = &v + return s +} + +// SetMaximum sets the Maximum field's value. +func (s *MetricDatapoint) SetMaximum(v float64) *MetricDatapoint { + s.Maximum = &v + return s +} + +// SetMinimum sets the Minimum field's value. +func (s *MetricDatapoint) SetMinimum(v float64) *MetricDatapoint { + s.Minimum = &v + return s +} + +// SetSampleCount sets the SampleCount field's value. +func (s *MetricDatapoint) SetSampleCount(v float64) *MetricDatapoint { + s.SampleCount = &v + return s +} + +// SetSum sets the Sum field's value. +func (s *MetricDatapoint) SetSum(v float64) *MetricDatapoint { + s.Sum = &v + return s +} + +// SetTimestamp sets the Timestamp field's value. +func (s *MetricDatapoint) SetTimestamp(v time.Time) *MetricDatapoint { + s.Timestamp = &v + return s +} + +// SetUnit sets the Unit field's value. +func (s *MetricDatapoint) SetUnit(v string) *MetricDatapoint { + s.Unit = &v + return s +} + +// Describes the monthly data transfer in and out of your virtual private server +// (or instance). +type MonthlyTransfer struct { + _ struct{} `type:"structure"` + + // The amount allocated per month (in GB). + GbPerMonthAllocated *int64 `locationName:"gbPerMonthAllocated" type:"integer"` +} + +// String returns the string representation +func (s MonthlyTransfer) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s MonthlyTransfer) GoString() string { + return s.String() +} + +// SetGbPerMonthAllocated sets the GbPerMonthAllocated field's value. +func (s *MonthlyTransfer) SetGbPerMonthAllocated(v int64) *MonthlyTransfer { + s.GbPerMonthAllocated = &v + return s +} + +type OpenInstancePublicPortsInput struct { + _ struct{} `type:"structure"` + + // The name of the instance for which you want to open the public ports. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` + + // An array of key-value pairs containing information about the port mappings. + // + // PortInfo is a required field + PortInfo *PortInfo `locationName:"portInfo" type:"structure" required:"true"` +} + +// String returns the string representation +func (s OpenInstancePublicPortsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s OpenInstancePublicPortsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *OpenInstancePublicPortsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "OpenInstancePublicPortsInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + if s.PortInfo == nil { + invalidParams.Add(request.NewErrParamRequired("PortInfo")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *OpenInstancePublicPortsInput) SetInstanceName(v string) *OpenInstancePublicPortsInput { + s.InstanceName = &v + return s +} + +// SetPortInfo sets the PortInfo field's value. +func (s *OpenInstancePublicPortsInput) SetPortInfo(v *PortInfo) *OpenInstancePublicPortsInput { + s.PortInfo = v + return s +} + +type OpenInstancePublicPortsOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operation. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s OpenInstancePublicPortsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s OpenInstancePublicPortsOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *OpenInstancePublicPortsOutput) SetOperation(v *Operation) *OpenInstancePublicPortsOutput { + s.Operation = v + return s +} + +// Describes the API operation. +type Operation struct { + _ struct{} `type:"structure"` + + // The timestamp when the operation was initialized (e.g., 1479816991.349). + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The error code. + ErrorCode *string `locationName:"errorCode" type:"string"` + + // The error details. + ErrorDetails *string `locationName:"errorDetails" type:"string"` + + // The ID of the operation. + Id *string `locationName:"id" type:"string"` + + // A Boolean value indicating whether the operation is terminal. + IsTerminal *bool `locationName:"isTerminal" type:"boolean"` + + // The region and Availability Zone. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // Details about the operation (e.g., Debian-1GB-Ohio-1). + OperationDetails *string `locationName:"operationDetails" type:"string"` + + // The type of operation. + OperationType *string `locationName:"operationType" type:"string" enum:"OperationType"` + + // The resource name. + ResourceName *string `locationName:"resourceName" type:"string"` + + // The resource type. + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The status of the operation. + Status *string `locationName:"status" type:"string" enum:"OperationStatus"` + + // The timestamp when the status was changed (e.g., 1479816991.349). + StatusChangedAt *time.Time `locationName:"statusChangedAt" type:"timestamp"` +} + +// String returns the string representation +func (s Operation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Operation) GoString() string { + return s.String() +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *Operation) SetCreatedAt(v time.Time) *Operation { + s.CreatedAt = &v + return s +} + +// SetErrorCode sets the ErrorCode field's value. +func (s *Operation) SetErrorCode(v string) *Operation { + s.ErrorCode = &v + return s +} + +// SetErrorDetails sets the ErrorDetails field's value. +func (s *Operation) SetErrorDetails(v string) *Operation { + s.ErrorDetails = &v + return s +} + +// SetId sets the Id field's value. +func (s *Operation) SetId(v string) *Operation { + s.Id = &v + return s +} + +// SetIsTerminal sets the IsTerminal field's value. +func (s *Operation) SetIsTerminal(v bool) *Operation { + s.IsTerminal = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *Operation) SetLocation(v *ResourceLocation) *Operation { + s.Location = v + return s +} + +// SetOperationDetails sets the OperationDetails field's value. +func (s *Operation) SetOperationDetails(v string) *Operation { + s.OperationDetails = &v + return s +} + +// SetOperationType sets the OperationType field's value. +func (s *Operation) SetOperationType(v string) *Operation { + s.OperationType = &v + return s +} + +// SetResourceName sets the ResourceName field's value. +func (s *Operation) SetResourceName(v string) *Operation { + s.ResourceName = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *Operation) SetResourceType(v string) *Operation { + s.ResourceType = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *Operation) SetStatus(v string) *Operation { + s.Status = &v + return s +} + +// SetStatusChangedAt sets the StatusChangedAt field's value. +func (s *Operation) SetStatusChangedAt(v time.Time) *Operation { + s.StatusChangedAt = &v + return s +} + +// The password data for the Windows Server-based instance, including the ciphertext +// and the key pair name. +type PasswordData struct { + _ struct{} `type:"structure"` + + // The encrypted password. Ciphertext will be an empty string if access to your + // new instance is not ready yet. When you create an instance, it can take up + // to 15 minutes for the instance to be ready. + // + // If you use the default key pair (LightsailDefaultKeyPair), the decrypted + // password will be available in the password field. + // + // If you are using a custom key pair, you need to use your own means of decryption. + // + // If you change the Administrator password on the instance, Lightsail will + // continue to return the original ciphertext value. When accessing the instance + // using RDP, you need to manually enter the Administrator password after changing + // it from the default. + Ciphertext *string `locationName:"ciphertext" type:"string"` + + // The name of the key pair that you used when creating your instance. If no + // key pair name was specified when creating the instance, Lightsail uses the + // default key pair (LightsailDefaultKeyPair). + // + // If you are using a custom key pair, you need to use your own means of decrypting + // your password using the ciphertext. Lightsail creates the ciphertext by encrypting + // your password with the public key part of this key pair. + KeyPairName *string `locationName:"keyPairName" type:"string"` +} + +// String returns the string representation +func (s PasswordData) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PasswordData) GoString() string { + return s.String() +} + +// SetCiphertext sets the Ciphertext field's value. +func (s *PasswordData) SetCiphertext(v string) *PasswordData { + s.Ciphertext = &v + return s +} + +// SetKeyPairName sets the KeyPairName field's value. +func (s *PasswordData) SetKeyPairName(v string) *PasswordData { + s.KeyPairName = &v + return s +} + +type PeerVpcInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s PeerVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PeerVpcInput) GoString() string { + return s.String() +} + +type PeerVpcOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operation. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s PeerVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PeerVpcOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *PeerVpcOutput) SetOperation(v *Operation) *PeerVpcOutput { + s.Operation = v + return s +} + +// Describes a pending database maintenance action. +type PendingMaintenanceAction struct { + _ struct{} `type:"structure"` + + // The type of pending database maintenance action. + Action *string `locationName:"action" type:"string"` + + // The effective date of the pending database maintenance action. + CurrentApplyDate *time.Time `locationName:"currentApplyDate" type:"timestamp"` + + // Additional detail about the pending database maintenance action. + Description *string `locationName:"description" type:"string"` +} + +// String returns the string representation +func (s PendingMaintenanceAction) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PendingMaintenanceAction) GoString() string { + return s.String() +} + +// SetAction sets the Action field's value. +func (s *PendingMaintenanceAction) SetAction(v string) *PendingMaintenanceAction { + s.Action = &v + return s +} + +// SetCurrentApplyDate sets the CurrentApplyDate field's value. +func (s *PendingMaintenanceAction) SetCurrentApplyDate(v time.Time) *PendingMaintenanceAction { + s.CurrentApplyDate = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *PendingMaintenanceAction) SetDescription(v string) *PendingMaintenanceAction { + s.Description = &v + return s +} + +// Describes a pending database value modification. +type PendingModifiedRelationalDatabaseValues struct { + _ struct{} `type:"structure"` + + // A Boolean value indicating whether automated backup retention is enabled. + BackupRetentionEnabled *bool `locationName:"backupRetentionEnabled" type:"boolean"` + + // The database engine version. + EngineVersion *string `locationName:"engineVersion" type:"string"` + + // The password for the master user of the database. + MasterUserPassword *string `locationName:"masterUserPassword" type:"string"` +} + +// String returns the string representation +func (s PendingModifiedRelationalDatabaseValues) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PendingModifiedRelationalDatabaseValues) GoString() string { + return s.String() +} + +// SetBackupRetentionEnabled sets the BackupRetentionEnabled field's value. +func (s *PendingModifiedRelationalDatabaseValues) SetBackupRetentionEnabled(v bool) *PendingModifiedRelationalDatabaseValues { + s.BackupRetentionEnabled = &v + return s +} + +// SetEngineVersion sets the EngineVersion field's value. +func (s *PendingModifiedRelationalDatabaseValues) SetEngineVersion(v string) *PendingModifiedRelationalDatabaseValues { + s.EngineVersion = &v + return s +} + +// SetMasterUserPassword sets the MasterUserPassword field's value. +func (s *PendingModifiedRelationalDatabaseValues) SetMasterUserPassword(v string) *PendingModifiedRelationalDatabaseValues { + s.MasterUserPassword = &v + return s +} + +// Describes information about the ports on your virtual private server (or +// instance). +type PortInfo struct { + _ struct{} `type:"structure"` + + // The first port in the range. + FromPort *int64 `locationName:"fromPort" type:"integer"` + + // The protocol. + Protocol *string `locationName:"protocol" type:"string" enum:"NetworkProtocol"` + + // The last port in the range. + ToPort *int64 `locationName:"toPort" type:"integer"` +} + +// String returns the string representation +func (s PortInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PortInfo) GoString() string { + return s.String() +} + +// SetFromPort sets the FromPort field's value. +func (s *PortInfo) SetFromPort(v int64) *PortInfo { + s.FromPort = &v + return s +} + +// SetProtocol sets the Protocol field's value. +func (s *PortInfo) SetProtocol(v string) *PortInfo { + s.Protocol = &v + return s +} + +// SetToPort sets the ToPort field's value. +func (s *PortInfo) SetToPort(v int64) *PortInfo { + s.ToPort = &v + return s +} + +type PutInstancePublicPortsInput struct { + _ struct{} `type:"structure"` + + // The Lightsail instance name of the public port(s) you are setting. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` + + // Specifies information about the public port(s). + // + // PortInfos is a required field + PortInfos []*PortInfo `locationName:"portInfos" type:"list" required:"true"` +} + +// String returns the string representation +func (s PutInstancePublicPortsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutInstancePublicPortsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutInstancePublicPortsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PutInstancePublicPortsInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + if s.PortInfos == nil { + invalidParams.Add(request.NewErrParamRequired("PortInfos")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *PutInstancePublicPortsInput) SetInstanceName(v string) *PutInstancePublicPortsInput { + s.InstanceName = &v + return s +} + +// SetPortInfos sets the PortInfos field's value. +func (s *PutInstancePublicPortsInput) SetPortInfos(v []*PortInfo) *PutInstancePublicPortsInput { + s.PortInfos = v + return s +} + +type PutInstancePublicPortsOutput struct { + _ struct{} `type:"structure"` + + // Describes metadata about the operation you just executed. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s PutInstancePublicPortsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutInstancePublicPortsOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *PutInstancePublicPortsOutput) SetOperation(v *Operation) *PutInstancePublicPortsOutput { + s.Operation = v + return s +} + +type RebootInstanceInput struct { + _ struct{} `type:"structure"` + + // The name of the instance to reboot. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s RebootInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RebootInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RebootInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RebootInstanceInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *RebootInstanceInput) SetInstanceName(v string) *RebootInstanceInput { + s.InstanceName = &v + return s +} + +type RebootInstanceOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s RebootInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RebootInstanceOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *RebootInstanceOutput) SetOperations(v []*Operation) *RebootInstanceOutput { + s.Operations = v + return s +} + +type RebootRelationalDatabaseInput struct { + _ struct{} `type:"structure"` + + // The name of your database to reboot. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` +} + +// String returns the string representation +func (s RebootRelationalDatabaseInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RebootRelationalDatabaseInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *RebootRelationalDatabaseInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "RebootRelationalDatabaseInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *RebootRelationalDatabaseInput) SetRelationalDatabaseName(v string) *RebootRelationalDatabaseInput { + s.RelationalDatabaseName = &v + return s +} + +type RebootRelationalDatabaseOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your reboot relational database request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s RebootRelationalDatabaseOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RebootRelationalDatabaseOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *RebootRelationalDatabaseOutput) SetOperations(v []*Operation) *RebootRelationalDatabaseOutput { + s.Operations = v + return s +} + +// Describes the AWS Region. +type Region struct { + _ struct{} `type:"structure"` + + // The Availability Zones. Follows the format us-east-2a (case-sensitive). + AvailabilityZones []*AvailabilityZone `locationName:"availabilityZones" type:"list"` + + // The continent code (e.g., NA, meaning North America). + ContinentCode *string `locationName:"continentCode" type:"string"` + + // The description of the AWS Region (e.g., This region is recommended to serve + // users in the eastern United States and eastern Canada). + Description *string `locationName:"description" type:"string"` + + // The display name (e.g., Ohio). + DisplayName *string `locationName:"displayName" type:"string"` + + // The region name (e.g., us-east-2). + Name *string `locationName:"name" type:"string" enum:"RegionName"` + + // The Availability Zones for databases. Follows the format us-east-2a (case-sensitive). + RelationalDatabaseAvailabilityZones []*AvailabilityZone `locationName:"relationalDatabaseAvailabilityZones" type:"list"` +} + +// String returns the string representation +func (s Region) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Region) GoString() string { + return s.String() +} + +// SetAvailabilityZones sets the AvailabilityZones field's value. +func (s *Region) SetAvailabilityZones(v []*AvailabilityZone) *Region { + s.AvailabilityZones = v + return s +} + +// SetContinentCode sets the ContinentCode field's value. +func (s *Region) SetContinentCode(v string) *Region { + s.ContinentCode = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *Region) SetDescription(v string) *Region { + s.Description = &v + return s +} + +// SetDisplayName sets the DisplayName field's value. +func (s *Region) SetDisplayName(v string) *Region { + s.DisplayName = &v + return s +} + +// SetName sets the Name field's value. +func (s *Region) SetName(v string) *Region { + s.Name = &v + return s +} + +// SetRelationalDatabaseAvailabilityZones sets the RelationalDatabaseAvailabilityZones field's value. +func (s *Region) SetRelationalDatabaseAvailabilityZones(v []*AvailabilityZone) *Region { + s.RelationalDatabaseAvailabilityZones = v + return s +} + +// Describes a database. +type RelationalDatabase struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the database. + Arn *string `locationName:"arn" type:"string"` + + // A Boolean value indicating whether automated backup retention is enabled + // for the database. + BackupRetentionEnabled *bool `locationName:"backupRetentionEnabled" type:"boolean"` + + // The timestamp when the database was created. Formatted in Unix time. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The database software (for example, MySQL). + Engine *string `locationName:"engine" type:"string"` + + // The database engine version (for example, 5.7.23). + EngineVersion *string `locationName:"engineVersion" type:"string"` + + // Describes the hardware of the database. + Hardware *RelationalDatabaseHardware `locationName:"hardware" type:"structure"` + + // The latest point in time to which the database can be restored. Formatted + // in Unix time. + LatestRestorableTime *time.Time `locationName:"latestRestorableTime" type:"timestamp"` + + // The Region name and Availability Zone where the database is located. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the master database created when the Lightsail database resource + // is created. + MasterDatabaseName *string `locationName:"masterDatabaseName" type:"string"` + + // The master endpoint for the database. + MasterEndpoint *RelationalDatabaseEndpoint `locationName:"masterEndpoint" type:"structure"` + + // The master user name of the database. + MasterUsername *string `locationName:"masterUsername" type:"string"` + + // The unique name of the database resource in Lightsail. + Name *string `locationName:"name" type:"string"` + + // The status of parameter updates for the database. + ParameterApplyStatus *string `locationName:"parameterApplyStatus" type:"string"` + + // Describes the pending maintenance actions for the database. + PendingMaintenanceActions []*PendingMaintenanceAction `locationName:"pendingMaintenanceActions" type:"list"` + + // Describes pending database value modifications. + PendingModifiedValues *PendingModifiedRelationalDatabaseValues `locationName:"pendingModifiedValues" type:"structure"` + + // The daily time range during which automated backups are created for the database + // (for example, 16:00-16:30). + PreferredBackupWindow *string `locationName:"preferredBackupWindow" type:"string"` + + // The weekly time range during which system maintenance can occur on the database. + // + // In the format ddd:hh24:mi-ddd:hh24:mi. For example, Tue:17:00-Tue:17:30. + PreferredMaintenanceWindow *string `locationName:"preferredMaintenanceWindow" type:"string"` + + // A Boolean value indicating whether the database is publicly accessible. + PubliclyAccessible *bool `locationName:"publiclyAccessible" type:"boolean"` + + // The blueprint ID for the database. A blueprint describes the major engine + // version of a database. + RelationalDatabaseBlueprintId *string `locationName:"relationalDatabaseBlueprintId" type:"string"` + + // The bundle ID for the database. A bundle describes the performance specifications + // for your database. + RelationalDatabaseBundleId *string `locationName:"relationalDatabaseBundleId" type:"string"` + + // The Lightsail resource type for the database (for example, RelationalDatabase). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // Describes the secondary Availability Zone of a high availability database. + // + // The secondary database is used for failover support of a high availability + // database. + SecondaryAvailabilityZone *string `locationName:"secondaryAvailabilityZone" type:"string"` + + // Describes the current state of the database. + State *string `locationName:"state" type:"string"` + + // The support code for the database. Include this code in your email to support + // when you have questions about a database in Lightsail. This code enables + // our support team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s RelationalDatabase) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RelationalDatabase) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *RelationalDatabase) SetArn(v string) *RelationalDatabase { + s.Arn = &v + return s +} + +// SetBackupRetentionEnabled sets the BackupRetentionEnabled field's value. +func (s *RelationalDatabase) SetBackupRetentionEnabled(v bool) *RelationalDatabase { + s.BackupRetentionEnabled = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *RelationalDatabase) SetCreatedAt(v time.Time) *RelationalDatabase { + s.CreatedAt = &v + return s +} + +// SetEngine sets the Engine field's value. +func (s *RelationalDatabase) SetEngine(v string) *RelationalDatabase { + s.Engine = &v + return s +} + +// SetEngineVersion sets the EngineVersion field's value. +func (s *RelationalDatabase) SetEngineVersion(v string) *RelationalDatabase { + s.EngineVersion = &v + return s +} + +// SetHardware sets the Hardware field's value. +func (s *RelationalDatabase) SetHardware(v *RelationalDatabaseHardware) *RelationalDatabase { + s.Hardware = v + return s +} + +// SetLatestRestorableTime sets the LatestRestorableTime field's value. +func (s *RelationalDatabase) SetLatestRestorableTime(v time.Time) *RelationalDatabase { + s.LatestRestorableTime = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *RelationalDatabase) SetLocation(v *ResourceLocation) *RelationalDatabase { + s.Location = v + return s +} + +// SetMasterDatabaseName sets the MasterDatabaseName field's value. +func (s *RelationalDatabase) SetMasterDatabaseName(v string) *RelationalDatabase { + s.MasterDatabaseName = &v + return s +} + +// SetMasterEndpoint sets the MasterEndpoint field's value. +func (s *RelationalDatabase) SetMasterEndpoint(v *RelationalDatabaseEndpoint) *RelationalDatabase { + s.MasterEndpoint = v + return s +} + +// SetMasterUsername sets the MasterUsername field's value. +func (s *RelationalDatabase) SetMasterUsername(v string) *RelationalDatabase { + s.MasterUsername = &v + return s +} + +// SetName sets the Name field's value. +func (s *RelationalDatabase) SetName(v string) *RelationalDatabase { + s.Name = &v + return s +} + +// SetParameterApplyStatus sets the ParameterApplyStatus field's value. +func (s *RelationalDatabase) SetParameterApplyStatus(v string) *RelationalDatabase { + s.ParameterApplyStatus = &v + return s +} + +// SetPendingMaintenanceActions sets the PendingMaintenanceActions field's value. +func (s *RelationalDatabase) SetPendingMaintenanceActions(v []*PendingMaintenanceAction) *RelationalDatabase { + s.PendingMaintenanceActions = v + return s +} + +// SetPendingModifiedValues sets the PendingModifiedValues field's value. +func (s *RelationalDatabase) SetPendingModifiedValues(v *PendingModifiedRelationalDatabaseValues) *RelationalDatabase { + s.PendingModifiedValues = v + return s +} + +// SetPreferredBackupWindow sets the PreferredBackupWindow field's value. +func (s *RelationalDatabase) SetPreferredBackupWindow(v string) *RelationalDatabase { + s.PreferredBackupWindow = &v + return s +} + +// SetPreferredMaintenanceWindow sets the PreferredMaintenanceWindow field's value. +func (s *RelationalDatabase) SetPreferredMaintenanceWindow(v string) *RelationalDatabase { + s.PreferredMaintenanceWindow = &v + return s +} + +// SetPubliclyAccessible sets the PubliclyAccessible field's value. +func (s *RelationalDatabase) SetPubliclyAccessible(v bool) *RelationalDatabase { + s.PubliclyAccessible = &v + return s +} + +// SetRelationalDatabaseBlueprintId sets the RelationalDatabaseBlueprintId field's value. +func (s *RelationalDatabase) SetRelationalDatabaseBlueprintId(v string) *RelationalDatabase { + s.RelationalDatabaseBlueprintId = &v + return s +} + +// SetRelationalDatabaseBundleId sets the RelationalDatabaseBundleId field's value. +func (s *RelationalDatabase) SetRelationalDatabaseBundleId(v string) *RelationalDatabase { + s.RelationalDatabaseBundleId = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *RelationalDatabase) SetResourceType(v string) *RelationalDatabase { + s.ResourceType = &v + return s +} + +// SetSecondaryAvailabilityZone sets the SecondaryAvailabilityZone field's value. +func (s *RelationalDatabase) SetSecondaryAvailabilityZone(v string) *RelationalDatabase { + s.SecondaryAvailabilityZone = &v + return s +} + +// SetState sets the State field's value. +func (s *RelationalDatabase) SetState(v string) *RelationalDatabase { + s.State = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *RelationalDatabase) SetSupportCode(v string) *RelationalDatabase { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *RelationalDatabase) SetTags(v []*Tag) *RelationalDatabase { + s.Tags = v + return s +} + +// Describes a database image, or blueprint. A blueprint describes the major +// engine version of a database. +type RelationalDatabaseBlueprint struct { + _ struct{} `type:"structure"` + + // The ID for the database blueprint. + BlueprintId *string `locationName:"blueprintId" type:"string"` + + // The database software of the database blueprint (for example, MySQL). + Engine *string `locationName:"engine" type:"string" enum:"RelationalDatabaseEngine"` + + // The description of the database engine for the database blueprint. + EngineDescription *string `locationName:"engineDescription" type:"string"` + + // The database engine version for the database blueprint (for example, 5.7.23). + EngineVersion *string `locationName:"engineVersion" type:"string"` + + // The description of the database engine version for the database blueprint. + EngineVersionDescription *string `locationName:"engineVersionDescription" type:"string"` + + // A Boolean value indicating whether the engine version is the default for + // the database blueprint. + IsEngineDefault *bool `locationName:"isEngineDefault" type:"boolean"` +} + +// String returns the string representation +func (s RelationalDatabaseBlueprint) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RelationalDatabaseBlueprint) GoString() string { + return s.String() +} + +// SetBlueprintId sets the BlueprintId field's value. +func (s *RelationalDatabaseBlueprint) SetBlueprintId(v string) *RelationalDatabaseBlueprint { + s.BlueprintId = &v + return s +} + +// SetEngine sets the Engine field's value. +func (s *RelationalDatabaseBlueprint) SetEngine(v string) *RelationalDatabaseBlueprint { + s.Engine = &v + return s +} + +// SetEngineDescription sets the EngineDescription field's value. +func (s *RelationalDatabaseBlueprint) SetEngineDescription(v string) *RelationalDatabaseBlueprint { + s.EngineDescription = &v + return s +} + +// SetEngineVersion sets the EngineVersion field's value. +func (s *RelationalDatabaseBlueprint) SetEngineVersion(v string) *RelationalDatabaseBlueprint { + s.EngineVersion = &v + return s +} + +// SetEngineVersionDescription sets the EngineVersionDescription field's value. +func (s *RelationalDatabaseBlueprint) SetEngineVersionDescription(v string) *RelationalDatabaseBlueprint { + s.EngineVersionDescription = &v + return s +} + +// SetIsEngineDefault sets the IsEngineDefault field's value. +func (s *RelationalDatabaseBlueprint) SetIsEngineDefault(v bool) *RelationalDatabaseBlueprint { + s.IsEngineDefault = &v + return s +} + +// Describes a database bundle. A bundle describes the performance specifications +// of the database. +type RelationalDatabaseBundle struct { + _ struct{} `type:"structure"` + + // The ID for the database bundle. + BundleId *string `locationName:"bundleId" type:"string"` + + // The number of virtual CPUs (vCPUs) for the database bundle. + CpuCount *int64 `locationName:"cpuCount" type:"integer"` + + // The size of the disk for the database bundle. + DiskSizeInGb *int64 `locationName:"diskSizeInGb" type:"integer"` + + // A Boolean value indicating whether the database bundle is active. + IsActive *bool `locationName:"isActive" type:"boolean"` + + // A Boolean value indicating whether the database bundle is encrypted. + IsEncrypted *bool `locationName:"isEncrypted" type:"boolean"` + + // The name for the database bundle. + Name *string `locationName:"name" type:"string"` + + // The cost of the database bundle in US currency. + Price *float64 `locationName:"price" type:"float"` + + // The amount of RAM in GB (for example, 2.0) for the database bundle. + RamSizeInGb *float64 `locationName:"ramSizeInGb" type:"float"` + + // The data transfer rate per month in GB for the database bundle. + TransferPerMonthInGb *int64 `locationName:"transferPerMonthInGb" type:"integer"` +} + +// String returns the string representation +func (s RelationalDatabaseBundle) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RelationalDatabaseBundle) GoString() string { + return s.String() +} + +// SetBundleId sets the BundleId field's value. +func (s *RelationalDatabaseBundle) SetBundleId(v string) *RelationalDatabaseBundle { + s.BundleId = &v + return s +} + +// SetCpuCount sets the CpuCount field's value. +func (s *RelationalDatabaseBundle) SetCpuCount(v int64) *RelationalDatabaseBundle { + s.CpuCount = &v + return s +} + +// SetDiskSizeInGb sets the DiskSizeInGb field's value. +func (s *RelationalDatabaseBundle) SetDiskSizeInGb(v int64) *RelationalDatabaseBundle { + s.DiskSizeInGb = &v + return s +} + +// SetIsActive sets the IsActive field's value. +func (s *RelationalDatabaseBundle) SetIsActive(v bool) *RelationalDatabaseBundle { + s.IsActive = &v + return s +} + +// SetIsEncrypted sets the IsEncrypted field's value. +func (s *RelationalDatabaseBundle) SetIsEncrypted(v bool) *RelationalDatabaseBundle { + s.IsEncrypted = &v + return s +} + +// SetName sets the Name field's value. +func (s *RelationalDatabaseBundle) SetName(v string) *RelationalDatabaseBundle { + s.Name = &v + return s +} + +// SetPrice sets the Price field's value. +func (s *RelationalDatabaseBundle) SetPrice(v float64) *RelationalDatabaseBundle { + s.Price = &v + return s +} + +// SetRamSizeInGb sets the RamSizeInGb field's value. +func (s *RelationalDatabaseBundle) SetRamSizeInGb(v float64) *RelationalDatabaseBundle { + s.RamSizeInGb = &v + return s +} + +// SetTransferPerMonthInGb sets the TransferPerMonthInGb field's value. +func (s *RelationalDatabaseBundle) SetTransferPerMonthInGb(v int64) *RelationalDatabaseBundle { + s.TransferPerMonthInGb = &v + return s +} + +// Describes an endpoint for a database. +type RelationalDatabaseEndpoint struct { + _ struct{} `type:"structure"` + + // Specifies the DNS address of the database. + Address *string `locationName:"address" type:"string"` + + // Specifies the port that the database is listening on. + Port *int64 `locationName:"port" type:"integer"` +} + +// String returns the string representation +func (s RelationalDatabaseEndpoint) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RelationalDatabaseEndpoint) GoString() string { + return s.String() +} + +// SetAddress sets the Address field's value. +func (s *RelationalDatabaseEndpoint) SetAddress(v string) *RelationalDatabaseEndpoint { + s.Address = &v + return s +} + +// SetPort sets the Port field's value. +func (s *RelationalDatabaseEndpoint) SetPort(v int64) *RelationalDatabaseEndpoint { + s.Port = &v + return s +} + +// Describes an event for a database. +type RelationalDatabaseEvent struct { + _ struct{} `type:"structure"` + + // The timestamp when the database event was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The category that the database event belongs to. + EventCategories []*string `locationName:"eventCategories" type:"list"` + + // The message of the database event. + Message *string `locationName:"message" type:"string"` + + // The database that the database event relates to. + Resource *string `locationName:"resource" type:"string"` +} + +// String returns the string representation +func (s RelationalDatabaseEvent) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RelationalDatabaseEvent) GoString() string { + return s.String() +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *RelationalDatabaseEvent) SetCreatedAt(v time.Time) *RelationalDatabaseEvent { + s.CreatedAt = &v + return s +} + +// SetEventCategories sets the EventCategories field's value. +func (s *RelationalDatabaseEvent) SetEventCategories(v []*string) *RelationalDatabaseEvent { + s.EventCategories = v + return s +} + +// SetMessage sets the Message field's value. +func (s *RelationalDatabaseEvent) SetMessage(v string) *RelationalDatabaseEvent { + s.Message = &v + return s +} + +// SetResource sets the Resource field's value. +func (s *RelationalDatabaseEvent) SetResource(v string) *RelationalDatabaseEvent { + s.Resource = &v + return s +} + +// Describes the hardware of a database. +type RelationalDatabaseHardware struct { + _ struct{} `type:"structure"` + + // The number of vCPUs for the database. + CpuCount *int64 `locationName:"cpuCount" type:"integer"` + + // The size of the disk for the database. + DiskSizeInGb *int64 `locationName:"diskSizeInGb" type:"integer"` + + // The amount of RAM in GB for the database. + RamSizeInGb *float64 `locationName:"ramSizeInGb" type:"float"` +} + +// String returns the string representation +func (s RelationalDatabaseHardware) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RelationalDatabaseHardware) GoString() string { + return s.String() +} + +// SetCpuCount sets the CpuCount field's value. +func (s *RelationalDatabaseHardware) SetCpuCount(v int64) *RelationalDatabaseHardware { + s.CpuCount = &v + return s +} + +// SetDiskSizeInGb sets the DiskSizeInGb field's value. +func (s *RelationalDatabaseHardware) SetDiskSizeInGb(v int64) *RelationalDatabaseHardware { + s.DiskSizeInGb = &v + return s +} + +// SetRamSizeInGb sets the RamSizeInGb field's value. +func (s *RelationalDatabaseHardware) SetRamSizeInGb(v float64) *RelationalDatabaseHardware { + s.RamSizeInGb = &v + return s +} + +// Describes the parameters of a database. +type RelationalDatabaseParameter struct { + _ struct{} `type:"structure"` + + // Specifies the valid range of values for the parameter. + AllowedValues *string `locationName:"allowedValues" type:"string"` + + // Indicates when parameter updates are applied. + // + // Can be immediate or pending-reboot. + ApplyMethod *string `locationName:"applyMethod" type:"string"` + + // Specifies the engine-specific parameter type. + ApplyType *string `locationName:"applyType" type:"string"` + + // Specifies the valid data type for the parameter. + DataType *string `locationName:"dataType" type:"string"` + + // Provides a description of the parameter. + Description *string `locationName:"description" type:"string"` + + // A Boolean value indicating whether the parameter can be modified. + IsModifiable *bool `locationName:"isModifiable" type:"boolean"` + + // Specifies the name of the parameter. + ParameterName *string `locationName:"parameterName" type:"string"` + + // Specifies the value of the parameter. + ParameterValue *string `locationName:"parameterValue" type:"string"` +} + +// String returns the string representation +func (s RelationalDatabaseParameter) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RelationalDatabaseParameter) GoString() string { + return s.String() +} + +// SetAllowedValues sets the AllowedValues field's value. +func (s *RelationalDatabaseParameter) SetAllowedValues(v string) *RelationalDatabaseParameter { + s.AllowedValues = &v + return s +} + +// SetApplyMethod sets the ApplyMethod field's value. +func (s *RelationalDatabaseParameter) SetApplyMethod(v string) *RelationalDatabaseParameter { + s.ApplyMethod = &v + return s +} + +// SetApplyType sets the ApplyType field's value. +func (s *RelationalDatabaseParameter) SetApplyType(v string) *RelationalDatabaseParameter { + s.ApplyType = &v + return s +} + +// SetDataType sets the DataType field's value. +func (s *RelationalDatabaseParameter) SetDataType(v string) *RelationalDatabaseParameter { + s.DataType = &v + return s +} + +// SetDescription sets the Description field's value. +func (s *RelationalDatabaseParameter) SetDescription(v string) *RelationalDatabaseParameter { + s.Description = &v + return s +} + +// SetIsModifiable sets the IsModifiable field's value. +func (s *RelationalDatabaseParameter) SetIsModifiable(v bool) *RelationalDatabaseParameter { + s.IsModifiable = &v + return s +} + +// SetParameterName sets the ParameterName field's value. +func (s *RelationalDatabaseParameter) SetParameterName(v string) *RelationalDatabaseParameter { + s.ParameterName = &v + return s +} + +// SetParameterValue sets the ParameterValue field's value. +func (s *RelationalDatabaseParameter) SetParameterValue(v string) *RelationalDatabaseParameter { + s.ParameterValue = &v + return s +} + +// Describes a database snapshot. +type RelationalDatabaseSnapshot struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the database snapshot. + Arn *string `locationName:"arn" type:"string"` + + // The timestamp when the database snapshot was created. + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The software of the database snapshot (for example, MySQL) + Engine *string `locationName:"engine" type:"string"` + + // The database engine version for the database snapshot (for example, 5.7.23). + EngineVersion *string `locationName:"engineVersion" type:"string"` + + // The Amazon Resource Name (ARN) of the database from which the database snapshot + // was created. + FromRelationalDatabaseArn *string `locationName:"fromRelationalDatabaseArn" type:"string"` + + // The blueprint ID of the database from which the database snapshot was created. + // A blueprint describes the major engine version of a database. + FromRelationalDatabaseBlueprintId *string `locationName:"fromRelationalDatabaseBlueprintId" type:"string"` + + // The bundle ID of the database from which the database snapshot was created. + FromRelationalDatabaseBundleId *string `locationName:"fromRelationalDatabaseBundleId" type:"string"` + + // The name of the source database from which the database snapshot was created. + FromRelationalDatabaseName *string `locationName:"fromRelationalDatabaseName" type:"string"` + + // The Region name and Availability Zone where the database snapshot is located. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the database snapshot. + Name *string `locationName:"name" type:"string"` + + // The Lightsail resource type. + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The size of the disk in GB (for example, 32) for the database snapshot. + SizeInGb *int64 `locationName:"sizeInGb" type:"integer"` + + // The state of the database snapshot. + State *string `locationName:"state" type:"string"` + + // The support code for the database snapshot. Include this code in your email + // to support when you have questions about a database snapshot in Lightsail. + // This code enables our support team to look up your Lightsail information + // more easily. + SupportCode *string `locationName:"supportCode" type:"string"` + + // The tag keys and optional values for the resource. For more information about + // tags in Lightsail, see the Lightsail Dev Guide (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). + Tags []*Tag `locationName:"tags" type:"list"` +} + +// String returns the string representation +func (s RelationalDatabaseSnapshot) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RelationalDatabaseSnapshot) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *RelationalDatabaseSnapshot) SetArn(v string) *RelationalDatabaseSnapshot { + s.Arn = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *RelationalDatabaseSnapshot) SetCreatedAt(v time.Time) *RelationalDatabaseSnapshot { + s.CreatedAt = &v + return s +} + +// SetEngine sets the Engine field's value. +func (s *RelationalDatabaseSnapshot) SetEngine(v string) *RelationalDatabaseSnapshot { + s.Engine = &v + return s +} + +// SetEngineVersion sets the EngineVersion field's value. +func (s *RelationalDatabaseSnapshot) SetEngineVersion(v string) *RelationalDatabaseSnapshot { + s.EngineVersion = &v + return s +} + +// SetFromRelationalDatabaseArn sets the FromRelationalDatabaseArn field's value. +func (s *RelationalDatabaseSnapshot) SetFromRelationalDatabaseArn(v string) *RelationalDatabaseSnapshot { + s.FromRelationalDatabaseArn = &v + return s +} + +// SetFromRelationalDatabaseBlueprintId sets the FromRelationalDatabaseBlueprintId field's value. +func (s *RelationalDatabaseSnapshot) SetFromRelationalDatabaseBlueprintId(v string) *RelationalDatabaseSnapshot { + s.FromRelationalDatabaseBlueprintId = &v + return s +} + +// SetFromRelationalDatabaseBundleId sets the FromRelationalDatabaseBundleId field's value. +func (s *RelationalDatabaseSnapshot) SetFromRelationalDatabaseBundleId(v string) *RelationalDatabaseSnapshot { + s.FromRelationalDatabaseBundleId = &v + return s +} + +// SetFromRelationalDatabaseName sets the FromRelationalDatabaseName field's value. +func (s *RelationalDatabaseSnapshot) SetFromRelationalDatabaseName(v string) *RelationalDatabaseSnapshot { + s.FromRelationalDatabaseName = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *RelationalDatabaseSnapshot) SetLocation(v *ResourceLocation) *RelationalDatabaseSnapshot { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *RelationalDatabaseSnapshot) SetName(v string) *RelationalDatabaseSnapshot { + s.Name = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *RelationalDatabaseSnapshot) SetResourceType(v string) *RelationalDatabaseSnapshot { + s.ResourceType = &v + return s +} + +// SetSizeInGb sets the SizeInGb field's value. +func (s *RelationalDatabaseSnapshot) SetSizeInGb(v int64) *RelationalDatabaseSnapshot { + s.SizeInGb = &v + return s +} + +// SetState sets the State field's value. +func (s *RelationalDatabaseSnapshot) SetState(v string) *RelationalDatabaseSnapshot { + s.State = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *RelationalDatabaseSnapshot) SetSupportCode(v string) *RelationalDatabaseSnapshot { + s.SupportCode = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *RelationalDatabaseSnapshot) SetTags(v []*Tag) *RelationalDatabaseSnapshot { + s.Tags = v + return s +} + +type ReleaseStaticIpInput struct { + _ struct{} `type:"structure"` + + // The name of the static IP to delete. + // + // StaticIpName is a required field + StaticIpName *string `locationName:"staticIpName" type:"string" required:"true"` +} + +// String returns the string representation +func (s ReleaseStaticIpInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReleaseStaticIpInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ReleaseStaticIpInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ReleaseStaticIpInput"} + if s.StaticIpName == nil { + invalidParams.Add(request.NewErrParamRequired("StaticIpName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetStaticIpName sets the StaticIpName field's value. +func (s *ReleaseStaticIpInput) SetStaticIpName(v string) *ReleaseStaticIpInput { + s.StaticIpName = &v + return s +} + +type ReleaseStaticIpOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s ReleaseStaticIpOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReleaseStaticIpOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *ReleaseStaticIpOutput) SetOperations(v []*Operation) *ReleaseStaticIpOutput { + s.Operations = v + return s +} + +// Describes the resource location. +type ResourceLocation struct { + _ struct{} `type:"structure"` + + // The Availability Zone. Follows the format us-east-2a (case-sensitive). + AvailabilityZone *string `locationName:"availabilityZone" type:"string"` + + // The AWS Region name. + RegionName *string `locationName:"regionName" type:"string" enum:"RegionName"` +} + +// String returns the string representation +func (s ResourceLocation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResourceLocation) GoString() string { + return s.String() +} + +// SetAvailabilityZone sets the AvailabilityZone field's value. +func (s *ResourceLocation) SetAvailabilityZone(v string) *ResourceLocation { + s.AvailabilityZone = &v + return s +} + +// SetRegionName sets the RegionName field's value. +func (s *ResourceLocation) SetRegionName(v string) *ResourceLocation { + s.RegionName = &v + return s +} + +type StartInstanceInput struct { + _ struct{} `type:"structure"` + + // The name of the instance (a virtual private server) to start. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s StartInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StartInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StartInstanceInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetInstanceName sets the InstanceName field's value. +func (s *StartInstanceInput) SetInstanceName(v string) *StartInstanceInput { + s.InstanceName = &v + return s +} + +type StartInstanceOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s StartInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartInstanceOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *StartInstanceOutput) SetOperations(v []*Operation) *StartInstanceOutput { + s.Operations = v + return s +} + +type StartRelationalDatabaseInput struct { + _ struct{} `type:"structure"` + + // The name of your database to start. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` +} + +// String returns the string representation +func (s StartRelationalDatabaseInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartRelationalDatabaseInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StartRelationalDatabaseInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StartRelationalDatabaseInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *StartRelationalDatabaseInput) SetRelationalDatabaseName(v string) *StartRelationalDatabaseInput { + s.RelationalDatabaseName = &v + return s +} + +type StartRelationalDatabaseOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your start relational database request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s StartRelationalDatabaseOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StartRelationalDatabaseOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *StartRelationalDatabaseOutput) SetOperations(v []*Operation) *StartRelationalDatabaseOutput { + s.Operations = v + return s +} + +// Describes the static IP. +type StaticIp struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the static IP (e.g., arn:aws:lightsail:us-east-2:123456789101:StaticIp/9cbb4a9e-f8e3-4dfe-b57e-12345EXAMPLE). + Arn *string `locationName:"arn" type:"string"` + + // The instance where the static IP is attached (e.g., Amazon_Linux-1GB-Ohio-1). + AttachedTo *string `locationName:"attachedTo" type:"string"` + + // The timestamp when the static IP was created (e.g., 1479735304.222). + CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"` + + // The static IP address. + IpAddress *string `locationName:"ipAddress" type:"string"` + + // A Boolean value indicating whether the static IP is attached. + IsAttached *bool `locationName:"isAttached" type:"boolean"` + + // The region and Availability Zone where the static IP was created. + Location *ResourceLocation `locationName:"location" type:"structure"` + + // The name of the static IP (e.g., StaticIP-Ohio-EXAMPLE). + Name *string `locationName:"name" type:"string"` + + // The resource type (usually StaticIp). + ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"` + + // The support code. Include this code in your email to support when you have + // questions about an instance or another resource in Lightsail. This code enables + // our support team to look up your Lightsail information more easily. + SupportCode *string `locationName:"supportCode" type:"string"` +} + +// String returns the string representation +func (s StaticIp) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StaticIp) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *StaticIp) SetArn(v string) *StaticIp { + s.Arn = &v + return s +} + +// SetAttachedTo sets the AttachedTo field's value. +func (s *StaticIp) SetAttachedTo(v string) *StaticIp { + s.AttachedTo = &v + return s +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *StaticIp) SetCreatedAt(v time.Time) *StaticIp { + s.CreatedAt = &v + return s +} + +// SetIpAddress sets the IpAddress field's value. +func (s *StaticIp) SetIpAddress(v string) *StaticIp { + s.IpAddress = &v + return s +} + +// SetIsAttached sets the IsAttached field's value. +func (s *StaticIp) SetIsAttached(v bool) *StaticIp { + s.IsAttached = &v + return s +} + +// SetLocation sets the Location field's value. +func (s *StaticIp) SetLocation(v *ResourceLocation) *StaticIp { + s.Location = v + return s +} + +// SetName sets the Name field's value. +func (s *StaticIp) SetName(v string) *StaticIp { + s.Name = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *StaticIp) SetResourceType(v string) *StaticIp { + s.ResourceType = &v + return s +} + +// SetSupportCode sets the SupportCode field's value. +func (s *StaticIp) SetSupportCode(v string) *StaticIp { + s.SupportCode = &v + return s +} + +type StopInstanceInput struct { + _ struct{} `type:"structure"` + + // When set to True, forces a Lightsail instance that is stuck in a stopping + // state to stop. + // + // Only use the force parameter if your instance is stuck in the stopping state. + // In any other state, your instance should stop normally without adding this + // parameter to your API request. + Force *bool `locationName:"force" type:"boolean"` + + // The name of the instance (a virtual private server) to stop. + // + // InstanceName is a required field + InstanceName *string `locationName:"instanceName" type:"string" required:"true"` +} + +// String returns the string representation +func (s StopInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StopInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StopInstanceInput"} + if s.InstanceName == nil { + invalidParams.Add(request.NewErrParamRequired("InstanceName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetForce sets the Force field's value. +func (s *StopInstanceInput) SetForce(v bool) *StopInstanceInput { + s.Force = &v + return s +} + +// SetInstanceName sets the InstanceName field's value. +func (s *StopInstanceInput) SetInstanceName(v string) *StopInstanceInput { + s.InstanceName = &v + return s +} + +type StopInstanceOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s StopInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopInstanceOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *StopInstanceOutput) SetOperations(v []*Operation) *StopInstanceOutput { + s.Operations = v + return s +} + +type StopRelationalDatabaseInput struct { + _ struct{} `type:"structure"` + + // The name of your database to stop. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` + + // The name of your new database snapshot to be created before stopping your + // database. + RelationalDatabaseSnapshotName *string `locationName:"relationalDatabaseSnapshotName" type:"string"` +} + +// String returns the string representation +func (s StopRelationalDatabaseInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopRelationalDatabaseInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *StopRelationalDatabaseInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "StopRelationalDatabaseInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *StopRelationalDatabaseInput) SetRelationalDatabaseName(v string) *StopRelationalDatabaseInput { + s.RelationalDatabaseName = &v + return s +} + +// SetRelationalDatabaseSnapshotName sets the RelationalDatabaseSnapshotName field's value. +func (s *StopRelationalDatabaseInput) SetRelationalDatabaseSnapshotName(v string) *StopRelationalDatabaseInput { + s.RelationalDatabaseSnapshotName = &v + return s +} + +type StopRelationalDatabaseOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your stop relational database request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s StopRelationalDatabaseOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StopRelationalDatabaseOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *StopRelationalDatabaseOutput) SetOperations(v []*Operation) *StopRelationalDatabaseOutput { + s.Operations = v + return s +} + +// Describes a tag key and optional value assigned to an Amazon Lightsail resource. +// +// For more information about tags in Lightsail, see the Lightsail Dev Guide +// (https://lightsail.aws.amazon.com/ls/docs/en/articles/amazon-lightsail-tags). +type Tag struct { + _ struct{} `type:"structure"` + + // The key of the tag. + // + // Constraints: Tag keys accept a maximum of 128 letters, numbers, spaces in + // UTF-8, or the following characters: + - = . _ : / @ + Key *string `locationName:"key" type:"string"` + + // The value of the tag. + // + // Constraints: Tag values accept a maximum of 256 letters, numbers, spaces + // in UTF-8, or the following characters: + - = . _ : / @ + Value *string `locationName:"value" type:"string"` +} + +// String returns the string representation +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Tag) GoString() string { + return s.String() +} + +// SetKey sets the Key field's value. +func (s *Tag) SetKey(v string) *Tag { + s.Key = &v + return s +} + +// SetValue sets the Value field's value. +func (s *Tag) SetValue(v string) *Tag { + s.Value = &v + return s +} + +type TagResourceInput struct { + _ struct{} `type:"structure"` + + // The name of the resource to which you are adding tags. + // + // ResourceName is a required field + ResourceName *string `locationName:"resourceName" type:"string" required:"true"` + + // The tag key and optional value. + // + // Tags is a required field + Tags []*Tag `locationName:"tags" type:"list" required:"true"` +} + +// String returns the string representation +func (s TagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TagResourceInput"} + if s.ResourceName == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceName")) + } + if s.Tags == nil { + invalidParams.Add(request.NewErrParamRequired("Tags")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceName sets the ResourceName field's value. +func (s *TagResourceInput) SetResourceName(v string) *TagResourceInput { + s.ResourceName = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *TagResourceInput) SetTags(v []*Tag) *TagResourceInput { + s.Tags = v + return s +} + +type TagResourceOutput struct { + _ struct{} `type:"structure"` + + // A list of objects describing the API operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s TagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TagResourceOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *TagResourceOutput) SetOperations(v []*Operation) *TagResourceOutput { + s.Operations = v + return s +} + +type UnpeerVpcInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s UnpeerVpcInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnpeerVpcInput) GoString() string { + return s.String() +} + +type UnpeerVpcOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operation. + Operation *Operation `locationName:"operation" type:"structure"` +} + +// String returns the string representation +func (s UnpeerVpcOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnpeerVpcOutput) GoString() string { + return s.String() +} + +// SetOperation sets the Operation field's value. +func (s *UnpeerVpcOutput) SetOperation(v *Operation) *UnpeerVpcOutput { + s.Operation = v + return s +} + +type UntagResourceInput struct { + _ struct{} `type:"structure"` + + // The name of the resource from which you are removing a tag. + // + // ResourceName is a required field + ResourceName *string `locationName:"resourceName" type:"string" required:"true"` + + // The tag keys to delete from the specified resource. + // + // TagKeys is a required field + TagKeys []*string `locationName:"tagKeys" type:"list" required:"true"` +} + +// String returns the string representation +func (s UntagResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UntagResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UntagResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UntagResourceInput"} + if s.ResourceName == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceName")) + } + if s.TagKeys == nil { + invalidParams.Add(request.NewErrParamRequired("TagKeys")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceName sets the ResourceName field's value. +func (s *UntagResourceInput) SetResourceName(v string) *UntagResourceInput { + s.ResourceName = &v + return s +} + +// SetTagKeys sets the TagKeys field's value. +func (s *UntagResourceInput) SetTagKeys(v []*string) *UntagResourceInput { + s.TagKeys = v + return s +} + +type UntagResourceOutput struct { + _ struct{} `type:"structure"` + + // A list of objects describing the API operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s UntagResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UntagResourceOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *UntagResourceOutput) SetOperations(v []*Operation) *UntagResourceOutput { + s.Operations = v + return s +} + +type UpdateDomainEntryInput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the domain entry. + // + // DomainEntry is a required field + DomainEntry *DomainEntry `locationName:"domainEntry" type:"structure" required:"true"` + + // The name of the domain recordset to update. + // + // DomainName is a required field + DomainName *string `locationName:"domainName" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateDomainEntryInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateDomainEntryInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateDomainEntryInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateDomainEntryInput"} + if s.DomainEntry == nil { + invalidParams.Add(request.NewErrParamRequired("DomainEntry")) + } + if s.DomainName == nil { + invalidParams.Add(request.NewErrParamRequired("DomainName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDomainEntry sets the DomainEntry field's value. +func (s *UpdateDomainEntryInput) SetDomainEntry(v *DomainEntry) *UpdateDomainEntryInput { + s.DomainEntry = v + return s +} + +// SetDomainName sets the DomainName field's value. +func (s *UpdateDomainEntryInput) SetDomainName(v string) *UpdateDomainEntryInput { + s.DomainName = &v + return s +} + +type UpdateDomainEntryOutput struct { + _ struct{} `type:"structure"` + + // An array of key-value pairs containing information about the request operation. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s UpdateDomainEntryOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateDomainEntryOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *UpdateDomainEntryOutput) SetOperations(v []*Operation) *UpdateDomainEntryOutput { + s.Operations = v + return s +} + +type UpdateLoadBalancerAttributeInput struct { + _ struct{} `type:"structure"` + + // The name of the attribute you want to update. Valid values are below. + // + // AttributeName is a required field + AttributeName *string `locationName:"attributeName" type:"string" required:"true" enum:"LoadBalancerAttributeName"` + + // The value that you want to specify for the attribute name. + // + // AttributeValue is a required field + AttributeValue *string `locationName:"attributeValue" min:"1" type:"string" required:"true"` + + // The name of the load balancer that you want to modify (e.g., my-load-balancer. + // + // LoadBalancerName is a required field + LoadBalancerName *string `locationName:"loadBalancerName" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateLoadBalancerAttributeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateLoadBalancerAttributeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateLoadBalancerAttributeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateLoadBalancerAttributeInput"} + if s.AttributeName == nil { + invalidParams.Add(request.NewErrParamRequired("AttributeName")) + } + if s.AttributeValue == nil { + invalidParams.Add(request.NewErrParamRequired("AttributeValue")) + } + if s.AttributeValue != nil && len(*s.AttributeValue) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AttributeValue", 1)) + } + if s.LoadBalancerName == nil { + invalidParams.Add(request.NewErrParamRequired("LoadBalancerName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributeName sets the AttributeName field's value. +func (s *UpdateLoadBalancerAttributeInput) SetAttributeName(v string) *UpdateLoadBalancerAttributeInput { + s.AttributeName = &v + return s +} + +// SetAttributeValue sets the AttributeValue field's value. +func (s *UpdateLoadBalancerAttributeInput) SetAttributeValue(v string) *UpdateLoadBalancerAttributeInput { + s.AttributeValue = &v + return s +} + +// SetLoadBalancerName sets the LoadBalancerName field's value. +func (s *UpdateLoadBalancerAttributeInput) SetLoadBalancerName(v string) *UpdateLoadBalancerAttributeInput { + s.LoadBalancerName = &v + return s +} + +type UpdateLoadBalancerAttributeOutput struct { + _ struct{} `type:"structure"` + + // An object describing the API operations. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s UpdateLoadBalancerAttributeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateLoadBalancerAttributeOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *UpdateLoadBalancerAttributeOutput) SetOperations(v []*Operation) *UpdateLoadBalancerAttributeOutput { + s.Operations = v + return s +} + +type UpdateRelationalDatabaseInput struct { + _ struct{} `type:"structure"` + + // When true, applies changes immediately. When false, applies changes during + // the preferred maintenance window. Some changes may cause an outage. + // + // Default: false + ApplyImmediately *bool `locationName:"applyImmediately" type:"boolean"` + + // When true, disables automated backup retention for your database. + // + // Disabling backup retention deletes all automated database backups. Before + // disabling this, you may want to create a snapshot of your database using + // the create relational database snapshot operation. + // + // Updates are applied during the next maintenance window because this can result + // in an outage. + DisableBackupRetention *bool `locationName:"disableBackupRetention" type:"boolean"` + + // When true, enables automated backup retention for your database. + // + // Updates are applied during the next maintenance window because this can result + // in an outage. + EnableBackupRetention *bool `locationName:"enableBackupRetention" type:"boolean"` + + // The password for the master user of your database. The password can include + // any printable ASCII character except "/", """, or "@". + // + // Constraints: Must contain 8 to 41 characters. + MasterUserPassword *string `locationName:"masterUserPassword" type:"string" sensitive:"true"` + + // The daily time range during which automated backups are created for your + // database if automated backups are enabled. + // + // Constraints: + // + // * Must be in the hh24:mi-hh24:mi format. Example: 16:00-16:30 + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Must not conflict with the preferred maintenance window. + // + // * Must be at least 30 minutes. + PreferredBackupWindow *string `locationName:"preferredBackupWindow" type:"string"` + + // The weekly time range during which system maintenance can occur on your database. + // + // The default is a 30-minute window selected at random from an 8-hour block + // of time for each AWS Region, occurring on a random day of the week. + // + // Constraints: + // + // * Must be in the ddd:hh24:mi-ddd:hh24:mi format. + // + // * Valid days: Mon, Tue, Wed, Thu, Fri, Sat, Sun. + // + // * Must be at least 30 minutes. + // + // * Specified in Universal Coordinated Time (UTC). + // + // * Example: Tue:17:00-Tue:17:30 + PreferredMaintenanceWindow *string `locationName:"preferredMaintenanceWindow" type:"string"` + + // Specifies the accessibility options for your database. A value of true specifies + // a database that is available to resources outside of your Lightsail account. + // A value of false specifies a database that is available only to your Lightsail + // resources in the same region as your database. + PubliclyAccessible *bool `locationName:"publiclyAccessible" type:"boolean"` + + // The name of your database to update. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` + + // When true, the master user password is changed to a new strong password generated + // by Lightsail. + // + // Use the get relational database master user password operation to get the + // new password. + RotateMasterUserPassword *bool `locationName:"rotateMasterUserPassword" type:"boolean"` +} + +// String returns the string representation +func (s UpdateRelationalDatabaseInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateRelationalDatabaseInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateRelationalDatabaseInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateRelationalDatabaseInput"} + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetApplyImmediately sets the ApplyImmediately field's value. +func (s *UpdateRelationalDatabaseInput) SetApplyImmediately(v bool) *UpdateRelationalDatabaseInput { + s.ApplyImmediately = &v + return s +} + +// SetDisableBackupRetention sets the DisableBackupRetention field's value. +func (s *UpdateRelationalDatabaseInput) SetDisableBackupRetention(v bool) *UpdateRelationalDatabaseInput { + s.DisableBackupRetention = &v + return s +} + +// SetEnableBackupRetention sets the EnableBackupRetention field's value. +func (s *UpdateRelationalDatabaseInput) SetEnableBackupRetention(v bool) *UpdateRelationalDatabaseInput { + s.EnableBackupRetention = &v + return s +} + +// SetMasterUserPassword sets the MasterUserPassword field's value. +func (s *UpdateRelationalDatabaseInput) SetMasterUserPassword(v string) *UpdateRelationalDatabaseInput { + s.MasterUserPassword = &v + return s +} + +// SetPreferredBackupWindow sets the PreferredBackupWindow field's value. +func (s *UpdateRelationalDatabaseInput) SetPreferredBackupWindow(v string) *UpdateRelationalDatabaseInput { + s.PreferredBackupWindow = &v + return s +} + +// SetPreferredMaintenanceWindow sets the PreferredMaintenanceWindow field's value. +func (s *UpdateRelationalDatabaseInput) SetPreferredMaintenanceWindow(v string) *UpdateRelationalDatabaseInput { + s.PreferredMaintenanceWindow = &v + return s +} + +// SetPubliclyAccessible sets the PubliclyAccessible field's value. +func (s *UpdateRelationalDatabaseInput) SetPubliclyAccessible(v bool) *UpdateRelationalDatabaseInput { + s.PubliclyAccessible = &v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *UpdateRelationalDatabaseInput) SetRelationalDatabaseName(v string) *UpdateRelationalDatabaseInput { + s.RelationalDatabaseName = &v + return s +} + +// SetRotateMasterUserPassword sets the RotateMasterUserPassword field's value. +func (s *UpdateRelationalDatabaseInput) SetRotateMasterUserPassword(v bool) *UpdateRelationalDatabaseInput { + s.RotateMasterUserPassword = &v + return s +} + +type UpdateRelationalDatabaseOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your update relational database request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s UpdateRelationalDatabaseOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateRelationalDatabaseOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *UpdateRelationalDatabaseOutput) SetOperations(v []*Operation) *UpdateRelationalDatabaseOutput { + s.Operations = v + return s +} + +type UpdateRelationalDatabaseParametersInput struct { + _ struct{} `type:"structure"` + + // The database parameters to update. + // + // Parameters is a required field + Parameters []*RelationalDatabaseParameter `locationName:"parameters" type:"list" required:"true"` + + // The name of your database for which to update parameters. + // + // RelationalDatabaseName is a required field + RelationalDatabaseName *string `locationName:"relationalDatabaseName" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateRelationalDatabaseParametersInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateRelationalDatabaseParametersInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateRelationalDatabaseParametersInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateRelationalDatabaseParametersInput"} + if s.Parameters == nil { + invalidParams.Add(request.NewErrParamRequired("Parameters")) + } + if s.RelationalDatabaseName == nil { + invalidParams.Add(request.NewErrParamRequired("RelationalDatabaseName")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetParameters sets the Parameters field's value. +func (s *UpdateRelationalDatabaseParametersInput) SetParameters(v []*RelationalDatabaseParameter) *UpdateRelationalDatabaseParametersInput { + s.Parameters = v + return s +} + +// SetRelationalDatabaseName sets the RelationalDatabaseName field's value. +func (s *UpdateRelationalDatabaseParametersInput) SetRelationalDatabaseName(v string) *UpdateRelationalDatabaseParametersInput { + s.RelationalDatabaseName = &v + return s +} + +type UpdateRelationalDatabaseParametersOutput struct { + _ struct{} `type:"structure"` + + // An object describing the result of your update relational database parameters + // request. + Operations []*Operation `locationName:"operations" type:"list"` +} + +// String returns the string representation +func (s UpdateRelationalDatabaseParametersOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateRelationalDatabaseParametersOutput) GoString() string { + return s.String() +} + +// SetOperations sets the Operations field's value. +func (s *UpdateRelationalDatabaseParametersOutput) SetOperations(v []*Operation) *UpdateRelationalDatabaseParametersOutput { + s.Operations = v + return s +} + +const ( + // AccessDirectionInbound is a AccessDirection enum value + AccessDirectionInbound = "inbound" + + // AccessDirectionOutbound is a AccessDirection enum value + AccessDirectionOutbound = "outbound" +) + +const ( + // BlueprintTypeOs is a BlueprintType enum value + BlueprintTypeOs = "os" + + // BlueprintTypeApp is a BlueprintType enum value + BlueprintTypeApp = "app" +) + +const ( + // CloudFormationStackRecordSourceTypeExportSnapshotRecord is a CloudFormationStackRecordSourceType enum value + CloudFormationStackRecordSourceTypeExportSnapshotRecord = "ExportSnapshotRecord" +) + +const ( + // DiskSnapshotStatePending is a DiskSnapshotState enum value + DiskSnapshotStatePending = "pending" + + // DiskSnapshotStateCompleted is a DiskSnapshotState enum value + DiskSnapshotStateCompleted = "completed" + + // DiskSnapshotStateError is a DiskSnapshotState enum value + DiskSnapshotStateError = "error" + + // DiskSnapshotStateUnknown is a DiskSnapshotState enum value + DiskSnapshotStateUnknown = "unknown" +) + +const ( + // DiskStatePending is a DiskState enum value + DiskStatePending = "pending" + + // DiskStateError is a DiskState enum value + DiskStateError = "error" + + // DiskStateAvailable is a DiskState enum value + DiskStateAvailable = "available" + + // DiskStateInUse is a DiskState enum value + DiskStateInUse = "in-use" + + // DiskStateUnknown is a DiskState enum value + DiskStateUnknown = "unknown" +) + +const ( + // ExportSnapshotRecordSourceTypeInstanceSnapshot is a ExportSnapshotRecordSourceType enum value + ExportSnapshotRecordSourceTypeInstanceSnapshot = "InstanceSnapshot" + + // ExportSnapshotRecordSourceTypeDiskSnapshot is a ExportSnapshotRecordSourceType enum value + ExportSnapshotRecordSourceTypeDiskSnapshot = "DiskSnapshot" +) + +const ( + // InstanceAccessProtocolSsh is a InstanceAccessProtocol enum value + InstanceAccessProtocolSsh = "ssh" + + // InstanceAccessProtocolRdp is a InstanceAccessProtocol enum value + InstanceAccessProtocolRdp = "rdp" +) + +const ( + // InstanceHealthReasonLbRegistrationInProgress is a InstanceHealthReason enum value + InstanceHealthReasonLbRegistrationInProgress = "Lb.RegistrationInProgress" + + // InstanceHealthReasonLbInitialHealthChecking is a InstanceHealthReason enum value + InstanceHealthReasonLbInitialHealthChecking = "Lb.InitialHealthChecking" + + // InstanceHealthReasonLbInternalError is a InstanceHealthReason enum value + InstanceHealthReasonLbInternalError = "Lb.InternalError" + + // InstanceHealthReasonInstanceResponseCodeMismatch is a InstanceHealthReason enum value + InstanceHealthReasonInstanceResponseCodeMismatch = "Instance.ResponseCodeMismatch" + + // InstanceHealthReasonInstanceTimeout is a InstanceHealthReason enum value + InstanceHealthReasonInstanceTimeout = "Instance.Timeout" + + // InstanceHealthReasonInstanceFailedHealthChecks is a InstanceHealthReason enum value + InstanceHealthReasonInstanceFailedHealthChecks = "Instance.FailedHealthChecks" + + // InstanceHealthReasonInstanceNotRegistered is a InstanceHealthReason enum value + InstanceHealthReasonInstanceNotRegistered = "Instance.NotRegistered" + + // InstanceHealthReasonInstanceNotInUse is a InstanceHealthReason enum value + InstanceHealthReasonInstanceNotInUse = "Instance.NotInUse" + + // InstanceHealthReasonInstanceDeregistrationInProgress is a InstanceHealthReason enum value + InstanceHealthReasonInstanceDeregistrationInProgress = "Instance.DeregistrationInProgress" + + // InstanceHealthReasonInstanceInvalidState is a InstanceHealthReason enum value + InstanceHealthReasonInstanceInvalidState = "Instance.InvalidState" + + // InstanceHealthReasonInstanceIpUnusable is a InstanceHealthReason enum value + InstanceHealthReasonInstanceIpUnusable = "Instance.IpUnusable" +) + +const ( + // InstanceHealthStateInitial is a InstanceHealthState enum value + InstanceHealthStateInitial = "initial" + + // InstanceHealthStateHealthy is a InstanceHealthState enum value + InstanceHealthStateHealthy = "healthy" + + // InstanceHealthStateUnhealthy is a InstanceHealthState enum value + InstanceHealthStateUnhealthy = "unhealthy" + + // InstanceHealthStateUnused is a InstanceHealthState enum value + InstanceHealthStateUnused = "unused" + + // InstanceHealthStateDraining is a InstanceHealthState enum value + InstanceHealthStateDraining = "draining" + + // InstanceHealthStateUnavailable is a InstanceHealthState enum value + InstanceHealthStateUnavailable = "unavailable" +) + +const ( + // InstanceMetricNameCpuutilization is a InstanceMetricName enum value + InstanceMetricNameCpuutilization = "CPUUtilization" + + // InstanceMetricNameNetworkIn is a InstanceMetricName enum value + InstanceMetricNameNetworkIn = "NetworkIn" + + // InstanceMetricNameNetworkOut is a InstanceMetricName enum value + InstanceMetricNameNetworkOut = "NetworkOut" + + // InstanceMetricNameStatusCheckFailed is a InstanceMetricName enum value + InstanceMetricNameStatusCheckFailed = "StatusCheckFailed" + + // InstanceMetricNameStatusCheckFailedInstance is a InstanceMetricName enum value + InstanceMetricNameStatusCheckFailedInstance = "StatusCheckFailed_Instance" + + // InstanceMetricNameStatusCheckFailedSystem is a InstanceMetricName enum value + InstanceMetricNameStatusCheckFailedSystem = "StatusCheckFailed_System" +) + +const ( + // InstancePlatformLinuxUnix is a InstancePlatform enum value + InstancePlatformLinuxUnix = "LINUX_UNIX" + + // InstancePlatformWindows is a InstancePlatform enum value + InstancePlatformWindows = "WINDOWS" +) + +const ( + // InstanceSnapshotStatePending is a InstanceSnapshotState enum value + InstanceSnapshotStatePending = "pending" + + // InstanceSnapshotStateError is a InstanceSnapshotState enum value + InstanceSnapshotStateError = "error" + + // InstanceSnapshotStateAvailable is a InstanceSnapshotState enum value + InstanceSnapshotStateAvailable = "available" +) + +const ( + // LoadBalancerAttributeNameHealthCheckPath is a LoadBalancerAttributeName enum value + LoadBalancerAttributeNameHealthCheckPath = "HealthCheckPath" + + // LoadBalancerAttributeNameSessionStickinessEnabled is a LoadBalancerAttributeName enum value + LoadBalancerAttributeNameSessionStickinessEnabled = "SessionStickinessEnabled" + + // LoadBalancerAttributeNameSessionStickinessLbCookieDurationSeconds is a LoadBalancerAttributeName enum value + LoadBalancerAttributeNameSessionStickinessLbCookieDurationSeconds = "SessionStickiness_LB_CookieDurationSeconds" +) + +const ( + // LoadBalancerMetricNameClientTlsnegotiationErrorCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameClientTlsnegotiationErrorCount = "ClientTLSNegotiationErrorCount" + + // LoadBalancerMetricNameHealthyHostCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameHealthyHostCount = "HealthyHostCount" + + // LoadBalancerMetricNameUnhealthyHostCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameUnhealthyHostCount = "UnhealthyHostCount" + + // LoadBalancerMetricNameHttpcodeLb4xxCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameHttpcodeLb4xxCount = "HTTPCode_LB_4XX_Count" + + // LoadBalancerMetricNameHttpcodeLb5xxCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameHttpcodeLb5xxCount = "HTTPCode_LB_5XX_Count" + + // LoadBalancerMetricNameHttpcodeInstance2xxCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameHttpcodeInstance2xxCount = "HTTPCode_Instance_2XX_Count" + + // LoadBalancerMetricNameHttpcodeInstance3xxCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameHttpcodeInstance3xxCount = "HTTPCode_Instance_3XX_Count" + + // LoadBalancerMetricNameHttpcodeInstance4xxCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameHttpcodeInstance4xxCount = "HTTPCode_Instance_4XX_Count" + + // LoadBalancerMetricNameHttpcodeInstance5xxCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameHttpcodeInstance5xxCount = "HTTPCode_Instance_5XX_Count" + + // LoadBalancerMetricNameInstanceResponseTime is a LoadBalancerMetricName enum value + LoadBalancerMetricNameInstanceResponseTime = "InstanceResponseTime" + + // LoadBalancerMetricNameRejectedConnectionCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameRejectedConnectionCount = "RejectedConnectionCount" + + // LoadBalancerMetricNameRequestCount is a LoadBalancerMetricName enum value + LoadBalancerMetricNameRequestCount = "RequestCount" +) + +const ( + // LoadBalancerProtocolHttpHttps is a LoadBalancerProtocol enum value + LoadBalancerProtocolHttpHttps = "HTTP_HTTPS" + + // LoadBalancerProtocolHttp is a LoadBalancerProtocol enum value + LoadBalancerProtocolHttp = "HTTP" +) + +const ( + // LoadBalancerStateActive is a LoadBalancerState enum value + LoadBalancerStateActive = "active" + + // LoadBalancerStateProvisioning is a LoadBalancerState enum value + LoadBalancerStateProvisioning = "provisioning" + + // LoadBalancerStateActiveImpaired is a LoadBalancerState enum value + LoadBalancerStateActiveImpaired = "active_impaired" + + // LoadBalancerStateFailed is a LoadBalancerState enum value + LoadBalancerStateFailed = "failed" + + // LoadBalancerStateUnknown is a LoadBalancerState enum value + LoadBalancerStateUnknown = "unknown" +) + +const ( + // LoadBalancerTlsCertificateDomainStatusPendingValidation is a LoadBalancerTlsCertificateDomainStatus enum value + LoadBalancerTlsCertificateDomainStatusPendingValidation = "PENDING_VALIDATION" + + // LoadBalancerTlsCertificateDomainStatusFailed is a LoadBalancerTlsCertificateDomainStatus enum value + LoadBalancerTlsCertificateDomainStatusFailed = "FAILED" + + // LoadBalancerTlsCertificateDomainStatusSuccess is a LoadBalancerTlsCertificateDomainStatus enum value + LoadBalancerTlsCertificateDomainStatusSuccess = "SUCCESS" +) + +const ( + // LoadBalancerTlsCertificateFailureReasonNoAvailableContacts is a LoadBalancerTlsCertificateFailureReason enum value + LoadBalancerTlsCertificateFailureReasonNoAvailableContacts = "NO_AVAILABLE_CONTACTS" + + // LoadBalancerTlsCertificateFailureReasonAdditionalVerificationRequired is a LoadBalancerTlsCertificateFailureReason enum value + LoadBalancerTlsCertificateFailureReasonAdditionalVerificationRequired = "ADDITIONAL_VERIFICATION_REQUIRED" + + // LoadBalancerTlsCertificateFailureReasonDomainNotAllowed is a LoadBalancerTlsCertificateFailureReason enum value + LoadBalancerTlsCertificateFailureReasonDomainNotAllowed = "DOMAIN_NOT_ALLOWED" + + // LoadBalancerTlsCertificateFailureReasonInvalidPublicDomain is a LoadBalancerTlsCertificateFailureReason enum value + LoadBalancerTlsCertificateFailureReasonInvalidPublicDomain = "INVALID_PUBLIC_DOMAIN" + + // LoadBalancerTlsCertificateFailureReasonOther is a LoadBalancerTlsCertificateFailureReason enum value + LoadBalancerTlsCertificateFailureReasonOther = "OTHER" +) + +const ( + // LoadBalancerTlsCertificateRenewalStatusPendingAutoRenewal is a LoadBalancerTlsCertificateRenewalStatus enum value + LoadBalancerTlsCertificateRenewalStatusPendingAutoRenewal = "PENDING_AUTO_RENEWAL" + + // LoadBalancerTlsCertificateRenewalStatusPendingValidation is a LoadBalancerTlsCertificateRenewalStatus enum value + LoadBalancerTlsCertificateRenewalStatusPendingValidation = "PENDING_VALIDATION" + + // LoadBalancerTlsCertificateRenewalStatusSuccess is a LoadBalancerTlsCertificateRenewalStatus enum value + LoadBalancerTlsCertificateRenewalStatusSuccess = "SUCCESS" + + // LoadBalancerTlsCertificateRenewalStatusFailed is a LoadBalancerTlsCertificateRenewalStatus enum value + LoadBalancerTlsCertificateRenewalStatusFailed = "FAILED" +) + +const ( + // LoadBalancerTlsCertificateRevocationReasonUnspecified is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonUnspecified = "UNSPECIFIED" + + // LoadBalancerTlsCertificateRevocationReasonKeyCompromise is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonKeyCompromise = "KEY_COMPROMISE" + + // LoadBalancerTlsCertificateRevocationReasonCaCompromise is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonCaCompromise = "CA_COMPROMISE" + + // LoadBalancerTlsCertificateRevocationReasonAffiliationChanged is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonAffiliationChanged = "AFFILIATION_CHANGED" + + // LoadBalancerTlsCertificateRevocationReasonSuperceded is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonSuperceded = "SUPERCEDED" + + // LoadBalancerTlsCertificateRevocationReasonCessationOfOperation is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonCessationOfOperation = "CESSATION_OF_OPERATION" + + // LoadBalancerTlsCertificateRevocationReasonCertificateHold is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonCertificateHold = "CERTIFICATE_HOLD" + + // LoadBalancerTlsCertificateRevocationReasonRemoveFromCrl is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonRemoveFromCrl = "REMOVE_FROM_CRL" + + // LoadBalancerTlsCertificateRevocationReasonPrivilegeWithdrawn is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonPrivilegeWithdrawn = "PRIVILEGE_WITHDRAWN" + + // LoadBalancerTlsCertificateRevocationReasonAACompromise is a LoadBalancerTlsCertificateRevocationReason enum value + LoadBalancerTlsCertificateRevocationReasonAACompromise = "A_A_COMPROMISE" +) + +const ( + // LoadBalancerTlsCertificateStatusPendingValidation is a LoadBalancerTlsCertificateStatus enum value + LoadBalancerTlsCertificateStatusPendingValidation = "PENDING_VALIDATION" + + // LoadBalancerTlsCertificateStatusIssued is a LoadBalancerTlsCertificateStatus enum value + LoadBalancerTlsCertificateStatusIssued = "ISSUED" + + // LoadBalancerTlsCertificateStatusInactive is a LoadBalancerTlsCertificateStatus enum value + LoadBalancerTlsCertificateStatusInactive = "INACTIVE" + + // LoadBalancerTlsCertificateStatusExpired is a LoadBalancerTlsCertificateStatus enum value + LoadBalancerTlsCertificateStatusExpired = "EXPIRED" + + // LoadBalancerTlsCertificateStatusValidationTimedOut is a LoadBalancerTlsCertificateStatus enum value + LoadBalancerTlsCertificateStatusValidationTimedOut = "VALIDATION_TIMED_OUT" + + // LoadBalancerTlsCertificateStatusRevoked is a LoadBalancerTlsCertificateStatus enum value + LoadBalancerTlsCertificateStatusRevoked = "REVOKED" + + // LoadBalancerTlsCertificateStatusFailed is a LoadBalancerTlsCertificateStatus enum value + LoadBalancerTlsCertificateStatusFailed = "FAILED" + + // LoadBalancerTlsCertificateStatusUnknown is a LoadBalancerTlsCertificateStatus enum value + LoadBalancerTlsCertificateStatusUnknown = "UNKNOWN" +) + +const ( + // MetricStatisticMinimum is a MetricStatistic enum value + MetricStatisticMinimum = "Minimum" + + // MetricStatisticMaximum is a MetricStatistic enum value + MetricStatisticMaximum = "Maximum" + + // MetricStatisticSum is a MetricStatistic enum value + MetricStatisticSum = "Sum" + + // MetricStatisticAverage is a MetricStatistic enum value + MetricStatisticAverage = "Average" + + // MetricStatisticSampleCount is a MetricStatistic enum value + MetricStatisticSampleCount = "SampleCount" +) + +const ( + // MetricUnitSeconds is a MetricUnit enum value + MetricUnitSeconds = "Seconds" + + // MetricUnitMicroseconds is a MetricUnit enum value + MetricUnitMicroseconds = "Microseconds" + + // MetricUnitMilliseconds is a MetricUnit enum value + MetricUnitMilliseconds = "Milliseconds" + + // MetricUnitBytes is a MetricUnit enum value + MetricUnitBytes = "Bytes" + + // MetricUnitKilobytes is a MetricUnit enum value + MetricUnitKilobytes = "Kilobytes" + + // MetricUnitMegabytes is a MetricUnit enum value + MetricUnitMegabytes = "Megabytes" + + // MetricUnitGigabytes is a MetricUnit enum value + MetricUnitGigabytes = "Gigabytes" + + // MetricUnitTerabytes is a MetricUnit enum value + MetricUnitTerabytes = "Terabytes" + + // MetricUnitBits is a MetricUnit enum value + MetricUnitBits = "Bits" + + // MetricUnitKilobits is a MetricUnit enum value + MetricUnitKilobits = "Kilobits" + + // MetricUnitMegabits is a MetricUnit enum value + MetricUnitMegabits = "Megabits" + + // MetricUnitGigabits is a MetricUnit enum value + MetricUnitGigabits = "Gigabits" + + // MetricUnitTerabits is a MetricUnit enum value + MetricUnitTerabits = "Terabits" + + // MetricUnitPercent is a MetricUnit enum value + MetricUnitPercent = "Percent" + + // MetricUnitCount is a MetricUnit enum value + MetricUnitCount = "Count" + + // MetricUnitBytesSecond is a MetricUnit enum value + MetricUnitBytesSecond = "Bytes/Second" + + // MetricUnitKilobytesSecond is a MetricUnit enum value + MetricUnitKilobytesSecond = "Kilobytes/Second" + + // MetricUnitMegabytesSecond is a MetricUnit enum value + MetricUnitMegabytesSecond = "Megabytes/Second" + + // MetricUnitGigabytesSecond is a MetricUnit enum value + MetricUnitGigabytesSecond = "Gigabytes/Second" + + // MetricUnitTerabytesSecond is a MetricUnit enum value + MetricUnitTerabytesSecond = "Terabytes/Second" + + // MetricUnitBitsSecond is a MetricUnit enum value + MetricUnitBitsSecond = "Bits/Second" + + // MetricUnitKilobitsSecond is a MetricUnit enum value + MetricUnitKilobitsSecond = "Kilobits/Second" + + // MetricUnitMegabitsSecond is a MetricUnit enum value + MetricUnitMegabitsSecond = "Megabits/Second" + + // MetricUnitGigabitsSecond is a MetricUnit enum value + MetricUnitGigabitsSecond = "Gigabits/Second" + + // MetricUnitTerabitsSecond is a MetricUnit enum value + MetricUnitTerabitsSecond = "Terabits/Second" + + // MetricUnitCountSecond is a MetricUnit enum value + MetricUnitCountSecond = "Count/Second" + + // MetricUnitNone is a MetricUnit enum value + MetricUnitNone = "None" +) + +const ( + // NetworkProtocolTcp is a NetworkProtocol enum value + NetworkProtocolTcp = "tcp" + + // NetworkProtocolAll is a NetworkProtocol enum value + NetworkProtocolAll = "all" + + // NetworkProtocolUdp is a NetworkProtocol enum value + NetworkProtocolUdp = "udp" +) + +const ( + // OperationStatusNotStarted is a OperationStatus enum value + OperationStatusNotStarted = "NotStarted" + + // OperationStatusStarted is a OperationStatus enum value + OperationStatusStarted = "Started" + + // OperationStatusFailed is a OperationStatus enum value + OperationStatusFailed = "Failed" + + // OperationStatusCompleted is a OperationStatus enum value + OperationStatusCompleted = "Completed" + + // OperationStatusSucceeded is a OperationStatus enum value + OperationStatusSucceeded = "Succeeded" +) + +const ( + // OperationTypeDeleteKnownHostKeys is a OperationType enum value + OperationTypeDeleteKnownHostKeys = "DeleteKnownHostKeys" + + // OperationTypeDeleteInstance is a OperationType enum value + OperationTypeDeleteInstance = "DeleteInstance" + + // OperationTypeCreateInstance is a OperationType enum value + OperationTypeCreateInstance = "CreateInstance" + + // OperationTypeStopInstance is a OperationType enum value + OperationTypeStopInstance = "StopInstance" + + // OperationTypeStartInstance is a OperationType enum value + OperationTypeStartInstance = "StartInstance" + + // OperationTypeRebootInstance is a OperationType enum value + OperationTypeRebootInstance = "RebootInstance" + + // OperationTypeOpenInstancePublicPorts is a OperationType enum value + OperationTypeOpenInstancePublicPorts = "OpenInstancePublicPorts" + + // OperationTypePutInstancePublicPorts is a OperationType enum value + OperationTypePutInstancePublicPorts = "PutInstancePublicPorts" + + // OperationTypeCloseInstancePublicPorts is a OperationType enum value + OperationTypeCloseInstancePublicPorts = "CloseInstancePublicPorts" + + // OperationTypeAllocateStaticIp is a OperationType enum value + OperationTypeAllocateStaticIp = "AllocateStaticIp" + + // OperationTypeReleaseStaticIp is a OperationType enum value + OperationTypeReleaseStaticIp = "ReleaseStaticIp" + + // OperationTypeAttachStaticIp is a OperationType enum value + OperationTypeAttachStaticIp = "AttachStaticIp" + + // OperationTypeDetachStaticIp is a OperationType enum value + OperationTypeDetachStaticIp = "DetachStaticIp" + + // OperationTypeUpdateDomainEntry is a OperationType enum value + OperationTypeUpdateDomainEntry = "UpdateDomainEntry" + + // OperationTypeDeleteDomainEntry is a OperationType enum value + OperationTypeDeleteDomainEntry = "DeleteDomainEntry" + + // OperationTypeCreateDomain is a OperationType enum value + OperationTypeCreateDomain = "CreateDomain" + + // OperationTypeDeleteDomain is a OperationType enum value + OperationTypeDeleteDomain = "DeleteDomain" + + // OperationTypeCreateInstanceSnapshot is a OperationType enum value + OperationTypeCreateInstanceSnapshot = "CreateInstanceSnapshot" + + // OperationTypeDeleteInstanceSnapshot is a OperationType enum value + OperationTypeDeleteInstanceSnapshot = "DeleteInstanceSnapshot" + + // OperationTypeCreateInstancesFromSnapshot is a OperationType enum value + OperationTypeCreateInstancesFromSnapshot = "CreateInstancesFromSnapshot" + + // OperationTypeCreateLoadBalancer is a OperationType enum value + OperationTypeCreateLoadBalancer = "CreateLoadBalancer" + + // OperationTypeDeleteLoadBalancer is a OperationType enum value + OperationTypeDeleteLoadBalancer = "DeleteLoadBalancer" + + // OperationTypeAttachInstancesToLoadBalancer is a OperationType enum value + OperationTypeAttachInstancesToLoadBalancer = "AttachInstancesToLoadBalancer" + + // OperationTypeDetachInstancesFromLoadBalancer is a OperationType enum value + OperationTypeDetachInstancesFromLoadBalancer = "DetachInstancesFromLoadBalancer" + + // OperationTypeUpdateLoadBalancerAttribute is a OperationType enum value + OperationTypeUpdateLoadBalancerAttribute = "UpdateLoadBalancerAttribute" + + // OperationTypeCreateLoadBalancerTlsCertificate is a OperationType enum value + OperationTypeCreateLoadBalancerTlsCertificate = "CreateLoadBalancerTlsCertificate" + + // OperationTypeDeleteLoadBalancerTlsCertificate is a OperationType enum value + OperationTypeDeleteLoadBalancerTlsCertificate = "DeleteLoadBalancerTlsCertificate" + + // OperationTypeAttachLoadBalancerTlsCertificate is a OperationType enum value + OperationTypeAttachLoadBalancerTlsCertificate = "AttachLoadBalancerTlsCertificate" + + // OperationTypeCreateDisk is a OperationType enum value + OperationTypeCreateDisk = "CreateDisk" + + // OperationTypeDeleteDisk is a OperationType enum value + OperationTypeDeleteDisk = "DeleteDisk" + + // OperationTypeAttachDisk is a OperationType enum value + OperationTypeAttachDisk = "AttachDisk" + + // OperationTypeDetachDisk is a OperationType enum value + OperationTypeDetachDisk = "DetachDisk" + + // OperationTypeCreateDiskSnapshot is a OperationType enum value + OperationTypeCreateDiskSnapshot = "CreateDiskSnapshot" + + // OperationTypeDeleteDiskSnapshot is a OperationType enum value + OperationTypeDeleteDiskSnapshot = "DeleteDiskSnapshot" + + // OperationTypeCreateDiskFromSnapshot is a OperationType enum value + OperationTypeCreateDiskFromSnapshot = "CreateDiskFromSnapshot" + + // OperationTypeCreateRelationalDatabase is a OperationType enum value + OperationTypeCreateRelationalDatabase = "CreateRelationalDatabase" + + // OperationTypeUpdateRelationalDatabase is a OperationType enum value + OperationTypeUpdateRelationalDatabase = "UpdateRelationalDatabase" + + // OperationTypeDeleteRelationalDatabase is a OperationType enum value + OperationTypeDeleteRelationalDatabase = "DeleteRelationalDatabase" + + // OperationTypeCreateRelationalDatabaseFromSnapshot is a OperationType enum value + OperationTypeCreateRelationalDatabaseFromSnapshot = "CreateRelationalDatabaseFromSnapshot" + + // OperationTypeCreateRelationalDatabaseSnapshot is a OperationType enum value + OperationTypeCreateRelationalDatabaseSnapshot = "CreateRelationalDatabaseSnapshot" + + // OperationTypeDeleteRelationalDatabaseSnapshot is a OperationType enum value + OperationTypeDeleteRelationalDatabaseSnapshot = "DeleteRelationalDatabaseSnapshot" + + // OperationTypeUpdateRelationalDatabaseParameters is a OperationType enum value + OperationTypeUpdateRelationalDatabaseParameters = "UpdateRelationalDatabaseParameters" + + // OperationTypeStartRelationalDatabase is a OperationType enum value + OperationTypeStartRelationalDatabase = "StartRelationalDatabase" + + // OperationTypeRebootRelationalDatabase is a OperationType enum value + OperationTypeRebootRelationalDatabase = "RebootRelationalDatabase" + + // OperationTypeStopRelationalDatabase is a OperationType enum value + OperationTypeStopRelationalDatabase = "StopRelationalDatabase" +) + +const ( + // PortAccessTypePublic is a PortAccessType enum value + PortAccessTypePublic = "Public" + + // PortAccessTypePrivate is a PortAccessType enum value + PortAccessTypePrivate = "Private" +) + +const ( + // PortInfoSourceTypeDefault is a PortInfoSourceType enum value + PortInfoSourceTypeDefault = "DEFAULT" + + // PortInfoSourceTypeInstance is a PortInfoSourceType enum value + PortInfoSourceTypeInstance = "INSTANCE" + + // PortInfoSourceTypeNone is a PortInfoSourceType enum value + PortInfoSourceTypeNone = "NONE" + + // PortInfoSourceTypeClosed is a PortInfoSourceType enum value + PortInfoSourceTypeClosed = "CLOSED" +) + +const ( + // PortStateOpen is a PortState enum value + PortStateOpen = "open" + + // PortStateClosed is a PortState enum value + PortStateClosed = "closed" +) + +const ( + // RecordStateStarted is a RecordState enum value + RecordStateStarted = "Started" + + // RecordStateSucceeded is a RecordState enum value + RecordStateSucceeded = "Succeeded" + + // RecordStateFailed is a RecordState enum value + RecordStateFailed = "Failed" +) + +const ( + // RegionNameUsEast1 is a RegionName enum value + RegionNameUsEast1 = "us-east-1" + + // RegionNameUsEast2 is a RegionName enum value + RegionNameUsEast2 = "us-east-2" + + // RegionNameUsWest1 is a RegionName enum value + RegionNameUsWest1 = "us-west-1" + + // RegionNameUsWest2 is a RegionName enum value + RegionNameUsWest2 = "us-west-2" + + // RegionNameEuWest1 is a RegionName enum value + RegionNameEuWest1 = "eu-west-1" + + // RegionNameEuWest2 is a RegionName enum value + RegionNameEuWest2 = "eu-west-2" + + // RegionNameEuWest3 is a RegionName enum value + RegionNameEuWest3 = "eu-west-3" + + // RegionNameEuCentral1 is a RegionName enum value + RegionNameEuCentral1 = "eu-central-1" + + // RegionNameCaCentral1 is a RegionName enum value + RegionNameCaCentral1 = "ca-central-1" + + // RegionNameApSouth1 is a RegionName enum value + RegionNameApSouth1 = "ap-south-1" + + // RegionNameApSoutheast1 is a RegionName enum value + RegionNameApSoutheast1 = "ap-southeast-1" + + // RegionNameApSoutheast2 is a RegionName enum value + RegionNameApSoutheast2 = "ap-southeast-2" + + // RegionNameApNortheast1 is a RegionName enum value + RegionNameApNortheast1 = "ap-northeast-1" + + // RegionNameApNortheast2 is a RegionName enum value + RegionNameApNortheast2 = "ap-northeast-2" +) + +const ( + // RelationalDatabaseEngineMysql is a RelationalDatabaseEngine enum value + RelationalDatabaseEngineMysql = "mysql" +) + +const ( + // RelationalDatabaseMetricNameCpuutilization is a RelationalDatabaseMetricName enum value + RelationalDatabaseMetricNameCpuutilization = "CPUUtilization" + + // RelationalDatabaseMetricNameDatabaseConnections is a RelationalDatabaseMetricName enum value + RelationalDatabaseMetricNameDatabaseConnections = "DatabaseConnections" + + // RelationalDatabaseMetricNameDiskQueueDepth is a RelationalDatabaseMetricName enum value + RelationalDatabaseMetricNameDiskQueueDepth = "DiskQueueDepth" + + // RelationalDatabaseMetricNameFreeStorageSpace is a RelationalDatabaseMetricName enum value + RelationalDatabaseMetricNameFreeStorageSpace = "FreeStorageSpace" + + // RelationalDatabaseMetricNameNetworkReceiveThroughput is a RelationalDatabaseMetricName enum value + RelationalDatabaseMetricNameNetworkReceiveThroughput = "NetworkReceiveThroughput" + + // RelationalDatabaseMetricNameNetworkTransmitThroughput is a RelationalDatabaseMetricName enum value + RelationalDatabaseMetricNameNetworkTransmitThroughput = "NetworkTransmitThroughput" +) + +const ( + // RelationalDatabasePasswordVersionCurrent is a RelationalDatabasePasswordVersion enum value + RelationalDatabasePasswordVersionCurrent = "CURRENT" + + // RelationalDatabasePasswordVersionPrevious is a RelationalDatabasePasswordVersion enum value + RelationalDatabasePasswordVersionPrevious = "PREVIOUS" + + // RelationalDatabasePasswordVersionPending is a RelationalDatabasePasswordVersion enum value + RelationalDatabasePasswordVersionPending = "PENDING" +) + +const ( + // ResourceTypeInstance is a ResourceType enum value + ResourceTypeInstance = "Instance" + + // ResourceTypeStaticIp is a ResourceType enum value + ResourceTypeStaticIp = "StaticIp" + + // ResourceTypeKeyPair is a ResourceType enum value + ResourceTypeKeyPair = "KeyPair" + + // ResourceTypeInstanceSnapshot is a ResourceType enum value + ResourceTypeInstanceSnapshot = "InstanceSnapshot" + + // ResourceTypeDomain is a ResourceType enum value + ResourceTypeDomain = "Domain" + + // ResourceTypePeeredVpc is a ResourceType enum value + ResourceTypePeeredVpc = "PeeredVpc" + + // ResourceTypeLoadBalancer is a ResourceType enum value + ResourceTypeLoadBalancer = "LoadBalancer" + + // ResourceTypeLoadBalancerTlsCertificate is a ResourceType enum value + ResourceTypeLoadBalancerTlsCertificate = "LoadBalancerTlsCertificate" + + // ResourceTypeDisk is a ResourceType enum value + ResourceTypeDisk = "Disk" + + // ResourceTypeDiskSnapshot is a ResourceType enum value + ResourceTypeDiskSnapshot = "DiskSnapshot" + + // ResourceTypeRelationalDatabase is a ResourceType enum value + ResourceTypeRelationalDatabase = "RelationalDatabase" + + // ResourceTypeRelationalDatabaseSnapshot is a ResourceType enum value + ResourceTypeRelationalDatabaseSnapshot = "RelationalDatabaseSnapshot" + + // ResourceTypeExportSnapshotRecord is a ResourceType enum value + ResourceTypeExportSnapshotRecord = "ExportSnapshotRecord" + + // ResourceTypeCloudFormationStackRecord is a ResourceType enum value + ResourceTypeCloudFormationStackRecord = "CloudFormationStackRecord" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/lightsail/doc.go b/vendor/github.com/aws/aws-sdk-go/service/lightsail/doc.go new file mode 100644 index 000000000..f806bbf09 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/lightsail/doc.go @@ -0,0 +1,40 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package lightsail provides the client and types for making API +// requests to Amazon Lightsail. +// +// Amazon Lightsail is the easiest way to get started with AWS for developers +// who just need virtual private servers. Lightsail includes everything you +// need to launch your project quickly - a virtual machine, a managed database, +// SSD-based storage, data transfer, DNS management, and a static IP - for a +// low, predictable price. You manage those Lightsail servers through the Lightsail +// console or by using the API or command-line interface (CLI). +// +// For more information about Lightsail concepts and tasks, see the Lightsail +// Dev Guide (https://lightsail.aws.amazon.com/ls/docs/all). +// +// To use the Lightsail API or the CLI, you will need to use AWS Identity and +// Access Management (IAM) to generate access keys. For details about how to +// set this up, see the Lightsail Dev Guide (http://lightsail.aws.amazon.com/ls/docs/how-to/article/lightsail-how-to-set-up-access-keys-to-use-sdk-api-cli). +// +// See https://docs.aws.amazon.com/goto/WebAPI/lightsail-2016-11-28 for more information on this service. +// +// See lightsail package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/lightsail/ +// +// Using the Client +// +// To contact Amazon Lightsail with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Amazon Lightsail client Lightsail for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/lightsail/#New +package lightsail diff --git a/vendor/github.com/aws/aws-sdk-go/service/lightsail/errors.go b/vendor/github.com/aws/aws-sdk-go/service/lightsail/errors.go new file mode 100644 index 000000000..bda8b8a66 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/lightsail/errors.go @@ -0,0 +1,55 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package lightsail + +const ( + + // ErrCodeAccessDeniedException for service response error code + // "AccessDeniedException". + // + // Lightsail throws this exception when the user cannot be authenticated or + // uses invalid credentials to access a resource. + ErrCodeAccessDeniedException = "AccessDeniedException" + + // ErrCodeAccountSetupInProgressException for service response error code + // "AccountSetupInProgressException". + // + // Lightsail throws this exception when an account is still in the setup in + // progress state. + ErrCodeAccountSetupInProgressException = "AccountSetupInProgressException" + + // ErrCodeInvalidInputException for service response error code + // "InvalidInputException". + // + // Lightsail throws this exception when user input does not conform to the validation + // rules of an input field. + // + // Domain-related APIs are only available in the N. Virginia (us-east-1) Region. + // Please set your AWS Region configuration to us-east-1 to create, view, or + // edit these resources. + ErrCodeInvalidInputException = "InvalidInputException" + + // ErrCodeNotFoundException for service response error code + // "NotFoundException". + // + // Lightsail throws this exception when it cannot find a resource. + ErrCodeNotFoundException = "NotFoundException" + + // ErrCodeOperationFailureException for service response error code + // "OperationFailureException". + // + // Lightsail throws this exception when an operation fails to execute. + ErrCodeOperationFailureException = "OperationFailureException" + + // ErrCodeServiceException for service response error code + // "ServiceException". + // + // A general service exception. + ErrCodeServiceException = "ServiceException" + + // ErrCodeUnauthenticatedException for service response error code + // "UnauthenticatedException". + // + // Lightsail throws this exception when the user has not been authenticated. + ErrCodeUnauthenticatedException = "UnauthenticatedException" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/lightsail/service.go b/vendor/github.com/aws/aws-sdk-go/service/lightsail/service.go new file mode 100644 index 000000000..b9f97faa8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/lightsail/service.go @@ -0,0 +1,97 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package lightsail + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" +) + +// Lightsail provides the API operation methods for making requests to +// Amazon Lightsail. See this package's package overview docs +// for details on the service. +// +// Lightsail methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type Lightsail struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "lightsail" // Name of service. + EndpointsID = ServiceName // ID to lookup a service endpoint with. + ServiceID = "Lightsail" // ServiceID is a unique identifer of a specific service. +) + +// New creates a new instance of the Lightsail client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// // Create a Lightsail client from just a session. +// svc := lightsail.New(mySession) +// +// // Create a Lightsail client with additional configuration +// svc := lightsail.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *Lightsail { + c := p.ClientConfig(EndpointsID, cfgs...) + return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *Lightsail { + svc := &Lightsail{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + Endpoint: endpoint, + APIVersion: "2016-11-28", + JSONVersion: "1.1", + TargetPrefix: "Lightsail_20161128", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a Lightsail operation and runs any +// custom request initialization. +func (c *Lightsail) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/api.go b/vendor/github.com/aws/aws-sdk-go/service/route53/api.go new file mode 100644 index 000000000..82e8d54b0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/api.go @@ -0,0 +1,15360 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package route53 + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/restxml" +) + +const opAssociateVPCWithHostedZone = "AssociateVPCWithHostedZone" + +// AssociateVPCWithHostedZoneRequest generates a "aws/request.Request" representing the +// client's request for the AssociateVPCWithHostedZone operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssociateVPCWithHostedZone for more information on using the AssociateVPCWithHostedZone +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssociateVPCWithHostedZoneRequest method. +// req, resp := client.AssociateVPCWithHostedZoneRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/AssociateVPCWithHostedZone +func (c *Route53) AssociateVPCWithHostedZoneRequest(input *AssociateVPCWithHostedZoneInput) (req *request.Request, output *AssociateVPCWithHostedZoneOutput) { + op := &request.Operation{ + Name: opAssociateVPCWithHostedZone, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/hostedzone/{Id}/associatevpc", + } + + if input == nil { + input = &AssociateVPCWithHostedZoneInput{} + } + + output = &AssociateVPCWithHostedZoneOutput{} + req = c.newRequest(op, input, output) + return +} + +// AssociateVPCWithHostedZone API operation for Amazon Route 53. +// +// Associates an Amazon VPC with a private hosted zone. +// +// To perform the association, the VPC and the private hosted zone must already +// exist. You can't convert a public hosted zone into a private hosted zone. +// +// If you want to associate a VPC that was created by using one AWS account +// with a private hosted zone that was created by using a different account, +// the AWS account that created the private hosted zone must first submit a +// CreateVPCAssociationAuthorization request. Then the account that created +// the VPC must submit an AssociateVPCWithHostedZone request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation AssociateVPCWithHostedZone for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeNotAuthorizedException "NotAuthorizedException" +// Associating the specified VPC with the specified hosted zone has not been +// authorized. +// +// * ErrCodeInvalidVPCId "InvalidVPCId" +// The VPC ID that you specified either isn't a valid ID or the current account +// is not authorized to access this VPC. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodePublicZoneVPCAssociation "PublicZoneVPCAssociation" +// You're trying to associate a VPC with a public hosted zone. Amazon Route +// 53 doesn't support associating a VPC with a public hosted zone. +// +// * ErrCodeConflictingDomainExists "ConflictingDomainExists" +// The cause of this error depends on whether you're trying to create a public +// or a private hosted zone: +// +// * Public hosted zone: Two hosted zones that have the same name or that +// have a parent/child relationship (example.com and test.example.com) can't +// have any common name servers. You tried to create a hosted zone that has +// the same name as an existing hosted zone or that's the parent or child +// of an existing hosted zone, and you specified a delegation set that shares +// one or more name servers with the existing hosted zone. For more information, +// see CreateReusableDelegationSet (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateReusableDelegationSet.html). +// +// * Private hosted zone: You specified an Amazon VPC that you're already +// using for another hosted zone, and the domain that you specified for one +// of the hosted zones is a subdomain of the domain that you specified for +// the other hosted zone. For example, you can't use the same Amazon VPC +// for the hosted zones for example.com and test.example.com. +// +// * ErrCodeLimitsExceeded "LimitsExceeded" +// This operation can't be completed either because the current account has +// reached the limit on reusable delegation sets that it can create or because +// you've reached the limit on the number of Amazon VPCs that you can associate +// with a private hosted zone. To get the current limit on the number of reusable +// delegation sets, see GetAccountLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). +// To get the current limit on the number of Amazon VPCs that you can associate +// with a private hosted zone, see GetHostedZoneLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetHostedZoneLimit.html). +// To request a higher limit, create a case (http://aws.amazon.com/route53-request) +// with the AWS Support Center. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/AssociateVPCWithHostedZone +func (c *Route53) AssociateVPCWithHostedZone(input *AssociateVPCWithHostedZoneInput) (*AssociateVPCWithHostedZoneOutput, error) { + req, out := c.AssociateVPCWithHostedZoneRequest(input) + return out, req.Send() +} + +// AssociateVPCWithHostedZoneWithContext is the same as AssociateVPCWithHostedZone with the addition of +// the ability to pass a context and additional request options. +// +// See AssociateVPCWithHostedZone for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) AssociateVPCWithHostedZoneWithContext(ctx aws.Context, input *AssociateVPCWithHostedZoneInput, opts ...request.Option) (*AssociateVPCWithHostedZoneOutput, error) { + req, out := c.AssociateVPCWithHostedZoneRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opChangeResourceRecordSets = "ChangeResourceRecordSets" + +// ChangeResourceRecordSetsRequest generates a "aws/request.Request" representing the +// client's request for the ChangeResourceRecordSets operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ChangeResourceRecordSets for more information on using the ChangeResourceRecordSets +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ChangeResourceRecordSetsRequest method. +// req, resp := client.ChangeResourceRecordSetsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ChangeResourceRecordSets +func (c *Route53) ChangeResourceRecordSetsRequest(input *ChangeResourceRecordSetsInput) (req *request.Request, output *ChangeResourceRecordSetsOutput) { + op := &request.Operation{ + Name: opChangeResourceRecordSets, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/hostedzone/{Id}/rrset/", + } + + if input == nil { + input = &ChangeResourceRecordSetsInput{} + } + + output = &ChangeResourceRecordSetsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ChangeResourceRecordSets API operation for Amazon Route 53. +// +// Creates, changes, or deletes a resource record set, which contains authoritative +// DNS information for a specified domain name or subdomain name. For example, +// you can use ChangeResourceRecordSets to create a resource record set that +// routes traffic for test.example.com to a web server that has an IP address +// of 192.0.2.44. +// +// Change Batches and Transactional Changes +// +// The request body must include a document with a ChangeResourceRecordSetsRequest +// element. The request body contains a list of change items, known as a change +// batch. Change batches are considered transactional changes. When using the +// Amazon Route 53 API to change resource record sets, Route 53 either makes +// all or none of the changes in a change batch request. This ensures that Route +// 53 never partially implements the intended changes to the resource record +// sets in a hosted zone. +// +// For example, a change batch request that deletes the CNAME record for www.example.com +// and creates an alias resource record set for www.example.com. Route 53 deletes +// the first resource record set and creates the second resource record set +// in a single operation. If either the DELETE or the CREATE action fails, then +// both changes (plus any other changes in the batch) fail, and the original +// CNAME record continues to exist. +// +// Due to the nature of transactional changes, you can't delete the same resource +// record set more than once in a single change batch. If you attempt to delete +// the same change batch more than once, Route 53 returns an InvalidChangeBatch +// error. +// +// Traffic Flow +// +// To create resource record sets for complex routing configurations, use either +// the traffic flow visual editor in the Route 53 console or the API actions +// for traffic policies and traffic policy instances. Save the configuration +// as a traffic policy, then associate the traffic policy with one or more domain +// names (such as example.com) or subdomain names (such as www.example.com), +// in the same hosted zone or in multiple hosted zones. You can roll back the +// updates if the new configuration isn't performing as expected. For more information, +// see Using Traffic Flow to Route DNS Traffic (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/traffic-flow.html) +// in the Amazon Route 53 Developer Guide. +// +// Create, Delete, and Upsert +// +// Use ChangeResourceRecordsSetsRequest to perform the following actions: +// +// * CREATE: Creates a resource record set that has the specified values. +// +// * DELETE: Deletes an existing resource record set that has the specified +// values. +// +// * UPSERT: If a resource record set does not already exist, AWS creates +// it. If a resource set does exist, Route 53 updates it with the values +// in the request. +// +// Syntaxes for Creating, Updating, and Deleting Resource Record Sets +// +// The syntax for a request depends on the type of resource record set that +// you want to create, delete, or update, such as weighted, alias, or failover. +// The XML elements in your request must appear in the order listed in the syntax. +// +// For an example for each type of resource record set, see "Examples." +// +// Don't refer to the syntax in the "Parameter Syntax" section, which includes +// all of the elements for every kind of resource record set that you can create, +// delete, or update by using ChangeResourceRecordSets. +// +// Change Propagation to Route 53 DNS Servers +// +// When you submit a ChangeResourceRecordSets request, Route 53 propagates your +// changes to all of the Route 53 authoritative DNS servers. While your changes +// are propagating, GetChange returns a status of PENDING. When propagation +// is complete, GetChange returns a status of INSYNC. Changes generally propagate +// to all Route 53 name servers within 60 seconds. For more information, see +// GetChange (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetChange.html). +// +// Limits on ChangeResourceRecordSets Requests +// +// For information about the limits on a ChangeResourceRecordSets request, see +// Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) +// in the Amazon Route 53 Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ChangeResourceRecordSets for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeInvalidChangeBatch "InvalidChangeBatch" +// This exception contains a list of messages that might contain one or more +// error messages. Each error message indicates one error in the change batch. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodePriorRequestNotComplete "PriorRequestNotComplete" +// If Amazon Route 53 can't process a request before the next request arrives, +// it will reject subsequent requests for the same hosted zone and return an +// HTTP 400 error (Bad request). If Route 53 returns this error repeatedly for +// the same request, we recommend that you wait, in intervals of increasing +// duration, before you try the request again. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ChangeResourceRecordSets +func (c *Route53) ChangeResourceRecordSets(input *ChangeResourceRecordSetsInput) (*ChangeResourceRecordSetsOutput, error) { + req, out := c.ChangeResourceRecordSetsRequest(input) + return out, req.Send() +} + +// ChangeResourceRecordSetsWithContext is the same as ChangeResourceRecordSets with the addition of +// the ability to pass a context and additional request options. +// +// See ChangeResourceRecordSets for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ChangeResourceRecordSetsWithContext(ctx aws.Context, input *ChangeResourceRecordSetsInput, opts ...request.Option) (*ChangeResourceRecordSetsOutput, error) { + req, out := c.ChangeResourceRecordSetsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opChangeTagsForResource = "ChangeTagsForResource" + +// ChangeTagsForResourceRequest generates a "aws/request.Request" representing the +// client's request for the ChangeTagsForResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ChangeTagsForResource for more information on using the ChangeTagsForResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ChangeTagsForResourceRequest method. +// req, resp := client.ChangeTagsForResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ChangeTagsForResource +func (c *Route53) ChangeTagsForResourceRequest(input *ChangeTagsForResourceInput) (req *request.Request, output *ChangeTagsForResourceOutput) { + op := &request.Operation{ + Name: opChangeTagsForResource, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/tags/{ResourceType}/{ResourceId}", + } + + if input == nil { + input = &ChangeTagsForResourceInput{} + } + + output = &ChangeTagsForResourceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// ChangeTagsForResource API operation for Amazon Route 53. +// +// Adds, edits, or deletes tags for a health check or a hosted zone. +// +// For information about using tags for cost allocation, see Using Cost Allocation +// Tags (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html) +// in the AWS Billing and Cost Management User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ChangeTagsForResource for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodePriorRequestNotComplete "PriorRequestNotComplete" +// If Amazon Route 53 can't process a request before the next request arrives, +// it will reject subsequent requests for the same hosted zone and return an +// HTTP 400 error (Bad request). If Route 53 returns this error repeatedly for +// the same request, we recommend that you wait, in intervals of increasing +// duration, before you try the request again. +// +// * ErrCodeThrottlingException "ThrottlingException" +// The limit on the number of requests per second was exceeded. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ChangeTagsForResource +func (c *Route53) ChangeTagsForResource(input *ChangeTagsForResourceInput) (*ChangeTagsForResourceOutput, error) { + req, out := c.ChangeTagsForResourceRequest(input) + return out, req.Send() +} + +// ChangeTagsForResourceWithContext is the same as ChangeTagsForResource with the addition of +// the ability to pass a context and additional request options. +// +// See ChangeTagsForResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ChangeTagsForResourceWithContext(ctx aws.Context, input *ChangeTagsForResourceInput, opts ...request.Option) (*ChangeTagsForResourceOutput, error) { + req, out := c.ChangeTagsForResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateHealthCheck = "CreateHealthCheck" + +// CreateHealthCheckRequest generates a "aws/request.Request" representing the +// client's request for the CreateHealthCheck operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateHealthCheck for more information on using the CreateHealthCheck +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateHealthCheckRequest method. +// req, resp := client.CreateHealthCheckRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateHealthCheck +func (c *Route53) CreateHealthCheckRequest(input *CreateHealthCheckInput) (req *request.Request, output *CreateHealthCheckOutput) { + op := &request.Operation{ + Name: opCreateHealthCheck, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/healthcheck", + } + + if input == nil { + input = &CreateHealthCheckInput{} + } + + output = &CreateHealthCheckOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateHealthCheck API operation for Amazon Route 53. +// +// Creates a new health check. +// +// For information about adding health checks to resource record sets, see HealthCheckId +// (https://docs.aws.amazon.com/Route53/latest/APIReference/API_ResourceRecordSet.html#Route53-Type-ResourceRecordSet-HealthCheckId) +// in ChangeResourceRecordSets (https://docs.aws.amazon.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html). +// +// ELB Load Balancers +// +// If you're registering EC2 instances with an Elastic Load Balancing (ELB) +// load balancer, do not create Amazon Route 53 health checks for the EC2 instances. +// When you register an EC2 instance with a load balancer, you configure settings +// for an ELB health check, which performs a similar function to a Route 53 +// health check. +// +// Private Hosted Zones +// +// You can associate health checks with failover resource record sets in a private +// hosted zone. Note the following: +// +// * Route 53 health checkers are outside the VPC. To check the health of +// an endpoint within a VPC by IP address, you must assign a public IP address +// to the instance in the VPC. +// +// * You can configure a health checker to check the health of an external +// resource that the instance relies on, such as a database server. +// +// * You can create a CloudWatch metric, associate an alarm with the metric, +// and then create a health check that is based on the state of the alarm. +// For example, you might create a CloudWatch metric that checks the status +// of the Amazon EC2 StatusCheckFailed metric, add an alarm to the metric, +// and then create a health check that is based on the state of the alarm. +// For information about creating CloudWatch metrics and alarms by using +// the CloudWatch console, see the Amazon CloudWatch User Guide (http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/WhatIsCloudWatch.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation CreateHealthCheck for usage and error information. +// +// Returned Error Codes: +// * ErrCodeTooManyHealthChecks "TooManyHealthChecks" +// This health check can't be created because the current account has reached +// the limit on the number of active health checks. +// +// For information about default limits, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) +// in the Amazon Route 53 Developer Guide. +// +// For information about how to get the current limit for an account, see GetAccountLimit +// (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). +// To request a higher limit, create a case (http://aws.amazon.com/route53-request) +// with the AWS Support Center. +// +// You have reached the maximum number of active health checks for an AWS account. +// To request a higher limit, create a case (http://aws.amazon.com/route53-request) +// with the AWS Support Center. +// +// * ErrCodeHealthCheckAlreadyExists "HealthCheckAlreadyExists" +// The health check you're attempting to create already exists. Amazon Route +// 53 returns this error when you submit a request that has the following values: +// +// * The same value for CallerReference as an existing health check, and +// one or more values that differ from the existing health check that has +// the same caller reference. +// +// * The same value for CallerReference as a health check that you created +// and later deleted, regardless of the other settings in the request. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateHealthCheck +func (c *Route53) CreateHealthCheck(input *CreateHealthCheckInput) (*CreateHealthCheckOutput, error) { + req, out := c.CreateHealthCheckRequest(input) + return out, req.Send() +} + +// CreateHealthCheckWithContext is the same as CreateHealthCheck with the addition of +// the ability to pass a context and additional request options. +// +// See CreateHealthCheck for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) CreateHealthCheckWithContext(ctx aws.Context, input *CreateHealthCheckInput, opts ...request.Option) (*CreateHealthCheckOutput, error) { + req, out := c.CreateHealthCheckRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateHostedZone = "CreateHostedZone" + +// CreateHostedZoneRequest generates a "aws/request.Request" representing the +// client's request for the CreateHostedZone operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateHostedZone for more information on using the CreateHostedZone +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateHostedZoneRequest method. +// req, resp := client.CreateHostedZoneRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateHostedZone +func (c *Route53) CreateHostedZoneRequest(input *CreateHostedZoneInput) (req *request.Request, output *CreateHostedZoneOutput) { + op := &request.Operation{ + Name: opCreateHostedZone, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/hostedzone", + } + + if input == nil { + input = &CreateHostedZoneInput{} + } + + output = &CreateHostedZoneOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateHostedZone API operation for Amazon Route 53. +// +// Creates a new public or private hosted zone. You create records in a public +// hosted zone to define how you want to route traffic on the internet for a +// domain, such as example.com, and its subdomains (apex.example.com, acme.example.com). +// You create records in a private hosted zone to define how you want to route +// traffic for a domain and its subdomains within one or more Amazon Virtual +// Private Clouds (Amazon VPCs). +// +// You can't convert a public hosted zone to a private hosted zone or vice versa. +// Instead, you must create a new hosted zone with the same name and create +// new resource record sets. +// +// For more information about charges for hosted zones, see Amazon Route 53 +// Pricing (http://aws.amazon.com/route53/pricing/). +// +// Note the following: +// +// * You can't create a hosted zone for a top-level domain (TLD) such as +// .com. +// +// * For public hosted zones, Amazon Route 53 automatically creates a default +// SOA record and four NS records for the zone. For more information about +// SOA and NS records, see NS and SOA Records that Route 53 Creates for a +// Hosted Zone (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/SOA-NSrecords.html) +// in the Amazon Route 53 Developer Guide. If you want to use the same name +// servers for multiple public hosted zones, you can optionally associate +// a reusable delegation set with the hosted zone. See the DelegationSetId +// element. +// +// * If your domain is registered with a registrar other than Route 53, you +// must update the name servers with your registrar to make Route 53 the +// DNS service for the domain. For more information, see Migrating DNS Service +// for an Existing Domain to Amazon Route 53 (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/MigratingDNS.html) +// in the Amazon Route 53 Developer Guide. +// +// When you submit a CreateHostedZone request, the initial status of the hosted +// zone is PENDING. For public hosted zones, this means that the NS and SOA +// records are not yet available on all Route 53 DNS servers. When the NS and +// SOA records are available, the status of the zone changes to INSYNC. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation CreateHostedZone for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidDomainName "InvalidDomainName" +// The specified domain name is not valid. +// +// * ErrCodeHostedZoneAlreadyExists "HostedZoneAlreadyExists" +// The hosted zone you're trying to create already exists. Amazon Route 53 returns +// this error when a hosted zone has already been created with the specified +// CallerReference. +// +// * ErrCodeTooManyHostedZones "TooManyHostedZones" +// This operation can't be completed either because the current account has +// reached the limit on the number of hosted zones or because you've reached +// the limit on the number of hosted zones that can be associated with a reusable +// delegation set. +// +// For information about default limits, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) +// in the Amazon Route 53 Developer Guide. +// +// To get the current limit on hosted zones that can be created by an account, +// see GetAccountLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). +// +// To get the current limit on hosted zones that can be associated with a reusable +// delegation set, see GetReusableDelegationSetLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetReusableDelegationSetLimit.html). +// +// To request a higher limit, create a case (http://aws.amazon.com/route53-request) +// with the AWS Support Center. +// +// * ErrCodeInvalidVPCId "InvalidVPCId" +// The VPC ID that you specified either isn't a valid ID or the current account +// is not authorized to access this VPC. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeDelegationSetNotAvailable "DelegationSetNotAvailable" +// You can create a hosted zone that has the same name as an existing hosted +// zone (example.com is common), but there is a limit to the number of hosted +// zones that have the same name. If you get this error, Amazon Route 53 has +// reached that limit. If you own the domain name and Route 53 generates this +// error, contact Customer Support. +// +// * ErrCodeConflictingDomainExists "ConflictingDomainExists" +// The cause of this error depends on whether you're trying to create a public +// or a private hosted zone: +// +// * Public hosted zone: Two hosted zones that have the same name or that +// have a parent/child relationship (example.com and test.example.com) can't +// have any common name servers. You tried to create a hosted zone that has +// the same name as an existing hosted zone or that's the parent or child +// of an existing hosted zone, and you specified a delegation set that shares +// one or more name servers with the existing hosted zone. For more information, +// see CreateReusableDelegationSet (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateReusableDelegationSet.html). +// +// * Private hosted zone: You specified an Amazon VPC that you're already +// using for another hosted zone, and the domain that you specified for one +// of the hosted zones is a subdomain of the domain that you specified for +// the other hosted zone. For example, you can't use the same Amazon VPC +// for the hosted zones for example.com and test.example.com. +// +// * ErrCodeNoSuchDelegationSet "NoSuchDelegationSet" +// A reusable delegation set with the specified ID does not exist. +// +// * ErrCodeDelegationSetNotReusable "DelegationSetNotReusable" +// A reusable delegation set with the specified ID does not exist. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateHostedZone +func (c *Route53) CreateHostedZone(input *CreateHostedZoneInput) (*CreateHostedZoneOutput, error) { + req, out := c.CreateHostedZoneRequest(input) + return out, req.Send() +} + +// CreateHostedZoneWithContext is the same as CreateHostedZone with the addition of +// the ability to pass a context and additional request options. +// +// See CreateHostedZone for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) CreateHostedZoneWithContext(ctx aws.Context, input *CreateHostedZoneInput, opts ...request.Option) (*CreateHostedZoneOutput, error) { + req, out := c.CreateHostedZoneRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateQueryLoggingConfig = "CreateQueryLoggingConfig" + +// CreateQueryLoggingConfigRequest generates a "aws/request.Request" representing the +// client's request for the CreateQueryLoggingConfig operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateQueryLoggingConfig for more information on using the CreateQueryLoggingConfig +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateQueryLoggingConfigRequest method. +// req, resp := client.CreateQueryLoggingConfigRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateQueryLoggingConfig +func (c *Route53) CreateQueryLoggingConfigRequest(input *CreateQueryLoggingConfigInput) (req *request.Request, output *CreateQueryLoggingConfigOutput) { + op := &request.Operation{ + Name: opCreateQueryLoggingConfig, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/queryloggingconfig", + } + + if input == nil { + input = &CreateQueryLoggingConfigInput{} + } + + output = &CreateQueryLoggingConfigOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateQueryLoggingConfig API operation for Amazon Route 53. +// +// Creates a configuration for DNS query logging. After you create a query logging +// configuration, Amazon Route 53 begins to publish log data to an Amazon CloudWatch +// Logs log group. +// +// DNS query logs contain information about the queries that Route 53 receives +// for a specified public hosted zone, such as the following: +// +// * Route 53 edge location that responded to the DNS query +// +// * Domain or subdomain that was requested +// +// * DNS record type, such as A or AAAA +// +// * DNS response code, such as NoError or ServFail +// +// Log Group and Resource Policy +// +// Before you create a query logging configuration, perform the following operations. +// +// If you create a query logging configuration using the Route 53 console, Route +// 53 performs these operations automatically. +// +// Create a CloudWatch Logs log group, and make note of the ARN, which you specify +// when you create a query logging configuration. Note the following: +// +// * You must create the log group in the us-east-1 region. +// +// * You must use the same AWS account to create the log group and the hosted +// zone that you want to configure query logging for. +// +// * When you create log groups for query logging, we recommend that you +// use a consistent prefix, for example: /aws/route53/hosted zone name In +// the next step, you'll create a resource policy, which controls access +// to one or more log groups and the associated AWS resources, such as Route +// 53 hosted zones. There's a limit on the number of resource policies that +// you can create, so we recommend that you use a consistent prefix so you +// can use the same resource policy for all the log groups that you create +// for query logging. +// +// Create a CloudWatch Logs resource policy, and give it the permissions that +// Route 53 needs to create log streams and to send query logs to log streams. +// For the value of Resource, specify the ARN for the log group that you created +// in the previous step. To use the same resource policy for all the CloudWatch +// Logs log groups that you created for query logging configurations, replace +// the hosted zone name with *, for example: +// +// arn:aws:logs:us-east-1:123412341234:log-group:/aws/route53/* +// +// You can't use the CloudWatch console to create or edit a resource policy. +// You must use the CloudWatch API, one of the AWS SDKs, or the AWS CLI. +// +// Log Streams and Edge Locations +// +// When Route 53 finishes creating the configuration for DNS query logging, +// it does the following: +// +// * Creates a log stream for an edge location the first time that the edge +// location responds to DNS queries for the specified hosted zone. That log +// stream is used to log all queries that Route 53 responds to for that edge +// location. +// +// * Begins to send query logs to the applicable log stream. +// +// The name of each log stream is in the following format: +// +// hosted zone ID/edge location code +// +// The edge location code is a three-letter code and an arbitrarily assigned +// number, for example, DFW3. The three-letter code typically corresponds with +// the International Air Transport Association airport code for an airport near +// the edge location. (These abbreviations might change in the future.) For +// a list of edge locations, see "The Route 53 Global Network" on the Route +// 53 Product Details (http://aws.amazon.com/route53/details/) page. +// +// Queries That Are Logged +// +// Query logs contain only the queries that DNS resolvers forward to Route 53. +// If a DNS resolver has already cached the response to a query (such as the +// IP address for a load balancer for example.com), the resolver will continue +// to return the cached response. It doesn't forward another query to Route +// 53 until the TTL for the corresponding resource record set expires. Depending +// on how many DNS queries are submitted for a resource record set, and depending +// on the TTL for that resource record set, query logs might contain information +// about only one query out of every several thousand queries that are submitted +// to DNS. For more information about how DNS works, see Routing Internet Traffic +// to Your Website or Web Application (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/welcome-dns-service.html) +// in the Amazon Route 53 Developer Guide. +// +// Log File Format +// +// For a list of the values in each query log and the format of each value, +// see Logging DNS Queries (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/query-logs.html) +// in the Amazon Route 53 Developer Guide. +// +// Pricing +// +// For information about charges for query logs, see Amazon CloudWatch Pricing +// (http://aws.amazon.com/cloudwatch/pricing/). +// +// How to Stop Logging +// +// If you want Route 53 to stop sending query logs to CloudWatch Logs, delete +// the query logging configuration. For more information, see DeleteQueryLoggingConfig +// (https://docs.aws.amazon.com/Route53/latest/APIReference/API_DeleteQueryLoggingConfig.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation CreateQueryLoggingConfig for usage and error information. +// +// Returned Error Codes: +// * ErrCodeConcurrentModification "ConcurrentModification" +// Another user submitted a request to create, update, or delete the object +// at the same time that you did. Retry the request. +// +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeNoSuchCloudWatchLogsLogGroup "NoSuchCloudWatchLogsLogGroup" +// There is no CloudWatch Logs log group with the specified ARN. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeQueryLoggingConfigAlreadyExists "QueryLoggingConfigAlreadyExists" +// You can create only one query logging configuration for a hosted zone, and +// a query logging configuration already exists for this hosted zone. +// +// * ErrCodeInsufficientCloudWatchLogsResourcePolicy "InsufficientCloudWatchLogsResourcePolicy" +// Amazon Route 53 doesn't have the permissions required to create log streams +// and send query logs to log streams. Possible causes include the following: +// +// * There is no resource policy that specifies the log group ARN in the +// value for Resource. +// +// * The resource policy that includes the log group ARN in the value for +// Resource doesn't have the necessary permissions. +// +// * The resource policy hasn't finished propagating yet. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateQueryLoggingConfig +func (c *Route53) CreateQueryLoggingConfig(input *CreateQueryLoggingConfigInput) (*CreateQueryLoggingConfigOutput, error) { + req, out := c.CreateQueryLoggingConfigRequest(input) + return out, req.Send() +} + +// CreateQueryLoggingConfigWithContext is the same as CreateQueryLoggingConfig with the addition of +// the ability to pass a context and additional request options. +// +// See CreateQueryLoggingConfig for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) CreateQueryLoggingConfigWithContext(ctx aws.Context, input *CreateQueryLoggingConfigInput, opts ...request.Option) (*CreateQueryLoggingConfigOutput, error) { + req, out := c.CreateQueryLoggingConfigRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateReusableDelegationSet = "CreateReusableDelegationSet" + +// CreateReusableDelegationSetRequest generates a "aws/request.Request" representing the +// client's request for the CreateReusableDelegationSet operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateReusableDelegationSet for more information on using the CreateReusableDelegationSet +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateReusableDelegationSetRequest method. +// req, resp := client.CreateReusableDelegationSetRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateReusableDelegationSet +func (c *Route53) CreateReusableDelegationSetRequest(input *CreateReusableDelegationSetInput) (req *request.Request, output *CreateReusableDelegationSetOutput) { + op := &request.Operation{ + Name: opCreateReusableDelegationSet, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/delegationset", + } + + if input == nil { + input = &CreateReusableDelegationSetInput{} + } + + output = &CreateReusableDelegationSetOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateReusableDelegationSet API operation for Amazon Route 53. +// +// Creates a delegation set (a group of four name servers) that can be reused +// by multiple hosted zones. If a hosted zoned ID is specified, CreateReusableDelegationSet +// marks the delegation set associated with that zone as reusable. +// +// You can't associate a reusable delegation set with a private hosted zone. +// +// For information about using a reusable delegation set to configure white +// label name servers, see Configuring White Label Name Servers (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/white-label-name-servers.html). +// +// The process for migrating existing hosted zones to use a reusable delegation +// set is comparable to the process for configuring white label name servers. +// You need to perform the following steps: +// +// Create a reusable delegation set. +// +// Recreate hosted zones, and reduce the TTL to 60 seconds or less. +// +// Recreate resource record sets in the new hosted zones. +// +// Change the registrar's name servers to use the name servers for the new hosted +// zones. +// +// Monitor traffic for the website or application. +// +// Change TTLs back to their original values. +// +// If you want to migrate existing hosted zones to use a reusable delegation +// set, the existing hosted zones can't use any of the name servers that are +// assigned to the reusable delegation set. If one or more hosted zones do use +// one or more name servers that are assigned to the reusable delegation set, +// you can do one of the following: +// +// * For small numbers of hosted zones—up to a few hundred—it's relatively +// easy to create reusable delegation sets until you get one that has four +// name servers that don't overlap with any of the name servers in your hosted +// zones. +// +// * For larger numbers of hosted zones, the easiest solution is to use more +// than one reusable delegation set. +// +// * For larger numbers of hosted zones, you can also migrate hosted zones +// that have overlapping name servers to hosted zones that don't have overlapping +// name servers, then migrate the hosted zones again to use the reusable +// delegation set. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation CreateReusableDelegationSet for usage and error information. +// +// Returned Error Codes: +// * ErrCodeDelegationSetAlreadyCreated "DelegationSetAlreadyCreated" +// A delegation set with the same owner and caller reference combination has +// already been created. +// +// * ErrCodeLimitsExceeded "LimitsExceeded" +// This operation can't be completed either because the current account has +// reached the limit on reusable delegation sets that it can create or because +// you've reached the limit on the number of Amazon VPCs that you can associate +// with a private hosted zone. To get the current limit on the number of reusable +// delegation sets, see GetAccountLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). +// To get the current limit on the number of Amazon VPCs that you can associate +// with a private hosted zone, see GetHostedZoneLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetHostedZoneLimit.html). +// To request a higher limit, create a case (http://aws.amazon.com/route53-request) +// with the AWS Support Center. +// +// * ErrCodeHostedZoneNotFound "HostedZoneNotFound" +// The specified HostedZone can't be found. +// +// * ErrCodeInvalidArgument "InvalidArgument" +// Parameter name is invalid. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeDelegationSetNotAvailable "DelegationSetNotAvailable" +// You can create a hosted zone that has the same name as an existing hosted +// zone (example.com is common), but there is a limit to the number of hosted +// zones that have the same name. If you get this error, Amazon Route 53 has +// reached that limit. If you own the domain name and Route 53 generates this +// error, contact Customer Support. +// +// * ErrCodeDelegationSetAlreadyReusable "DelegationSetAlreadyReusable" +// The specified delegation set has already been marked as reusable. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateReusableDelegationSet +func (c *Route53) CreateReusableDelegationSet(input *CreateReusableDelegationSetInput) (*CreateReusableDelegationSetOutput, error) { + req, out := c.CreateReusableDelegationSetRequest(input) + return out, req.Send() +} + +// CreateReusableDelegationSetWithContext is the same as CreateReusableDelegationSet with the addition of +// the ability to pass a context and additional request options. +// +// See CreateReusableDelegationSet for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) CreateReusableDelegationSetWithContext(ctx aws.Context, input *CreateReusableDelegationSetInput, opts ...request.Option) (*CreateReusableDelegationSetOutput, error) { + req, out := c.CreateReusableDelegationSetRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateTrafficPolicy = "CreateTrafficPolicy" + +// CreateTrafficPolicyRequest generates a "aws/request.Request" representing the +// client's request for the CreateTrafficPolicy operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateTrafficPolicy for more information on using the CreateTrafficPolicy +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateTrafficPolicyRequest method. +// req, resp := client.CreateTrafficPolicyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateTrafficPolicy +func (c *Route53) CreateTrafficPolicyRequest(input *CreateTrafficPolicyInput) (req *request.Request, output *CreateTrafficPolicyOutput) { + op := &request.Operation{ + Name: opCreateTrafficPolicy, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/trafficpolicy", + } + + if input == nil { + input = &CreateTrafficPolicyInput{} + } + + output = &CreateTrafficPolicyOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateTrafficPolicy API operation for Amazon Route 53. +// +// Creates a traffic policy, which you use to create multiple DNS resource record +// sets for one domain name (such as example.com) or one subdomain name (such +// as www.example.com). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation CreateTrafficPolicy for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeTooManyTrafficPolicies "TooManyTrafficPolicies" +// This traffic policy can't be created because the current account has reached +// the limit on the number of traffic policies. +// +// For information about default limits, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) +// in the Amazon Route 53 Developer Guide. +// +// To get the current limit for an account, see GetAccountLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). +// +// To request a higher limit, create a case (http://aws.amazon.com/route53-request) +// with the AWS Support Center. +// +// * ErrCodeTrafficPolicyAlreadyExists "TrafficPolicyAlreadyExists" +// A traffic policy that has the same value for Name already exists. +// +// * ErrCodeInvalidTrafficPolicyDocument "InvalidTrafficPolicyDocument" +// The format of the traffic policy document that you specified in the Document +// element is invalid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateTrafficPolicy +func (c *Route53) CreateTrafficPolicy(input *CreateTrafficPolicyInput) (*CreateTrafficPolicyOutput, error) { + req, out := c.CreateTrafficPolicyRequest(input) + return out, req.Send() +} + +// CreateTrafficPolicyWithContext is the same as CreateTrafficPolicy with the addition of +// the ability to pass a context and additional request options. +// +// See CreateTrafficPolicy for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) CreateTrafficPolicyWithContext(ctx aws.Context, input *CreateTrafficPolicyInput, opts ...request.Option) (*CreateTrafficPolicyOutput, error) { + req, out := c.CreateTrafficPolicyRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateTrafficPolicyInstance = "CreateTrafficPolicyInstance" + +// CreateTrafficPolicyInstanceRequest generates a "aws/request.Request" representing the +// client's request for the CreateTrafficPolicyInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateTrafficPolicyInstance for more information on using the CreateTrafficPolicyInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateTrafficPolicyInstanceRequest method. +// req, resp := client.CreateTrafficPolicyInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateTrafficPolicyInstance +func (c *Route53) CreateTrafficPolicyInstanceRequest(input *CreateTrafficPolicyInstanceInput) (req *request.Request, output *CreateTrafficPolicyInstanceOutput) { + op := &request.Operation{ + Name: opCreateTrafficPolicyInstance, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/trafficpolicyinstance", + } + + if input == nil { + input = &CreateTrafficPolicyInstanceInput{} + } + + output = &CreateTrafficPolicyInstanceOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateTrafficPolicyInstance API operation for Amazon Route 53. +// +// Creates resource record sets in a specified hosted zone based on the settings +// in a specified traffic policy version. In addition, CreateTrafficPolicyInstance +// associates the resource record sets with a specified domain name (such as +// example.com) or subdomain name (such as www.example.com). Amazon Route 53 +// responds to DNS queries for the domain or subdomain name by using the resource +// record sets that CreateTrafficPolicyInstance created. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation CreateTrafficPolicyInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeTooManyTrafficPolicyInstances "TooManyTrafficPolicyInstances" +// This traffic policy instance can't be created because the current account +// has reached the limit on the number of traffic policy instances. +// +// For information about default limits, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) +// in the Amazon Route 53 Developer Guide. +// +// For information about how to get the current limit for an account, see GetAccountLimit +// (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). +// +// To request a higher limit, create a case (http://aws.amazon.com/route53-request) +// with the AWS Support Center. +// +// * ErrCodeNoSuchTrafficPolicy "NoSuchTrafficPolicy" +// No traffic policy exists with the specified ID. +// +// * ErrCodeTrafficPolicyInstanceAlreadyExists "TrafficPolicyInstanceAlreadyExists" +// There is already a traffic policy instance with the specified ID. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateTrafficPolicyInstance +func (c *Route53) CreateTrafficPolicyInstance(input *CreateTrafficPolicyInstanceInput) (*CreateTrafficPolicyInstanceOutput, error) { + req, out := c.CreateTrafficPolicyInstanceRequest(input) + return out, req.Send() +} + +// CreateTrafficPolicyInstanceWithContext is the same as CreateTrafficPolicyInstance with the addition of +// the ability to pass a context and additional request options. +// +// See CreateTrafficPolicyInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) CreateTrafficPolicyInstanceWithContext(ctx aws.Context, input *CreateTrafficPolicyInstanceInput, opts ...request.Option) (*CreateTrafficPolicyInstanceOutput, error) { + req, out := c.CreateTrafficPolicyInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateTrafficPolicyVersion = "CreateTrafficPolicyVersion" + +// CreateTrafficPolicyVersionRequest generates a "aws/request.Request" representing the +// client's request for the CreateTrafficPolicyVersion operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateTrafficPolicyVersion for more information on using the CreateTrafficPolicyVersion +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateTrafficPolicyVersionRequest method. +// req, resp := client.CreateTrafficPolicyVersionRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateTrafficPolicyVersion +func (c *Route53) CreateTrafficPolicyVersionRequest(input *CreateTrafficPolicyVersionInput) (req *request.Request, output *CreateTrafficPolicyVersionOutput) { + op := &request.Operation{ + Name: opCreateTrafficPolicyVersion, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/trafficpolicy/{Id}", + } + + if input == nil { + input = &CreateTrafficPolicyVersionInput{} + } + + output = &CreateTrafficPolicyVersionOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateTrafficPolicyVersion API operation for Amazon Route 53. +// +// Creates a new version of an existing traffic policy. When you create a new +// version of a traffic policy, you specify the ID of the traffic policy that +// you want to update and a JSON-formatted document that describes the new version. +// You use traffic policies to create multiple DNS resource record sets for +// one domain name (such as example.com) or one subdomain name (such as www.example.com). +// You can create a maximum of 1000 versions of a traffic policy. If you reach +// the limit and need to create another version, you'll need to start a new +// traffic policy. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation CreateTrafficPolicyVersion for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchTrafficPolicy "NoSuchTrafficPolicy" +// No traffic policy exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeTooManyTrafficPolicyVersionsForCurrentPolicy "TooManyTrafficPolicyVersionsForCurrentPolicy" +// This traffic policy version can't be created because you've reached the limit +// of 1000 on the number of versions that you can create for the current traffic +// policy. +// +// To create more traffic policy versions, you can use GetTrafficPolicy (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetTrafficPolicy.html) +// to get the traffic policy document for a specified traffic policy version, +// and then use CreateTrafficPolicy (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateTrafficPolicy.html) +// to create a new traffic policy using the traffic policy document. +// +// * ErrCodeConcurrentModification "ConcurrentModification" +// Another user submitted a request to create, update, or delete the object +// at the same time that you did. Retry the request. +// +// * ErrCodeInvalidTrafficPolicyDocument "InvalidTrafficPolicyDocument" +// The format of the traffic policy document that you specified in the Document +// element is invalid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateTrafficPolicyVersion +func (c *Route53) CreateTrafficPolicyVersion(input *CreateTrafficPolicyVersionInput) (*CreateTrafficPolicyVersionOutput, error) { + req, out := c.CreateTrafficPolicyVersionRequest(input) + return out, req.Send() +} + +// CreateTrafficPolicyVersionWithContext is the same as CreateTrafficPolicyVersion with the addition of +// the ability to pass a context and additional request options. +// +// See CreateTrafficPolicyVersion for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) CreateTrafficPolicyVersionWithContext(ctx aws.Context, input *CreateTrafficPolicyVersionInput, opts ...request.Option) (*CreateTrafficPolicyVersionOutput, error) { + req, out := c.CreateTrafficPolicyVersionRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateVPCAssociationAuthorization = "CreateVPCAssociationAuthorization" + +// CreateVPCAssociationAuthorizationRequest generates a "aws/request.Request" representing the +// client's request for the CreateVPCAssociationAuthorization operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateVPCAssociationAuthorization for more information on using the CreateVPCAssociationAuthorization +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateVPCAssociationAuthorizationRequest method. +// req, resp := client.CreateVPCAssociationAuthorizationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateVPCAssociationAuthorization +func (c *Route53) CreateVPCAssociationAuthorizationRequest(input *CreateVPCAssociationAuthorizationInput) (req *request.Request, output *CreateVPCAssociationAuthorizationOutput) { + op := &request.Operation{ + Name: opCreateVPCAssociationAuthorization, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/hostedzone/{Id}/authorizevpcassociation", + } + + if input == nil { + input = &CreateVPCAssociationAuthorizationInput{} + } + + output = &CreateVPCAssociationAuthorizationOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateVPCAssociationAuthorization API operation for Amazon Route 53. +// +// Authorizes the AWS account that created a specified VPC to submit an AssociateVPCWithHostedZone +// request to associate the VPC with a specified hosted zone that was created +// by a different account. To submit a CreateVPCAssociationAuthorization request, +// you must use the account that created the hosted zone. After you authorize +// the association, use the account that created the VPC to submit an AssociateVPCWithHostedZone +// request. +// +// If you want to associate multiple VPCs that you created by using one account +// with a hosted zone that you created by using a different account, you must +// submit one authorization request for each VPC. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation CreateVPCAssociationAuthorization for usage and error information. +// +// Returned Error Codes: +// * ErrCodeConcurrentModification "ConcurrentModification" +// Another user submitted a request to create, update, or delete the object +// at the same time that you did. Retry the request. +// +// * ErrCodeTooManyVPCAssociationAuthorizations "TooManyVPCAssociationAuthorizations" +// You've created the maximum number of authorizations that can be created for +// the specified hosted zone. To authorize another VPC to be associated with +// the hosted zone, submit a DeleteVPCAssociationAuthorization request to remove +// an existing authorization. To get a list of existing authorizations, submit +// a ListVPCAssociationAuthorizations request. +// +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidVPCId "InvalidVPCId" +// The VPC ID that you specified either isn't a valid ID or the current account +// is not authorized to access this VPC. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/CreateVPCAssociationAuthorization +func (c *Route53) CreateVPCAssociationAuthorization(input *CreateVPCAssociationAuthorizationInput) (*CreateVPCAssociationAuthorizationOutput, error) { + req, out := c.CreateVPCAssociationAuthorizationRequest(input) + return out, req.Send() +} + +// CreateVPCAssociationAuthorizationWithContext is the same as CreateVPCAssociationAuthorization with the addition of +// the ability to pass a context and additional request options. +// +// See CreateVPCAssociationAuthorization for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) CreateVPCAssociationAuthorizationWithContext(ctx aws.Context, input *CreateVPCAssociationAuthorizationInput, opts ...request.Option) (*CreateVPCAssociationAuthorizationOutput, error) { + req, out := c.CreateVPCAssociationAuthorizationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteHealthCheck = "DeleteHealthCheck" + +// DeleteHealthCheckRequest generates a "aws/request.Request" representing the +// client's request for the DeleteHealthCheck operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteHealthCheck for more information on using the DeleteHealthCheck +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteHealthCheckRequest method. +// req, resp := client.DeleteHealthCheckRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteHealthCheck +func (c *Route53) DeleteHealthCheckRequest(input *DeleteHealthCheckInput) (req *request.Request, output *DeleteHealthCheckOutput) { + op := &request.Operation{ + Name: opDeleteHealthCheck, + HTTPMethod: "DELETE", + HTTPPath: "/2013-04-01/healthcheck/{HealthCheckId}", + } + + if input == nil { + input = &DeleteHealthCheckInput{} + } + + output = &DeleteHealthCheckOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteHealthCheck API operation for Amazon Route 53. +// +// Deletes a health check. +// +// Amazon Route 53 does not prevent you from deleting a health check even if +// the health check is associated with one or more resource record sets. If +// you delete a health check and you don't update the associated resource record +// sets, the future status of the health check can't be predicted and may change. +// This will affect the routing of DNS queries for your DNS failover configuration. +// For more information, see Replacing and Deleting Health Checks (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-creating-deleting.html#health-checks-deleting.html) +// in the Amazon Route 53 Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation DeleteHealthCheck for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeHealthCheckInUse "HealthCheckInUse" +// This error code is not in use. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteHealthCheck +func (c *Route53) DeleteHealthCheck(input *DeleteHealthCheckInput) (*DeleteHealthCheckOutput, error) { + req, out := c.DeleteHealthCheckRequest(input) + return out, req.Send() +} + +// DeleteHealthCheckWithContext is the same as DeleteHealthCheck with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteHealthCheck for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) DeleteHealthCheckWithContext(ctx aws.Context, input *DeleteHealthCheckInput, opts ...request.Option) (*DeleteHealthCheckOutput, error) { + req, out := c.DeleteHealthCheckRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteHostedZone = "DeleteHostedZone" + +// DeleteHostedZoneRequest generates a "aws/request.Request" representing the +// client's request for the DeleteHostedZone operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteHostedZone for more information on using the DeleteHostedZone +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteHostedZoneRequest method. +// req, resp := client.DeleteHostedZoneRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteHostedZone +func (c *Route53) DeleteHostedZoneRequest(input *DeleteHostedZoneInput) (req *request.Request, output *DeleteHostedZoneOutput) { + op := &request.Operation{ + Name: opDeleteHostedZone, + HTTPMethod: "DELETE", + HTTPPath: "/2013-04-01/hostedzone/{Id}", + } + + if input == nil { + input = &DeleteHostedZoneInput{} + } + + output = &DeleteHostedZoneOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteHostedZone API operation for Amazon Route 53. +// +// Deletes a hosted zone. +// +// If the hosted zone was created by another service, such as AWS Cloud Map, +// see Deleting Public Hosted Zones That Were Created by Another Service (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DeleteHostedZone.html#delete-public-hosted-zone-created-by-another-service) +// in the Amazon Route 53 Developer Guide for information about how to delete +// it. (The process is the same for public and private hosted zones that were +// created by another service.) +// +// If you want to keep your domain registration but you want to stop routing +// internet traffic to your website or web application, we recommend that you +// delete resource record sets in the hosted zone instead of deleting the hosted +// zone. +// +// If you delete a hosted zone, you can't undelete it. You must create a new +// hosted zone and update the name servers for your domain registration, which +// can require up to 48 hours to take effect. (If you delegated responsibility +// for a subdomain to a hosted zone and you delete the child hosted zone, you +// must update the name servers in the parent hosted zone.) In addition, if +// you delete a hosted zone, someone could hijack the domain and route traffic +// to their own resources using your domain name. +// +// If you want to avoid the monthly charge for the hosted zone, you can transfer +// DNS service for the domain to a free DNS service. When you transfer DNS service, +// you have to update the name servers for the domain registration. If the domain +// is registered with Route 53, see UpdateDomainNameservers (https://docs.aws.amazon.com/Route53/latest/APIReference/API_domains_UpdateDomainNameservers.html) +// for information about how to replace Route 53 name servers with name servers +// for the new DNS service. If the domain is registered with another registrar, +// use the method provided by the registrar to update name servers for the domain +// registration. For more information, perform an internet search on "free DNS +// service." +// +// You can delete a hosted zone only if it contains only the default SOA record +// and NS resource record sets. If the hosted zone contains other resource record +// sets, you must delete them before you can delete the hosted zone. If you +// try to delete a hosted zone that contains other resource record sets, the +// request fails, and Route 53 returns a HostedZoneNotEmpty error. For information +// about deleting records from your hosted zone, see ChangeResourceRecordSets +// (https://docs.aws.amazon.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html). +// +// To verify that the hosted zone has been deleted, do one of the following: +// +// * Use the GetHostedZone action to request information about the hosted +// zone. +// +// * Use the ListHostedZones action to get a list of the hosted zones associated +// with the current AWS account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation DeleteHostedZone for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeHostedZoneNotEmpty "HostedZoneNotEmpty" +// The hosted zone contains resource records that are not SOA or NS records. +// +// * ErrCodePriorRequestNotComplete "PriorRequestNotComplete" +// If Amazon Route 53 can't process a request before the next request arrives, +// it will reject subsequent requests for the same hosted zone and return an +// HTTP 400 error (Bad request). If Route 53 returns this error repeatedly for +// the same request, we recommend that you wait, in intervals of increasing +// duration, before you try the request again. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeInvalidDomainName "InvalidDomainName" +// The specified domain name is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteHostedZone +func (c *Route53) DeleteHostedZone(input *DeleteHostedZoneInput) (*DeleteHostedZoneOutput, error) { + req, out := c.DeleteHostedZoneRequest(input) + return out, req.Send() +} + +// DeleteHostedZoneWithContext is the same as DeleteHostedZone with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteHostedZone for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) DeleteHostedZoneWithContext(ctx aws.Context, input *DeleteHostedZoneInput, opts ...request.Option) (*DeleteHostedZoneOutput, error) { + req, out := c.DeleteHostedZoneRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteQueryLoggingConfig = "DeleteQueryLoggingConfig" + +// DeleteQueryLoggingConfigRequest generates a "aws/request.Request" representing the +// client's request for the DeleteQueryLoggingConfig operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteQueryLoggingConfig for more information on using the DeleteQueryLoggingConfig +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteQueryLoggingConfigRequest method. +// req, resp := client.DeleteQueryLoggingConfigRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteQueryLoggingConfig +func (c *Route53) DeleteQueryLoggingConfigRequest(input *DeleteQueryLoggingConfigInput) (req *request.Request, output *DeleteQueryLoggingConfigOutput) { + op := &request.Operation{ + Name: opDeleteQueryLoggingConfig, + HTTPMethod: "DELETE", + HTTPPath: "/2013-04-01/queryloggingconfig/{Id}", + } + + if input == nil { + input = &DeleteQueryLoggingConfigInput{} + } + + output = &DeleteQueryLoggingConfigOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteQueryLoggingConfig API operation for Amazon Route 53. +// +// Deletes a configuration for DNS query logging. If you delete a configuration, +// Amazon Route 53 stops sending query logs to CloudWatch Logs. Route 53 doesn't +// delete any logs that are already in CloudWatch Logs. +// +// For more information about DNS query logs, see CreateQueryLoggingConfig (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateQueryLoggingConfig.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation DeleteQueryLoggingConfig for usage and error information. +// +// Returned Error Codes: +// * ErrCodeConcurrentModification "ConcurrentModification" +// Another user submitted a request to create, update, or delete the object +// at the same time that you did. Retry the request. +// +// * ErrCodeNoSuchQueryLoggingConfig "NoSuchQueryLoggingConfig" +// There is no DNS query logging configuration with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteQueryLoggingConfig +func (c *Route53) DeleteQueryLoggingConfig(input *DeleteQueryLoggingConfigInput) (*DeleteQueryLoggingConfigOutput, error) { + req, out := c.DeleteQueryLoggingConfigRequest(input) + return out, req.Send() +} + +// DeleteQueryLoggingConfigWithContext is the same as DeleteQueryLoggingConfig with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteQueryLoggingConfig for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) DeleteQueryLoggingConfigWithContext(ctx aws.Context, input *DeleteQueryLoggingConfigInput, opts ...request.Option) (*DeleteQueryLoggingConfigOutput, error) { + req, out := c.DeleteQueryLoggingConfigRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteReusableDelegationSet = "DeleteReusableDelegationSet" + +// DeleteReusableDelegationSetRequest generates a "aws/request.Request" representing the +// client's request for the DeleteReusableDelegationSet operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteReusableDelegationSet for more information on using the DeleteReusableDelegationSet +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteReusableDelegationSetRequest method. +// req, resp := client.DeleteReusableDelegationSetRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteReusableDelegationSet +func (c *Route53) DeleteReusableDelegationSetRequest(input *DeleteReusableDelegationSetInput) (req *request.Request, output *DeleteReusableDelegationSetOutput) { + op := &request.Operation{ + Name: opDeleteReusableDelegationSet, + HTTPMethod: "DELETE", + HTTPPath: "/2013-04-01/delegationset/{Id}", + } + + if input == nil { + input = &DeleteReusableDelegationSetInput{} + } + + output = &DeleteReusableDelegationSetOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteReusableDelegationSet API operation for Amazon Route 53. +// +// Deletes a reusable delegation set. +// +// You can delete a reusable delegation set only if it isn't associated with +// any hosted zones. +// +// To verify that the reusable delegation set is not associated with any hosted +// zones, submit a GetReusableDelegationSet (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetReusableDelegationSet.html) +// request and specify the ID of the reusable delegation set that you want to +// delete. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation DeleteReusableDelegationSet for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchDelegationSet "NoSuchDelegationSet" +// A reusable delegation set with the specified ID does not exist. +// +// * ErrCodeDelegationSetInUse "DelegationSetInUse" +// The specified delegation contains associated hosted zones which must be deleted +// before the reusable delegation set can be deleted. +// +// * ErrCodeDelegationSetNotReusable "DelegationSetNotReusable" +// A reusable delegation set with the specified ID does not exist. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteReusableDelegationSet +func (c *Route53) DeleteReusableDelegationSet(input *DeleteReusableDelegationSetInput) (*DeleteReusableDelegationSetOutput, error) { + req, out := c.DeleteReusableDelegationSetRequest(input) + return out, req.Send() +} + +// DeleteReusableDelegationSetWithContext is the same as DeleteReusableDelegationSet with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteReusableDelegationSet for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) DeleteReusableDelegationSetWithContext(ctx aws.Context, input *DeleteReusableDelegationSetInput, opts ...request.Option) (*DeleteReusableDelegationSetOutput, error) { + req, out := c.DeleteReusableDelegationSetRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteTrafficPolicy = "DeleteTrafficPolicy" + +// DeleteTrafficPolicyRequest generates a "aws/request.Request" representing the +// client's request for the DeleteTrafficPolicy operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteTrafficPolicy for more information on using the DeleteTrafficPolicy +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteTrafficPolicyRequest method. +// req, resp := client.DeleteTrafficPolicyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteTrafficPolicy +func (c *Route53) DeleteTrafficPolicyRequest(input *DeleteTrafficPolicyInput) (req *request.Request, output *DeleteTrafficPolicyOutput) { + op := &request.Operation{ + Name: opDeleteTrafficPolicy, + HTTPMethod: "DELETE", + HTTPPath: "/2013-04-01/trafficpolicy/{Id}/{Version}", + } + + if input == nil { + input = &DeleteTrafficPolicyInput{} + } + + output = &DeleteTrafficPolicyOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteTrafficPolicy API operation for Amazon Route 53. +// +// Deletes a traffic policy. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation DeleteTrafficPolicy for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchTrafficPolicy "NoSuchTrafficPolicy" +// No traffic policy exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeTrafficPolicyInUse "TrafficPolicyInUse" +// One or more traffic policy instances were created by using the specified +// traffic policy. +// +// * ErrCodeConcurrentModification "ConcurrentModification" +// Another user submitted a request to create, update, or delete the object +// at the same time that you did. Retry the request. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteTrafficPolicy +func (c *Route53) DeleteTrafficPolicy(input *DeleteTrafficPolicyInput) (*DeleteTrafficPolicyOutput, error) { + req, out := c.DeleteTrafficPolicyRequest(input) + return out, req.Send() +} + +// DeleteTrafficPolicyWithContext is the same as DeleteTrafficPolicy with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteTrafficPolicy for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) DeleteTrafficPolicyWithContext(ctx aws.Context, input *DeleteTrafficPolicyInput, opts ...request.Option) (*DeleteTrafficPolicyOutput, error) { + req, out := c.DeleteTrafficPolicyRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteTrafficPolicyInstance = "DeleteTrafficPolicyInstance" + +// DeleteTrafficPolicyInstanceRequest generates a "aws/request.Request" representing the +// client's request for the DeleteTrafficPolicyInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteTrafficPolicyInstance for more information on using the DeleteTrafficPolicyInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteTrafficPolicyInstanceRequest method. +// req, resp := client.DeleteTrafficPolicyInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteTrafficPolicyInstance +func (c *Route53) DeleteTrafficPolicyInstanceRequest(input *DeleteTrafficPolicyInstanceInput) (req *request.Request, output *DeleteTrafficPolicyInstanceOutput) { + op := &request.Operation{ + Name: opDeleteTrafficPolicyInstance, + HTTPMethod: "DELETE", + HTTPPath: "/2013-04-01/trafficpolicyinstance/{Id}", + } + + if input == nil { + input = &DeleteTrafficPolicyInstanceInput{} + } + + output = &DeleteTrafficPolicyInstanceOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteTrafficPolicyInstance API operation for Amazon Route 53. +// +// Deletes a traffic policy instance and all of the resource record sets that +// Amazon Route 53 created when you created the instance. +// +// In the Route 53 console, traffic policy instances are known as policy records. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation DeleteTrafficPolicyInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchTrafficPolicyInstance "NoSuchTrafficPolicyInstance" +// No traffic policy instance exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodePriorRequestNotComplete "PriorRequestNotComplete" +// If Amazon Route 53 can't process a request before the next request arrives, +// it will reject subsequent requests for the same hosted zone and return an +// HTTP 400 error (Bad request). If Route 53 returns this error repeatedly for +// the same request, we recommend that you wait, in intervals of increasing +// duration, before you try the request again. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteTrafficPolicyInstance +func (c *Route53) DeleteTrafficPolicyInstance(input *DeleteTrafficPolicyInstanceInput) (*DeleteTrafficPolicyInstanceOutput, error) { + req, out := c.DeleteTrafficPolicyInstanceRequest(input) + return out, req.Send() +} + +// DeleteTrafficPolicyInstanceWithContext is the same as DeleteTrafficPolicyInstance with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteTrafficPolicyInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) DeleteTrafficPolicyInstanceWithContext(ctx aws.Context, input *DeleteTrafficPolicyInstanceInput, opts ...request.Option) (*DeleteTrafficPolicyInstanceOutput, error) { + req, out := c.DeleteTrafficPolicyInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteVPCAssociationAuthorization = "DeleteVPCAssociationAuthorization" + +// DeleteVPCAssociationAuthorizationRequest generates a "aws/request.Request" representing the +// client's request for the DeleteVPCAssociationAuthorization operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteVPCAssociationAuthorization for more information on using the DeleteVPCAssociationAuthorization +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteVPCAssociationAuthorizationRequest method. +// req, resp := client.DeleteVPCAssociationAuthorizationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteVPCAssociationAuthorization +func (c *Route53) DeleteVPCAssociationAuthorizationRequest(input *DeleteVPCAssociationAuthorizationInput) (req *request.Request, output *DeleteVPCAssociationAuthorizationOutput) { + op := &request.Operation{ + Name: opDeleteVPCAssociationAuthorization, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/hostedzone/{Id}/deauthorizevpcassociation", + } + + if input == nil { + input = &DeleteVPCAssociationAuthorizationInput{} + } + + output = &DeleteVPCAssociationAuthorizationOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restxml.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteVPCAssociationAuthorization API operation for Amazon Route 53. +// +// Removes authorization to submit an AssociateVPCWithHostedZone request to +// associate a specified VPC with a hosted zone that was created by a different +// account. You must use the account that created the hosted zone to submit +// a DeleteVPCAssociationAuthorization request. +// +// Sending this request only prevents the AWS account that created the VPC from +// associating the VPC with the Amazon Route 53 hosted zone in the future. If +// the VPC is already associated with the hosted zone, DeleteVPCAssociationAuthorization +// won't disassociate the VPC from the hosted zone. If you want to delete an +// existing association, use DisassociateVPCFromHostedZone. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation DeleteVPCAssociationAuthorization for usage and error information. +// +// Returned Error Codes: +// * ErrCodeConcurrentModification "ConcurrentModification" +// Another user submitted a request to create, update, or delete the object +// at the same time that you did. Retry the request. +// +// * ErrCodeVPCAssociationAuthorizationNotFound "VPCAssociationAuthorizationNotFound" +// The VPC that you specified is not authorized to be associated with the hosted +// zone. +// +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidVPCId "InvalidVPCId" +// The VPC ID that you specified either isn't a valid ID or the current account +// is not authorized to access this VPC. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DeleteVPCAssociationAuthorization +func (c *Route53) DeleteVPCAssociationAuthorization(input *DeleteVPCAssociationAuthorizationInput) (*DeleteVPCAssociationAuthorizationOutput, error) { + req, out := c.DeleteVPCAssociationAuthorizationRequest(input) + return out, req.Send() +} + +// DeleteVPCAssociationAuthorizationWithContext is the same as DeleteVPCAssociationAuthorization with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteVPCAssociationAuthorization for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) DeleteVPCAssociationAuthorizationWithContext(ctx aws.Context, input *DeleteVPCAssociationAuthorizationInput, opts ...request.Option) (*DeleteVPCAssociationAuthorizationOutput, error) { + req, out := c.DeleteVPCAssociationAuthorizationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDisassociateVPCFromHostedZone = "DisassociateVPCFromHostedZone" + +// DisassociateVPCFromHostedZoneRequest generates a "aws/request.Request" representing the +// client's request for the DisassociateVPCFromHostedZone operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DisassociateVPCFromHostedZone for more information on using the DisassociateVPCFromHostedZone +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DisassociateVPCFromHostedZoneRequest method. +// req, resp := client.DisassociateVPCFromHostedZoneRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DisassociateVPCFromHostedZone +func (c *Route53) DisassociateVPCFromHostedZoneRequest(input *DisassociateVPCFromHostedZoneInput) (req *request.Request, output *DisassociateVPCFromHostedZoneOutput) { + op := &request.Operation{ + Name: opDisassociateVPCFromHostedZone, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/hostedzone/{Id}/disassociatevpc", + } + + if input == nil { + input = &DisassociateVPCFromHostedZoneInput{} + } + + output = &DisassociateVPCFromHostedZoneOutput{} + req = c.newRequest(op, input, output) + return +} + +// DisassociateVPCFromHostedZone API operation for Amazon Route 53. +// +// Disassociates a VPC from a Amazon Route 53 private hosted zone. Note the +// following: +// +// * You can't disassociate the last VPC from a private hosted zone. +// +// * You can't convert a private hosted zone into a public hosted zone. +// +// * You can submit a DisassociateVPCFromHostedZone request using either +// the account that created the hosted zone or the account that created the +// VPC. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation DisassociateVPCFromHostedZone for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidVPCId "InvalidVPCId" +// The VPC ID that you specified either isn't a valid ID or the current account +// is not authorized to access this VPC. +// +// * ErrCodeVPCAssociationNotFound "VPCAssociationNotFound" +// The specified VPC and hosted zone are not currently associated. +// +// * ErrCodeLastVPCAssociation "LastVPCAssociation" +// The VPC that you're trying to disassociate from the private hosted zone is +// the last VPC that is associated with the hosted zone. Amazon Route 53 doesn't +// support disassociating the last VPC from a hosted zone. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/DisassociateVPCFromHostedZone +func (c *Route53) DisassociateVPCFromHostedZone(input *DisassociateVPCFromHostedZoneInput) (*DisassociateVPCFromHostedZoneOutput, error) { + req, out := c.DisassociateVPCFromHostedZoneRequest(input) + return out, req.Send() +} + +// DisassociateVPCFromHostedZoneWithContext is the same as DisassociateVPCFromHostedZone with the addition of +// the ability to pass a context and additional request options. +// +// See DisassociateVPCFromHostedZone for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) DisassociateVPCFromHostedZoneWithContext(ctx aws.Context, input *DisassociateVPCFromHostedZoneInput, opts ...request.Option) (*DisassociateVPCFromHostedZoneOutput, error) { + req, out := c.DisassociateVPCFromHostedZoneRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetAccountLimit = "GetAccountLimit" + +// GetAccountLimitRequest generates a "aws/request.Request" representing the +// client's request for the GetAccountLimit operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetAccountLimit for more information on using the GetAccountLimit +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetAccountLimitRequest method. +// req, resp := client.GetAccountLimitRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetAccountLimit +func (c *Route53) GetAccountLimitRequest(input *GetAccountLimitInput) (req *request.Request, output *GetAccountLimitOutput) { + op := &request.Operation{ + Name: opGetAccountLimit, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/accountlimit/{Type}", + } + + if input == nil { + input = &GetAccountLimitInput{} + } + + output = &GetAccountLimitOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetAccountLimit API operation for Amazon Route 53. +// +// Gets the specified limit for the current account, for example, the maximum +// number of health checks that you can create using the account. +// +// For the default limit, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) +// in the Amazon Route 53 Developer Guide. To request a higher limit, open a +// case (https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase&limitType=service-code-route53). +// +// You can also view account limits in AWS Trusted Advisor. Sign in to the AWS +// Management Console and open the Trusted Advisor console at https://console.aws.amazon.com/trustedadvisor/ +// (https://console.aws.amazon.com/trustedadvisor). Then choose Service limits +// in the navigation pane. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetAccountLimit for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetAccountLimit +func (c *Route53) GetAccountLimit(input *GetAccountLimitInput) (*GetAccountLimitOutput, error) { + req, out := c.GetAccountLimitRequest(input) + return out, req.Send() +} + +// GetAccountLimitWithContext is the same as GetAccountLimit with the addition of +// the ability to pass a context and additional request options. +// +// See GetAccountLimit for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetAccountLimitWithContext(ctx aws.Context, input *GetAccountLimitInput, opts ...request.Option) (*GetAccountLimitOutput, error) { + req, out := c.GetAccountLimitRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetChange = "GetChange" + +// GetChangeRequest generates a "aws/request.Request" representing the +// client's request for the GetChange operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetChange for more information on using the GetChange +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetChangeRequest method. +// req, resp := client.GetChangeRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetChange +func (c *Route53) GetChangeRequest(input *GetChangeInput) (req *request.Request, output *GetChangeOutput) { + op := &request.Operation{ + Name: opGetChange, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/change/{Id}", + } + + if input == nil { + input = &GetChangeInput{} + } + + output = &GetChangeOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetChange API operation for Amazon Route 53. +// +// Returns the current status of a change batch request. The status is one of +// the following values: +// +// * PENDING indicates that the changes in this request have not propagated +// to all Amazon Route 53 DNS servers. This is the initial status of all +// change batch requests. +// +// * INSYNC indicates that the changes have propagated to all Route 53 DNS +// servers. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetChange for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchChange "NoSuchChange" +// A change with the specified change ID does not exist. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetChange +func (c *Route53) GetChange(input *GetChangeInput) (*GetChangeOutput, error) { + req, out := c.GetChangeRequest(input) + return out, req.Send() +} + +// GetChangeWithContext is the same as GetChange with the addition of +// the ability to pass a context and additional request options. +// +// See GetChange for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetChangeWithContext(ctx aws.Context, input *GetChangeInput, opts ...request.Option) (*GetChangeOutput, error) { + req, out := c.GetChangeRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetCheckerIpRanges = "GetCheckerIpRanges" + +// GetCheckerIpRangesRequest generates a "aws/request.Request" representing the +// client's request for the GetCheckerIpRanges operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetCheckerIpRanges for more information on using the GetCheckerIpRanges +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetCheckerIpRangesRequest method. +// req, resp := client.GetCheckerIpRangesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetCheckerIpRanges +func (c *Route53) GetCheckerIpRangesRequest(input *GetCheckerIpRangesInput) (req *request.Request, output *GetCheckerIpRangesOutput) { + op := &request.Operation{ + Name: opGetCheckerIpRanges, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/checkeripranges", + } + + if input == nil { + input = &GetCheckerIpRangesInput{} + } + + output = &GetCheckerIpRangesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetCheckerIpRanges API operation for Amazon Route 53. +// +// +// GetCheckerIpRanges still works, but we recommend that you download ip-ranges.json, +// which includes IP address ranges for all AWS services. For more information, +// see IP Address Ranges of Amazon Route 53 Servers (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/route-53-ip-addresses.html) +// in the Amazon Route 53 Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetCheckerIpRanges for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetCheckerIpRanges +func (c *Route53) GetCheckerIpRanges(input *GetCheckerIpRangesInput) (*GetCheckerIpRangesOutput, error) { + req, out := c.GetCheckerIpRangesRequest(input) + return out, req.Send() +} + +// GetCheckerIpRangesWithContext is the same as GetCheckerIpRanges with the addition of +// the ability to pass a context and additional request options. +// +// See GetCheckerIpRanges for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetCheckerIpRangesWithContext(ctx aws.Context, input *GetCheckerIpRangesInput, opts ...request.Option) (*GetCheckerIpRangesOutput, error) { + req, out := c.GetCheckerIpRangesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetGeoLocation = "GetGeoLocation" + +// GetGeoLocationRequest generates a "aws/request.Request" representing the +// client's request for the GetGeoLocation operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetGeoLocation for more information on using the GetGeoLocation +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetGeoLocationRequest method. +// req, resp := client.GetGeoLocationRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetGeoLocation +func (c *Route53) GetGeoLocationRequest(input *GetGeoLocationInput) (req *request.Request, output *GetGeoLocationOutput) { + op := &request.Operation{ + Name: opGetGeoLocation, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/geolocation", + } + + if input == nil { + input = &GetGeoLocationInput{} + } + + output = &GetGeoLocationOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetGeoLocation API operation for Amazon Route 53. +// +// Gets information about whether a specified geographic location is supported +// for Amazon Route 53 geolocation resource record sets. +// +// Use the following syntax to determine whether a continent is supported for +// geolocation: +// +// GET /2013-04-01/geolocation?continentcode=two-letter abbreviation for a continent +// +// Use the following syntax to determine whether a country is supported for +// geolocation: +// +// GET /2013-04-01/geolocation?countrycode=two-character country code +// +// Use the following syntax to determine whether a subdivision of a country +// is supported for geolocation: +// +// GET /2013-04-01/geolocation?countrycode=two-character country code&subdivisioncode=subdivision +// code +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetGeoLocation for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchGeoLocation "NoSuchGeoLocation" +// Amazon Route 53 doesn't support the specified geographic location. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetGeoLocation +func (c *Route53) GetGeoLocation(input *GetGeoLocationInput) (*GetGeoLocationOutput, error) { + req, out := c.GetGeoLocationRequest(input) + return out, req.Send() +} + +// GetGeoLocationWithContext is the same as GetGeoLocation with the addition of +// the ability to pass a context and additional request options. +// +// See GetGeoLocation for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetGeoLocationWithContext(ctx aws.Context, input *GetGeoLocationInput, opts ...request.Option) (*GetGeoLocationOutput, error) { + req, out := c.GetGeoLocationRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetHealthCheck = "GetHealthCheck" + +// GetHealthCheckRequest generates a "aws/request.Request" representing the +// client's request for the GetHealthCheck operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetHealthCheck for more information on using the GetHealthCheck +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetHealthCheckRequest method. +// req, resp := client.GetHealthCheckRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheck +func (c *Route53) GetHealthCheckRequest(input *GetHealthCheckInput) (req *request.Request, output *GetHealthCheckOutput) { + op := &request.Operation{ + Name: opGetHealthCheck, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/healthcheck/{HealthCheckId}", + } + + if input == nil { + input = &GetHealthCheckInput{} + } + + output = &GetHealthCheckOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetHealthCheck API operation for Amazon Route 53. +// +// Gets information about a specified health check. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetHealthCheck for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeIncompatibleVersion "IncompatibleVersion" +// The resource you're trying to access is unsupported on this Amazon Route +// 53 endpoint. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheck +func (c *Route53) GetHealthCheck(input *GetHealthCheckInput) (*GetHealthCheckOutput, error) { + req, out := c.GetHealthCheckRequest(input) + return out, req.Send() +} + +// GetHealthCheckWithContext is the same as GetHealthCheck with the addition of +// the ability to pass a context and additional request options. +// +// See GetHealthCheck for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetHealthCheckWithContext(ctx aws.Context, input *GetHealthCheckInput, opts ...request.Option) (*GetHealthCheckOutput, error) { + req, out := c.GetHealthCheckRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetHealthCheckCount = "GetHealthCheckCount" + +// GetHealthCheckCountRequest generates a "aws/request.Request" representing the +// client's request for the GetHealthCheckCount operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetHealthCheckCount for more information on using the GetHealthCheckCount +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetHealthCheckCountRequest method. +// req, resp := client.GetHealthCheckCountRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckCount +func (c *Route53) GetHealthCheckCountRequest(input *GetHealthCheckCountInput) (req *request.Request, output *GetHealthCheckCountOutput) { + op := &request.Operation{ + Name: opGetHealthCheckCount, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/healthcheckcount", + } + + if input == nil { + input = &GetHealthCheckCountInput{} + } + + output = &GetHealthCheckCountOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetHealthCheckCount API operation for Amazon Route 53. +// +// Retrieves the number of health checks that are associated with the current +// AWS account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetHealthCheckCount for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckCount +func (c *Route53) GetHealthCheckCount(input *GetHealthCheckCountInput) (*GetHealthCheckCountOutput, error) { + req, out := c.GetHealthCheckCountRequest(input) + return out, req.Send() +} + +// GetHealthCheckCountWithContext is the same as GetHealthCheckCount with the addition of +// the ability to pass a context and additional request options. +// +// See GetHealthCheckCount for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetHealthCheckCountWithContext(ctx aws.Context, input *GetHealthCheckCountInput, opts ...request.Option) (*GetHealthCheckCountOutput, error) { + req, out := c.GetHealthCheckCountRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetHealthCheckLastFailureReason = "GetHealthCheckLastFailureReason" + +// GetHealthCheckLastFailureReasonRequest generates a "aws/request.Request" representing the +// client's request for the GetHealthCheckLastFailureReason operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetHealthCheckLastFailureReason for more information on using the GetHealthCheckLastFailureReason +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetHealthCheckLastFailureReasonRequest method. +// req, resp := client.GetHealthCheckLastFailureReasonRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckLastFailureReason +func (c *Route53) GetHealthCheckLastFailureReasonRequest(input *GetHealthCheckLastFailureReasonInput) (req *request.Request, output *GetHealthCheckLastFailureReasonOutput) { + op := &request.Operation{ + Name: opGetHealthCheckLastFailureReason, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/healthcheck/{HealthCheckId}/lastfailurereason", + } + + if input == nil { + input = &GetHealthCheckLastFailureReasonInput{} + } + + output = &GetHealthCheckLastFailureReasonOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetHealthCheckLastFailureReason API operation for Amazon Route 53. +// +// Gets the reason that a specified health check failed most recently. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetHealthCheckLastFailureReason for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckLastFailureReason +func (c *Route53) GetHealthCheckLastFailureReason(input *GetHealthCheckLastFailureReasonInput) (*GetHealthCheckLastFailureReasonOutput, error) { + req, out := c.GetHealthCheckLastFailureReasonRequest(input) + return out, req.Send() +} + +// GetHealthCheckLastFailureReasonWithContext is the same as GetHealthCheckLastFailureReason with the addition of +// the ability to pass a context and additional request options. +// +// See GetHealthCheckLastFailureReason for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetHealthCheckLastFailureReasonWithContext(ctx aws.Context, input *GetHealthCheckLastFailureReasonInput, opts ...request.Option) (*GetHealthCheckLastFailureReasonOutput, error) { + req, out := c.GetHealthCheckLastFailureReasonRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetHealthCheckStatus = "GetHealthCheckStatus" + +// GetHealthCheckStatusRequest generates a "aws/request.Request" representing the +// client's request for the GetHealthCheckStatus operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetHealthCheckStatus for more information on using the GetHealthCheckStatus +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetHealthCheckStatusRequest method. +// req, resp := client.GetHealthCheckStatusRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckStatus +func (c *Route53) GetHealthCheckStatusRequest(input *GetHealthCheckStatusInput) (req *request.Request, output *GetHealthCheckStatusOutput) { + op := &request.Operation{ + Name: opGetHealthCheckStatus, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/healthcheck/{HealthCheckId}/status", + } + + if input == nil { + input = &GetHealthCheckStatusInput{} + } + + output = &GetHealthCheckStatusOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetHealthCheckStatus API operation for Amazon Route 53. +// +// Gets status of a specified health check. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetHealthCheckStatus for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHealthCheckStatus +func (c *Route53) GetHealthCheckStatus(input *GetHealthCheckStatusInput) (*GetHealthCheckStatusOutput, error) { + req, out := c.GetHealthCheckStatusRequest(input) + return out, req.Send() +} + +// GetHealthCheckStatusWithContext is the same as GetHealthCheckStatus with the addition of +// the ability to pass a context and additional request options. +// +// See GetHealthCheckStatus for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetHealthCheckStatusWithContext(ctx aws.Context, input *GetHealthCheckStatusInput, opts ...request.Option) (*GetHealthCheckStatusOutput, error) { + req, out := c.GetHealthCheckStatusRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetHostedZone = "GetHostedZone" + +// GetHostedZoneRequest generates a "aws/request.Request" representing the +// client's request for the GetHostedZone operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetHostedZone for more information on using the GetHostedZone +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetHostedZoneRequest method. +// req, resp := client.GetHostedZoneRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZone +func (c *Route53) GetHostedZoneRequest(input *GetHostedZoneInput) (req *request.Request, output *GetHostedZoneOutput) { + op := &request.Operation{ + Name: opGetHostedZone, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/hostedzone/{Id}", + } + + if input == nil { + input = &GetHostedZoneInput{} + } + + output = &GetHostedZoneOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetHostedZone API operation for Amazon Route 53. +// +// Gets information about a specified hosted zone including the four name servers +// assigned to the hosted zone. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetHostedZone for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZone +func (c *Route53) GetHostedZone(input *GetHostedZoneInput) (*GetHostedZoneOutput, error) { + req, out := c.GetHostedZoneRequest(input) + return out, req.Send() +} + +// GetHostedZoneWithContext is the same as GetHostedZone with the addition of +// the ability to pass a context and additional request options. +// +// See GetHostedZone for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetHostedZoneWithContext(ctx aws.Context, input *GetHostedZoneInput, opts ...request.Option) (*GetHostedZoneOutput, error) { + req, out := c.GetHostedZoneRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetHostedZoneCount = "GetHostedZoneCount" + +// GetHostedZoneCountRequest generates a "aws/request.Request" representing the +// client's request for the GetHostedZoneCount operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetHostedZoneCount for more information on using the GetHostedZoneCount +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetHostedZoneCountRequest method. +// req, resp := client.GetHostedZoneCountRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZoneCount +func (c *Route53) GetHostedZoneCountRequest(input *GetHostedZoneCountInput) (req *request.Request, output *GetHostedZoneCountOutput) { + op := &request.Operation{ + Name: opGetHostedZoneCount, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/hostedzonecount", + } + + if input == nil { + input = &GetHostedZoneCountInput{} + } + + output = &GetHostedZoneCountOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetHostedZoneCount API operation for Amazon Route 53. +// +// Retrieves the number of hosted zones that are associated with the current +// AWS account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetHostedZoneCount for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZoneCount +func (c *Route53) GetHostedZoneCount(input *GetHostedZoneCountInput) (*GetHostedZoneCountOutput, error) { + req, out := c.GetHostedZoneCountRequest(input) + return out, req.Send() +} + +// GetHostedZoneCountWithContext is the same as GetHostedZoneCount with the addition of +// the ability to pass a context and additional request options. +// +// See GetHostedZoneCount for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetHostedZoneCountWithContext(ctx aws.Context, input *GetHostedZoneCountInput, opts ...request.Option) (*GetHostedZoneCountOutput, error) { + req, out := c.GetHostedZoneCountRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetHostedZoneLimit = "GetHostedZoneLimit" + +// GetHostedZoneLimitRequest generates a "aws/request.Request" representing the +// client's request for the GetHostedZoneLimit operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetHostedZoneLimit for more information on using the GetHostedZoneLimit +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetHostedZoneLimitRequest method. +// req, resp := client.GetHostedZoneLimitRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZoneLimit +func (c *Route53) GetHostedZoneLimitRequest(input *GetHostedZoneLimitInput) (req *request.Request, output *GetHostedZoneLimitOutput) { + op := &request.Operation{ + Name: opGetHostedZoneLimit, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/hostedzonelimit/{Id}/{Type}", + } + + if input == nil { + input = &GetHostedZoneLimitInput{} + } + + output = &GetHostedZoneLimitOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetHostedZoneLimit API operation for Amazon Route 53. +// +// Gets the specified limit for a specified hosted zone, for example, the maximum +// number of records that you can create in the hosted zone. +// +// For the default limit, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) +// in the Amazon Route 53 Developer Guide. To request a higher limit, open a +// case (https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase&limitType=service-code-route53). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetHostedZoneLimit for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeHostedZoneNotPrivate "HostedZoneNotPrivate" +// The specified hosted zone is a public hosted zone, not a private hosted zone. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetHostedZoneLimit +func (c *Route53) GetHostedZoneLimit(input *GetHostedZoneLimitInput) (*GetHostedZoneLimitOutput, error) { + req, out := c.GetHostedZoneLimitRequest(input) + return out, req.Send() +} + +// GetHostedZoneLimitWithContext is the same as GetHostedZoneLimit with the addition of +// the ability to pass a context and additional request options. +// +// See GetHostedZoneLimit for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetHostedZoneLimitWithContext(ctx aws.Context, input *GetHostedZoneLimitInput, opts ...request.Option) (*GetHostedZoneLimitOutput, error) { + req, out := c.GetHostedZoneLimitRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetQueryLoggingConfig = "GetQueryLoggingConfig" + +// GetQueryLoggingConfigRequest generates a "aws/request.Request" representing the +// client's request for the GetQueryLoggingConfig operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetQueryLoggingConfig for more information on using the GetQueryLoggingConfig +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetQueryLoggingConfigRequest method. +// req, resp := client.GetQueryLoggingConfigRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetQueryLoggingConfig +func (c *Route53) GetQueryLoggingConfigRequest(input *GetQueryLoggingConfigInput) (req *request.Request, output *GetQueryLoggingConfigOutput) { + op := &request.Operation{ + Name: opGetQueryLoggingConfig, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/queryloggingconfig/{Id}", + } + + if input == nil { + input = &GetQueryLoggingConfigInput{} + } + + output = &GetQueryLoggingConfigOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetQueryLoggingConfig API operation for Amazon Route 53. +// +// Gets information about a specified configuration for DNS query logging. +// +// For more information about DNS query logs, see CreateQueryLoggingConfig (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateQueryLoggingConfig.html) +// and Logging DNS Queries (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/query-logs.html). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetQueryLoggingConfig for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchQueryLoggingConfig "NoSuchQueryLoggingConfig" +// There is no DNS query logging configuration with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetQueryLoggingConfig +func (c *Route53) GetQueryLoggingConfig(input *GetQueryLoggingConfigInput) (*GetQueryLoggingConfigOutput, error) { + req, out := c.GetQueryLoggingConfigRequest(input) + return out, req.Send() +} + +// GetQueryLoggingConfigWithContext is the same as GetQueryLoggingConfig with the addition of +// the ability to pass a context and additional request options. +// +// See GetQueryLoggingConfig for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetQueryLoggingConfigWithContext(ctx aws.Context, input *GetQueryLoggingConfigInput, opts ...request.Option) (*GetQueryLoggingConfigOutput, error) { + req, out := c.GetQueryLoggingConfigRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetReusableDelegationSet = "GetReusableDelegationSet" + +// GetReusableDelegationSetRequest generates a "aws/request.Request" representing the +// client's request for the GetReusableDelegationSet operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetReusableDelegationSet for more information on using the GetReusableDelegationSet +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetReusableDelegationSetRequest method. +// req, resp := client.GetReusableDelegationSetRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetReusableDelegationSet +func (c *Route53) GetReusableDelegationSetRequest(input *GetReusableDelegationSetInput) (req *request.Request, output *GetReusableDelegationSetOutput) { + op := &request.Operation{ + Name: opGetReusableDelegationSet, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/delegationset/{Id}", + } + + if input == nil { + input = &GetReusableDelegationSetInput{} + } + + output = &GetReusableDelegationSetOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetReusableDelegationSet API operation for Amazon Route 53. +// +// Retrieves information about a specified reusable delegation set, including +// the four name servers that are assigned to the delegation set. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetReusableDelegationSet for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchDelegationSet "NoSuchDelegationSet" +// A reusable delegation set with the specified ID does not exist. +// +// * ErrCodeDelegationSetNotReusable "DelegationSetNotReusable" +// A reusable delegation set with the specified ID does not exist. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetReusableDelegationSet +func (c *Route53) GetReusableDelegationSet(input *GetReusableDelegationSetInput) (*GetReusableDelegationSetOutput, error) { + req, out := c.GetReusableDelegationSetRequest(input) + return out, req.Send() +} + +// GetReusableDelegationSetWithContext is the same as GetReusableDelegationSet with the addition of +// the ability to pass a context and additional request options. +// +// See GetReusableDelegationSet for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetReusableDelegationSetWithContext(ctx aws.Context, input *GetReusableDelegationSetInput, opts ...request.Option) (*GetReusableDelegationSetOutput, error) { + req, out := c.GetReusableDelegationSetRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetReusableDelegationSetLimit = "GetReusableDelegationSetLimit" + +// GetReusableDelegationSetLimitRequest generates a "aws/request.Request" representing the +// client's request for the GetReusableDelegationSetLimit operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetReusableDelegationSetLimit for more information on using the GetReusableDelegationSetLimit +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetReusableDelegationSetLimitRequest method. +// req, resp := client.GetReusableDelegationSetLimitRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetReusableDelegationSetLimit +func (c *Route53) GetReusableDelegationSetLimitRequest(input *GetReusableDelegationSetLimitInput) (req *request.Request, output *GetReusableDelegationSetLimitOutput) { + op := &request.Operation{ + Name: opGetReusableDelegationSetLimit, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/reusabledelegationsetlimit/{Id}/{Type}", + } + + if input == nil { + input = &GetReusableDelegationSetLimitInput{} + } + + output = &GetReusableDelegationSetLimitOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetReusableDelegationSetLimit API operation for Amazon Route 53. +// +// Gets the maximum number of hosted zones that you can associate with the specified +// reusable delegation set. +// +// For the default limit, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) +// in the Amazon Route 53 Developer Guide. To request a higher limit, open a +// case (https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase&limitType=service-code-route53). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetReusableDelegationSetLimit for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchDelegationSet "NoSuchDelegationSet" +// A reusable delegation set with the specified ID does not exist. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetReusableDelegationSetLimit +func (c *Route53) GetReusableDelegationSetLimit(input *GetReusableDelegationSetLimitInput) (*GetReusableDelegationSetLimitOutput, error) { + req, out := c.GetReusableDelegationSetLimitRequest(input) + return out, req.Send() +} + +// GetReusableDelegationSetLimitWithContext is the same as GetReusableDelegationSetLimit with the addition of +// the ability to pass a context and additional request options. +// +// See GetReusableDelegationSetLimit for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetReusableDelegationSetLimitWithContext(ctx aws.Context, input *GetReusableDelegationSetLimitInput, opts ...request.Option) (*GetReusableDelegationSetLimitOutput, error) { + req, out := c.GetReusableDelegationSetLimitRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetTrafficPolicy = "GetTrafficPolicy" + +// GetTrafficPolicyRequest generates a "aws/request.Request" representing the +// client's request for the GetTrafficPolicy operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetTrafficPolicy for more information on using the GetTrafficPolicy +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetTrafficPolicyRequest method. +// req, resp := client.GetTrafficPolicyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetTrafficPolicy +func (c *Route53) GetTrafficPolicyRequest(input *GetTrafficPolicyInput) (req *request.Request, output *GetTrafficPolicyOutput) { + op := &request.Operation{ + Name: opGetTrafficPolicy, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/trafficpolicy/{Id}/{Version}", + } + + if input == nil { + input = &GetTrafficPolicyInput{} + } + + output = &GetTrafficPolicyOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetTrafficPolicy API operation for Amazon Route 53. +// +// Gets information about a specific traffic policy version. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetTrafficPolicy for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchTrafficPolicy "NoSuchTrafficPolicy" +// No traffic policy exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetTrafficPolicy +func (c *Route53) GetTrafficPolicy(input *GetTrafficPolicyInput) (*GetTrafficPolicyOutput, error) { + req, out := c.GetTrafficPolicyRequest(input) + return out, req.Send() +} + +// GetTrafficPolicyWithContext is the same as GetTrafficPolicy with the addition of +// the ability to pass a context and additional request options. +// +// See GetTrafficPolicy for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetTrafficPolicyWithContext(ctx aws.Context, input *GetTrafficPolicyInput, opts ...request.Option) (*GetTrafficPolicyOutput, error) { + req, out := c.GetTrafficPolicyRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetTrafficPolicyInstance = "GetTrafficPolicyInstance" + +// GetTrafficPolicyInstanceRequest generates a "aws/request.Request" representing the +// client's request for the GetTrafficPolicyInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetTrafficPolicyInstance for more information on using the GetTrafficPolicyInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetTrafficPolicyInstanceRequest method. +// req, resp := client.GetTrafficPolicyInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetTrafficPolicyInstance +func (c *Route53) GetTrafficPolicyInstanceRequest(input *GetTrafficPolicyInstanceInput) (req *request.Request, output *GetTrafficPolicyInstanceOutput) { + op := &request.Operation{ + Name: opGetTrafficPolicyInstance, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/trafficpolicyinstance/{Id}", + } + + if input == nil { + input = &GetTrafficPolicyInstanceInput{} + } + + output = &GetTrafficPolicyInstanceOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetTrafficPolicyInstance API operation for Amazon Route 53. +// +// Gets information about a specified traffic policy instance. +// +// After you submit a CreateTrafficPolicyInstance or an UpdateTrafficPolicyInstance +// request, there's a brief delay while Amazon Route 53 creates the resource +// record sets that are specified in the traffic policy definition. For more +// information, see the State response element. +// +// In the Route 53 console, traffic policy instances are known as policy records. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetTrafficPolicyInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchTrafficPolicyInstance "NoSuchTrafficPolicyInstance" +// No traffic policy instance exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetTrafficPolicyInstance +func (c *Route53) GetTrafficPolicyInstance(input *GetTrafficPolicyInstanceInput) (*GetTrafficPolicyInstanceOutput, error) { + req, out := c.GetTrafficPolicyInstanceRequest(input) + return out, req.Send() +} + +// GetTrafficPolicyInstanceWithContext is the same as GetTrafficPolicyInstance with the addition of +// the ability to pass a context and additional request options. +// +// See GetTrafficPolicyInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetTrafficPolicyInstanceWithContext(ctx aws.Context, input *GetTrafficPolicyInstanceInput, opts ...request.Option) (*GetTrafficPolicyInstanceOutput, error) { + req, out := c.GetTrafficPolicyInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetTrafficPolicyInstanceCount = "GetTrafficPolicyInstanceCount" + +// GetTrafficPolicyInstanceCountRequest generates a "aws/request.Request" representing the +// client's request for the GetTrafficPolicyInstanceCount operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetTrafficPolicyInstanceCount for more information on using the GetTrafficPolicyInstanceCount +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetTrafficPolicyInstanceCountRequest method. +// req, resp := client.GetTrafficPolicyInstanceCountRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetTrafficPolicyInstanceCount +func (c *Route53) GetTrafficPolicyInstanceCountRequest(input *GetTrafficPolicyInstanceCountInput) (req *request.Request, output *GetTrafficPolicyInstanceCountOutput) { + op := &request.Operation{ + Name: opGetTrafficPolicyInstanceCount, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/trafficpolicyinstancecount", + } + + if input == nil { + input = &GetTrafficPolicyInstanceCountInput{} + } + + output = &GetTrafficPolicyInstanceCountOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetTrafficPolicyInstanceCount API operation for Amazon Route 53. +// +// Gets the number of traffic policy instances that are associated with the +// current AWS account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation GetTrafficPolicyInstanceCount for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/GetTrafficPolicyInstanceCount +func (c *Route53) GetTrafficPolicyInstanceCount(input *GetTrafficPolicyInstanceCountInput) (*GetTrafficPolicyInstanceCountOutput, error) { + req, out := c.GetTrafficPolicyInstanceCountRequest(input) + return out, req.Send() +} + +// GetTrafficPolicyInstanceCountWithContext is the same as GetTrafficPolicyInstanceCount with the addition of +// the ability to pass a context and additional request options. +// +// See GetTrafficPolicyInstanceCount for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) GetTrafficPolicyInstanceCountWithContext(ctx aws.Context, input *GetTrafficPolicyInstanceCountInput, opts ...request.Option) (*GetTrafficPolicyInstanceCountOutput, error) { + req, out := c.GetTrafficPolicyInstanceCountRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListGeoLocations = "ListGeoLocations" + +// ListGeoLocationsRequest generates a "aws/request.Request" representing the +// client's request for the ListGeoLocations operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListGeoLocations for more information on using the ListGeoLocations +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListGeoLocationsRequest method. +// req, resp := client.ListGeoLocationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListGeoLocations +func (c *Route53) ListGeoLocationsRequest(input *ListGeoLocationsInput) (req *request.Request, output *ListGeoLocationsOutput) { + op := &request.Operation{ + Name: opListGeoLocations, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/geolocations", + } + + if input == nil { + input = &ListGeoLocationsInput{} + } + + output = &ListGeoLocationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListGeoLocations API operation for Amazon Route 53. +// +// Retrieves a list of supported geographic locations. +// +// Countries are listed first, and continents are listed last. If Amazon Route +// 53 supports subdivisions for a country (for example, states or provinces), +// the subdivisions for that country are listed in alphabetical order immediately +// after the corresponding country. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListGeoLocations for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListGeoLocations +func (c *Route53) ListGeoLocations(input *ListGeoLocationsInput) (*ListGeoLocationsOutput, error) { + req, out := c.ListGeoLocationsRequest(input) + return out, req.Send() +} + +// ListGeoLocationsWithContext is the same as ListGeoLocations with the addition of +// the ability to pass a context and additional request options. +// +// See ListGeoLocations for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListGeoLocationsWithContext(ctx aws.Context, input *ListGeoLocationsInput, opts ...request.Option) (*ListGeoLocationsOutput, error) { + req, out := c.ListGeoLocationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListHealthChecks = "ListHealthChecks" + +// ListHealthChecksRequest generates a "aws/request.Request" representing the +// client's request for the ListHealthChecks operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListHealthChecks for more information on using the ListHealthChecks +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListHealthChecksRequest method. +// req, resp := client.ListHealthChecksRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHealthChecks +func (c *Route53) ListHealthChecksRequest(input *ListHealthChecksInput) (req *request.Request, output *ListHealthChecksOutput) { + op := &request.Operation{ + Name: opListHealthChecks, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/healthcheck", + Paginator: &request.Paginator{ + InputTokens: []string{"Marker"}, + OutputTokens: []string{"NextMarker"}, + LimitToken: "MaxItems", + TruncationToken: "IsTruncated", + }, + } + + if input == nil { + input = &ListHealthChecksInput{} + } + + output = &ListHealthChecksOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListHealthChecks API operation for Amazon Route 53. +// +// Retrieve a list of the health checks that are associated with the current +// AWS account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListHealthChecks for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeIncompatibleVersion "IncompatibleVersion" +// The resource you're trying to access is unsupported on this Amazon Route +// 53 endpoint. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHealthChecks +func (c *Route53) ListHealthChecks(input *ListHealthChecksInput) (*ListHealthChecksOutput, error) { + req, out := c.ListHealthChecksRequest(input) + return out, req.Send() +} + +// ListHealthChecksWithContext is the same as ListHealthChecks with the addition of +// the ability to pass a context and additional request options. +// +// See ListHealthChecks for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListHealthChecksWithContext(ctx aws.Context, input *ListHealthChecksInput, opts ...request.Option) (*ListHealthChecksOutput, error) { + req, out := c.ListHealthChecksRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// ListHealthChecksPages iterates over the pages of a ListHealthChecks operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListHealthChecks method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListHealthChecks operation. +// pageNum := 0 +// err := client.ListHealthChecksPages(params, +// func(page *route53.ListHealthChecksOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *Route53) ListHealthChecksPages(input *ListHealthChecksInput, fn func(*ListHealthChecksOutput, bool) bool) error { + return c.ListHealthChecksPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListHealthChecksPagesWithContext same as ListHealthChecksPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListHealthChecksPagesWithContext(ctx aws.Context, input *ListHealthChecksInput, fn func(*ListHealthChecksOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListHealthChecksInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListHealthChecksRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*ListHealthChecksOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opListHostedZones = "ListHostedZones" + +// ListHostedZonesRequest generates a "aws/request.Request" representing the +// client's request for the ListHostedZones operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListHostedZones for more information on using the ListHostedZones +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListHostedZonesRequest method. +// req, resp := client.ListHostedZonesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHostedZones +func (c *Route53) ListHostedZonesRequest(input *ListHostedZonesInput) (req *request.Request, output *ListHostedZonesOutput) { + op := &request.Operation{ + Name: opListHostedZones, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/hostedzone", + Paginator: &request.Paginator{ + InputTokens: []string{"Marker"}, + OutputTokens: []string{"NextMarker"}, + LimitToken: "MaxItems", + TruncationToken: "IsTruncated", + }, + } + + if input == nil { + input = &ListHostedZonesInput{} + } + + output = &ListHostedZonesOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListHostedZones API operation for Amazon Route 53. +// +// Retrieves a list of the public and private hosted zones that are associated +// with the current AWS account. The response includes a HostedZones child element +// for each hosted zone. +// +// Amazon Route 53 returns a maximum of 100 items in each response. If you have +// a lot of hosted zones, you can use the maxitems parameter to list them in +// groups of up to 100. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListHostedZones for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchDelegationSet "NoSuchDelegationSet" +// A reusable delegation set with the specified ID does not exist. +// +// * ErrCodeDelegationSetNotReusable "DelegationSetNotReusable" +// A reusable delegation set with the specified ID does not exist. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHostedZones +func (c *Route53) ListHostedZones(input *ListHostedZonesInput) (*ListHostedZonesOutput, error) { + req, out := c.ListHostedZonesRequest(input) + return out, req.Send() +} + +// ListHostedZonesWithContext is the same as ListHostedZones with the addition of +// the ability to pass a context and additional request options. +// +// See ListHostedZones for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListHostedZonesWithContext(ctx aws.Context, input *ListHostedZonesInput, opts ...request.Option) (*ListHostedZonesOutput, error) { + req, out := c.ListHostedZonesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// ListHostedZonesPages iterates over the pages of a ListHostedZones operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListHostedZones method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListHostedZones operation. +// pageNum := 0 +// err := client.ListHostedZonesPages(params, +// func(page *route53.ListHostedZonesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *Route53) ListHostedZonesPages(input *ListHostedZonesInput, fn func(*ListHostedZonesOutput, bool) bool) error { + return c.ListHostedZonesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListHostedZonesPagesWithContext same as ListHostedZonesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListHostedZonesPagesWithContext(ctx aws.Context, input *ListHostedZonesInput, fn func(*ListHostedZonesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListHostedZonesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListHostedZonesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*ListHostedZonesOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opListHostedZonesByName = "ListHostedZonesByName" + +// ListHostedZonesByNameRequest generates a "aws/request.Request" representing the +// client's request for the ListHostedZonesByName operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListHostedZonesByName for more information on using the ListHostedZonesByName +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListHostedZonesByNameRequest method. +// req, resp := client.ListHostedZonesByNameRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHostedZonesByName +func (c *Route53) ListHostedZonesByNameRequest(input *ListHostedZonesByNameInput) (req *request.Request, output *ListHostedZonesByNameOutput) { + op := &request.Operation{ + Name: opListHostedZonesByName, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/hostedzonesbyname", + } + + if input == nil { + input = &ListHostedZonesByNameInput{} + } + + output = &ListHostedZonesByNameOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListHostedZonesByName API operation for Amazon Route 53. +// +// Retrieves a list of your hosted zones in lexicographic order. The response +// includes a HostedZones child element for each hosted zone created by the +// current AWS account. +// +// ListHostedZonesByName sorts hosted zones by name with the labels reversed. +// For example: +// +// com.example.www. +// +// Note the trailing dot, which can change the sort order in some circumstances. +// +// If the domain name includes escape characters or Punycode, ListHostedZonesByName +// alphabetizes the domain name using the escaped or Punycoded value, which +// is the format that Amazon Route 53 saves in its database. For example, to +// create a hosted zone for exämple.com, you specify ex\344mple.com for the +// domain name. ListHostedZonesByName alphabetizes it as: +// +// com.ex\344mple. +// +// The labels are reversed and alphabetized using the escaped value. For more +// information about valid domain name formats, including internationalized +// domain names, see DNS Domain Name Format (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DomainNameFormat.html) +// in the Amazon Route 53 Developer Guide. +// +// Route 53 returns up to 100 items in each response. If you have a lot of hosted +// zones, use the MaxItems parameter to list them in groups of up to 100. The +// response includes values that help navigate from one group of MaxItems hosted +// zones to the next: +// +// * The DNSName and HostedZoneId elements in the response contain the values, +// if any, specified for the dnsname and hostedzoneid parameters in the request +// that produced the current response. +// +// * The MaxItems element in the response contains the value, if any, that +// you specified for the maxitems parameter in the request that produced +// the current response. +// +// * If the value of IsTruncated in the response is true, there are more +// hosted zones associated with the current AWS account. If IsTruncated is +// false, this response includes the last hosted zone that is associated +// with the current account. The NextDNSName element and NextHostedZoneId +// elements are omitted from the response. +// +// * The NextDNSName and NextHostedZoneId elements in the response contain +// the domain name and the hosted zone ID of the next hosted zone that is +// associated with the current AWS account. If you want to list more hosted +// zones, make another call to ListHostedZonesByName, and specify the value +// of NextDNSName and NextHostedZoneId in the dnsname and hostedzoneid parameters, +// respectively. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListHostedZonesByName for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeInvalidDomainName "InvalidDomainName" +// The specified domain name is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListHostedZonesByName +func (c *Route53) ListHostedZonesByName(input *ListHostedZonesByNameInput) (*ListHostedZonesByNameOutput, error) { + req, out := c.ListHostedZonesByNameRequest(input) + return out, req.Send() +} + +// ListHostedZonesByNameWithContext is the same as ListHostedZonesByName with the addition of +// the ability to pass a context and additional request options. +// +// See ListHostedZonesByName for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListHostedZonesByNameWithContext(ctx aws.Context, input *ListHostedZonesByNameInput, opts ...request.Option) (*ListHostedZonesByNameOutput, error) { + req, out := c.ListHostedZonesByNameRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListQueryLoggingConfigs = "ListQueryLoggingConfigs" + +// ListQueryLoggingConfigsRequest generates a "aws/request.Request" representing the +// client's request for the ListQueryLoggingConfigs operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListQueryLoggingConfigs for more information on using the ListQueryLoggingConfigs +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListQueryLoggingConfigsRequest method. +// req, resp := client.ListQueryLoggingConfigsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListQueryLoggingConfigs +func (c *Route53) ListQueryLoggingConfigsRequest(input *ListQueryLoggingConfigsInput) (req *request.Request, output *ListQueryLoggingConfigsOutput) { + op := &request.Operation{ + Name: opListQueryLoggingConfigs, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/queryloggingconfig", + } + + if input == nil { + input = &ListQueryLoggingConfigsInput{} + } + + output = &ListQueryLoggingConfigsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListQueryLoggingConfigs API operation for Amazon Route 53. +// +// Lists the configurations for DNS query logging that are associated with the +// current AWS account or the configuration that is associated with a specified +// hosted zone. +// +// For more information about DNS query logs, see CreateQueryLoggingConfig (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateQueryLoggingConfig.html). +// Additional information, including the format of DNS query logs, appears in +// Logging DNS Queries (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/query-logs.html) +// in the Amazon Route 53 Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListQueryLoggingConfigs for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeInvalidPaginationToken "InvalidPaginationToken" +// The value that you specified to get the second or subsequent page of results +// is invalid. +// +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListQueryLoggingConfigs +func (c *Route53) ListQueryLoggingConfigs(input *ListQueryLoggingConfigsInput) (*ListQueryLoggingConfigsOutput, error) { + req, out := c.ListQueryLoggingConfigsRequest(input) + return out, req.Send() +} + +// ListQueryLoggingConfigsWithContext is the same as ListQueryLoggingConfigs with the addition of +// the ability to pass a context and additional request options. +// +// See ListQueryLoggingConfigs for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListQueryLoggingConfigsWithContext(ctx aws.Context, input *ListQueryLoggingConfigsInput, opts ...request.Option) (*ListQueryLoggingConfigsOutput, error) { + req, out := c.ListQueryLoggingConfigsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListResourceRecordSets = "ListResourceRecordSets" + +// ListResourceRecordSetsRequest generates a "aws/request.Request" representing the +// client's request for the ListResourceRecordSets operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListResourceRecordSets for more information on using the ListResourceRecordSets +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListResourceRecordSetsRequest method. +// req, resp := client.ListResourceRecordSetsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListResourceRecordSets +func (c *Route53) ListResourceRecordSetsRequest(input *ListResourceRecordSetsInput) (req *request.Request, output *ListResourceRecordSetsOutput) { + op := &request.Operation{ + Name: opListResourceRecordSets, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/hostedzone/{Id}/rrset", + Paginator: &request.Paginator{ + InputTokens: []string{"StartRecordName", "StartRecordType", "StartRecordIdentifier"}, + OutputTokens: []string{"NextRecordName", "NextRecordType", "NextRecordIdentifier"}, + LimitToken: "MaxItems", + TruncationToken: "IsTruncated", + }, + } + + if input == nil { + input = &ListResourceRecordSetsInput{} + } + + output = &ListResourceRecordSetsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListResourceRecordSets API operation for Amazon Route 53. +// +// Lists the resource record sets in a specified hosted zone. +// +// ListResourceRecordSets returns up to 100 resource record sets at a time in +// ASCII order, beginning at a position specified by the name and type elements. +// +// Sort order +// +// ListResourceRecordSets sorts results first by DNS name with the labels reversed, +// for example: +// +// com.example.www. +// +// Note the trailing dot, which can change the sort order when the record name +// contains characters that appear before . (decimal 46) in the ASCII table. +// These characters include the following: ! " # $ % & ' ( ) * + , - +// +// When multiple records have the same DNS name, ListResourceRecordSets sorts +// results by the record type. +// +// Specifying where to start listing records +// +// You can use the name and type elements to specify the resource record set +// that the list begins with: +// +// If you do not specify Name or Type +// +// The results begin with the first resource record set that the hosted zone +// contains. +// +// If you specify Name but not Type +// +// The results begin with the first resource record set in the list whose name +// is greater than or equal to Name. +// +// If you specify Type but not Name +// +// Amazon Route 53 returns the InvalidInput error. +// +// If you specify both Name and Type +// +// The results begin with the first resource record set in the list whose name +// is greater than or equal to Name, and whose type is greater than or equal +// to Type. +// +// Resource record sets that are PENDING +// +// This action returns the most current version of the records. This includes +// records that are PENDING, and that are not yet available on all Route 53 +// DNS servers. +// +// Changing resource record sets +// +// To ensure that you get an accurate listing of the resource record sets for +// a hosted zone at a point in time, do not submit a ChangeResourceRecordSets +// request while you're paging through the results of a ListResourceRecordSets +// request. If you do, some pages may display results without the latest changes +// while other pages display results with the latest changes. +// +// Displaying the next page of results +// +// If a ListResourceRecordSets command returns more than one page of results, +// the value of IsTruncated is true. To display the next page of results, get +// the values of NextRecordName, NextRecordType, and NextRecordIdentifier (if +// any) from the response. Then submit another ListResourceRecordSets request, +// and specify those values for StartRecordName, StartRecordType, and StartRecordIdentifier. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListResourceRecordSets for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListResourceRecordSets +func (c *Route53) ListResourceRecordSets(input *ListResourceRecordSetsInput) (*ListResourceRecordSetsOutput, error) { + req, out := c.ListResourceRecordSetsRequest(input) + return out, req.Send() +} + +// ListResourceRecordSetsWithContext is the same as ListResourceRecordSets with the addition of +// the ability to pass a context and additional request options. +// +// See ListResourceRecordSets for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListResourceRecordSetsWithContext(ctx aws.Context, input *ListResourceRecordSetsInput, opts ...request.Option) (*ListResourceRecordSetsOutput, error) { + req, out := c.ListResourceRecordSetsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// ListResourceRecordSetsPages iterates over the pages of a ListResourceRecordSets operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See ListResourceRecordSets method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a ListResourceRecordSets operation. +// pageNum := 0 +// err := client.ListResourceRecordSetsPages(params, +// func(page *route53.ListResourceRecordSetsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *Route53) ListResourceRecordSetsPages(input *ListResourceRecordSetsInput, fn func(*ListResourceRecordSetsOutput, bool) bool) error { + return c.ListResourceRecordSetsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// ListResourceRecordSetsPagesWithContext same as ListResourceRecordSetsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListResourceRecordSetsPagesWithContext(ctx aws.Context, input *ListResourceRecordSetsInput, fn func(*ListResourceRecordSetsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *ListResourceRecordSetsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.ListResourceRecordSetsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*ListResourceRecordSetsOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opListReusableDelegationSets = "ListReusableDelegationSets" + +// ListReusableDelegationSetsRequest generates a "aws/request.Request" representing the +// client's request for the ListReusableDelegationSets operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListReusableDelegationSets for more information on using the ListReusableDelegationSets +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListReusableDelegationSetsRequest method. +// req, resp := client.ListReusableDelegationSetsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListReusableDelegationSets +func (c *Route53) ListReusableDelegationSetsRequest(input *ListReusableDelegationSetsInput) (req *request.Request, output *ListReusableDelegationSetsOutput) { + op := &request.Operation{ + Name: opListReusableDelegationSets, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/delegationset", + } + + if input == nil { + input = &ListReusableDelegationSetsInput{} + } + + output = &ListReusableDelegationSetsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListReusableDelegationSets API operation for Amazon Route 53. +// +// Retrieves a list of the reusable delegation sets that are associated with +// the current AWS account. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListReusableDelegationSets for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListReusableDelegationSets +func (c *Route53) ListReusableDelegationSets(input *ListReusableDelegationSetsInput) (*ListReusableDelegationSetsOutput, error) { + req, out := c.ListReusableDelegationSetsRequest(input) + return out, req.Send() +} + +// ListReusableDelegationSetsWithContext is the same as ListReusableDelegationSets with the addition of +// the ability to pass a context and additional request options. +// +// See ListReusableDelegationSets for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListReusableDelegationSetsWithContext(ctx aws.Context, input *ListReusableDelegationSetsInput, opts ...request.Option) (*ListReusableDelegationSetsOutput, error) { + req, out := c.ListReusableDelegationSetsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListTagsForResource = "ListTagsForResource" + +// ListTagsForResourceRequest generates a "aws/request.Request" representing the +// client's request for the ListTagsForResource operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTagsForResource for more information on using the ListTagsForResource +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTagsForResourceRequest method. +// req, resp := client.ListTagsForResourceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTagsForResource +func (c *Route53) ListTagsForResourceRequest(input *ListTagsForResourceInput) (req *request.Request, output *ListTagsForResourceOutput) { + op := &request.Operation{ + Name: opListTagsForResource, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/tags/{ResourceType}/{ResourceId}", + } + + if input == nil { + input = &ListTagsForResourceInput{} + } + + output = &ListTagsForResourceOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTagsForResource API operation for Amazon Route 53. +// +// Lists tags for one health check or hosted zone. +// +// For information about using tags for cost allocation, see Using Cost Allocation +// Tags (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html) +// in the AWS Billing and Cost Management User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListTagsForResource for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodePriorRequestNotComplete "PriorRequestNotComplete" +// If Amazon Route 53 can't process a request before the next request arrives, +// it will reject subsequent requests for the same hosted zone and return an +// HTTP 400 error (Bad request). If Route 53 returns this error repeatedly for +// the same request, we recommend that you wait, in intervals of increasing +// duration, before you try the request again. +// +// * ErrCodeThrottlingException "ThrottlingException" +// The limit on the number of requests per second was exceeded. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTagsForResource +func (c *Route53) ListTagsForResource(input *ListTagsForResourceInput) (*ListTagsForResourceOutput, error) { + req, out := c.ListTagsForResourceRequest(input) + return out, req.Send() +} + +// ListTagsForResourceWithContext is the same as ListTagsForResource with the addition of +// the ability to pass a context and additional request options. +// +// See ListTagsForResource for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListTagsForResourceWithContext(ctx aws.Context, input *ListTagsForResourceInput, opts ...request.Option) (*ListTagsForResourceOutput, error) { + req, out := c.ListTagsForResourceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListTagsForResources = "ListTagsForResources" + +// ListTagsForResourcesRequest generates a "aws/request.Request" representing the +// client's request for the ListTagsForResources operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTagsForResources for more information on using the ListTagsForResources +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTagsForResourcesRequest method. +// req, resp := client.ListTagsForResourcesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTagsForResources +func (c *Route53) ListTagsForResourcesRequest(input *ListTagsForResourcesInput) (req *request.Request, output *ListTagsForResourcesOutput) { + op := &request.Operation{ + Name: opListTagsForResources, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/tags/{ResourceType}", + } + + if input == nil { + input = &ListTagsForResourcesInput{} + } + + output = &ListTagsForResourcesOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTagsForResources API operation for Amazon Route 53. +// +// Lists tags for up to 10 health checks or hosted zones. +// +// For information about using tags for cost allocation, see Using Cost Allocation +// Tags (https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html) +// in the AWS Billing and Cost Management User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListTagsForResources for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodePriorRequestNotComplete "PriorRequestNotComplete" +// If Amazon Route 53 can't process a request before the next request arrives, +// it will reject subsequent requests for the same hosted zone and return an +// HTTP 400 error (Bad request). If Route 53 returns this error repeatedly for +// the same request, we recommend that you wait, in intervals of increasing +// duration, before you try the request again. +// +// * ErrCodeThrottlingException "ThrottlingException" +// The limit on the number of requests per second was exceeded. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTagsForResources +func (c *Route53) ListTagsForResources(input *ListTagsForResourcesInput) (*ListTagsForResourcesOutput, error) { + req, out := c.ListTagsForResourcesRequest(input) + return out, req.Send() +} + +// ListTagsForResourcesWithContext is the same as ListTagsForResources with the addition of +// the ability to pass a context and additional request options. +// +// See ListTagsForResources for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListTagsForResourcesWithContext(ctx aws.Context, input *ListTagsForResourcesInput, opts ...request.Option) (*ListTagsForResourcesOutput, error) { + req, out := c.ListTagsForResourcesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListTrafficPolicies = "ListTrafficPolicies" + +// ListTrafficPoliciesRequest generates a "aws/request.Request" representing the +// client's request for the ListTrafficPolicies operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTrafficPolicies for more information on using the ListTrafficPolicies +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTrafficPoliciesRequest method. +// req, resp := client.ListTrafficPoliciesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicies +func (c *Route53) ListTrafficPoliciesRequest(input *ListTrafficPoliciesInput) (req *request.Request, output *ListTrafficPoliciesOutput) { + op := &request.Operation{ + Name: opListTrafficPolicies, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/trafficpolicies", + } + + if input == nil { + input = &ListTrafficPoliciesInput{} + } + + output = &ListTrafficPoliciesOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTrafficPolicies API operation for Amazon Route 53. +// +// Gets information about the latest version for every traffic policy that is +// associated with the current AWS account. Policies are listed in the order +// that they were created in. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListTrafficPolicies for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicies +func (c *Route53) ListTrafficPolicies(input *ListTrafficPoliciesInput) (*ListTrafficPoliciesOutput, error) { + req, out := c.ListTrafficPoliciesRequest(input) + return out, req.Send() +} + +// ListTrafficPoliciesWithContext is the same as ListTrafficPolicies with the addition of +// the ability to pass a context and additional request options. +// +// See ListTrafficPolicies for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListTrafficPoliciesWithContext(ctx aws.Context, input *ListTrafficPoliciesInput, opts ...request.Option) (*ListTrafficPoliciesOutput, error) { + req, out := c.ListTrafficPoliciesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListTrafficPolicyInstances = "ListTrafficPolicyInstances" + +// ListTrafficPolicyInstancesRequest generates a "aws/request.Request" representing the +// client's request for the ListTrafficPolicyInstances operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTrafficPolicyInstances for more information on using the ListTrafficPolicyInstances +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTrafficPolicyInstancesRequest method. +// req, resp := client.ListTrafficPolicyInstancesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicyInstances +func (c *Route53) ListTrafficPolicyInstancesRequest(input *ListTrafficPolicyInstancesInput) (req *request.Request, output *ListTrafficPolicyInstancesOutput) { + op := &request.Operation{ + Name: opListTrafficPolicyInstances, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/trafficpolicyinstances", + } + + if input == nil { + input = &ListTrafficPolicyInstancesInput{} + } + + output = &ListTrafficPolicyInstancesOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTrafficPolicyInstances API operation for Amazon Route 53. +// +// Gets information about the traffic policy instances that you created by using +// the current AWS account. +// +// After you submit an UpdateTrafficPolicyInstance request, there's a brief +// delay while Amazon Route 53 creates the resource record sets that are specified +// in the traffic policy definition. For more information, see the State response +// element. +// +// Route 53 returns a maximum of 100 items in each response. If you have a lot +// of traffic policy instances, you can use the MaxItems parameter to list them +// in groups of up to 100. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListTrafficPolicyInstances for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchTrafficPolicyInstance "NoSuchTrafficPolicyInstance" +// No traffic policy instance exists with the specified ID. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicyInstances +func (c *Route53) ListTrafficPolicyInstances(input *ListTrafficPolicyInstancesInput) (*ListTrafficPolicyInstancesOutput, error) { + req, out := c.ListTrafficPolicyInstancesRequest(input) + return out, req.Send() +} + +// ListTrafficPolicyInstancesWithContext is the same as ListTrafficPolicyInstances with the addition of +// the ability to pass a context and additional request options. +// +// See ListTrafficPolicyInstances for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListTrafficPolicyInstancesWithContext(ctx aws.Context, input *ListTrafficPolicyInstancesInput, opts ...request.Option) (*ListTrafficPolicyInstancesOutput, error) { + req, out := c.ListTrafficPolicyInstancesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListTrafficPolicyInstancesByHostedZone = "ListTrafficPolicyInstancesByHostedZone" + +// ListTrafficPolicyInstancesByHostedZoneRequest generates a "aws/request.Request" representing the +// client's request for the ListTrafficPolicyInstancesByHostedZone operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTrafficPolicyInstancesByHostedZone for more information on using the ListTrafficPolicyInstancesByHostedZone +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTrafficPolicyInstancesByHostedZoneRequest method. +// req, resp := client.ListTrafficPolicyInstancesByHostedZoneRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicyInstancesByHostedZone +func (c *Route53) ListTrafficPolicyInstancesByHostedZoneRequest(input *ListTrafficPolicyInstancesByHostedZoneInput) (req *request.Request, output *ListTrafficPolicyInstancesByHostedZoneOutput) { + op := &request.Operation{ + Name: opListTrafficPolicyInstancesByHostedZone, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/trafficpolicyinstances/hostedzone", + } + + if input == nil { + input = &ListTrafficPolicyInstancesByHostedZoneInput{} + } + + output = &ListTrafficPolicyInstancesByHostedZoneOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTrafficPolicyInstancesByHostedZone API operation for Amazon Route 53. +// +// Gets information about the traffic policy instances that you created in a +// specified hosted zone. +// +// After you submit a CreateTrafficPolicyInstance or an UpdateTrafficPolicyInstance +// request, there's a brief delay while Amazon Route 53 creates the resource +// record sets that are specified in the traffic policy definition. For more +// information, see the State response element. +// +// Route 53 returns a maximum of 100 items in each response. If you have a lot +// of traffic policy instances, you can use the MaxItems parameter to list them +// in groups of up to 100. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListTrafficPolicyInstancesByHostedZone for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchTrafficPolicyInstance "NoSuchTrafficPolicyInstance" +// No traffic policy instance exists with the specified ID. +// +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicyInstancesByHostedZone +func (c *Route53) ListTrafficPolicyInstancesByHostedZone(input *ListTrafficPolicyInstancesByHostedZoneInput) (*ListTrafficPolicyInstancesByHostedZoneOutput, error) { + req, out := c.ListTrafficPolicyInstancesByHostedZoneRequest(input) + return out, req.Send() +} + +// ListTrafficPolicyInstancesByHostedZoneWithContext is the same as ListTrafficPolicyInstancesByHostedZone with the addition of +// the ability to pass a context and additional request options. +// +// See ListTrafficPolicyInstancesByHostedZone for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListTrafficPolicyInstancesByHostedZoneWithContext(ctx aws.Context, input *ListTrafficPolicyInstancesByHostedZoneInput, opts ...request.Option) (*ListTrafficPolicyInstancesByHostedZoneOutput, error) { + req, out := c.ListTrafficPolicyInstancesByHostedZoneRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListTrafficPolicyInstancesByPolicy = "ListTrafficPolicyInstancesByPolicy" + +// ListTrafficPolicyInstancesByPolicyRequest generates a "aws/request.Request" representing the +// client's request for the ListTrafficPolicyInstancesByPolicy operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTrafficPolicyInstancesByPolicy for more information on using the ListTrafficPolicyInstancesByPolicy +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTrafficPolicyInstancesByPolicyRequest method. +// req, resp := client.ListTrafficPolicyInstancesByPolicyRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicyInstancesByPolicy +func (c *Route53) ListTrafficPolicyInstancesByPolicyRequest(input *ListTrafficPolicyInstancesByPolicyInput) (req *request.Request, output *ListTrafficPolicyInstancesByPolicyOutput) { + op := &request.Operation{ + Name: opListTrafficPolicyInstancesByPolicy, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/trafficpolicyinstances/trafficpolicy", + } + + if input == nil { + input = &ListTrafficPolicyInstancesByPolicyInput{} + } + + output = &ListTrafficPolicyInstancesByPolicyOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTrafficPolicyInstancesByPolicy API operation for Amazon Route 53. +// +// Gets information about the traffic policy instances that you created by using +// a specify traffic policy version. +// +// After you submit a CreateTrafficPolicyInstance or an UpdateTrafficPolicyInstance +// request, there's a brief delay while Amazon Route 53 creates the resource +// record sets that are specified in the traffic policy definition. For more +// information, see the State response element. +// +// Route 53 returns a maximum of 100 items in each response. If you have a lot +// of traffic policy instances, you can use the MaxItems parameter to list them +// in groups of up to 100. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListTrafficPolicyInstancesByPolicy for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchTrafficPolicyInstance "NoSuchTrafficPolicyInstance" +// No traffic policy instance exists with the specified ID. +// +// * ErrCodeNoSuchTrafficPolicy "NoSuchTrafficPolicy" +// No traffic policy exists with the specified ID. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicyInstancesByPolicy +func (c *Route53) ListTrafficPolicyInstancesByPolicy(input *ListTrafficPolicyInstancesByPolicyInput) (*ListTrafficPolicyInstancesByPolicyOutput, error) { + req, out := c.ListTrafficPolicyInstancesByPolicyRequest(input) + return out, req.Send() +} + +// ListTrafficPolicyInstancesByPolicyWithContext is the same as ListTrafficPolicyInstancesByPolicy with the addition of +// the ability to pass a context and additional request options. +// +// See ListTrafficPolicyInstancesByPolicy for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListTrafficPolicyInstancesByPolicyWithContext(ctx aws.Context, input *ListTrafficPolicyInstancesByPolicyInput, opts ...request.Option) (*ListTrafficPolicyInstancesByPolicyOutput, error) { + req, out := c.ListTrafficPolicyInstancesByPolicyRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListTrafficPolicyVersions = "ListTrafficPolicyVersions" + +// ListTrafficPolicyVersionsRequest generates a "aws/request.Request" representing the +// client's request for the ListTrafficPolicyVersions operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListTrafficPolicyVersions for more information on using the ListTrafficPolicyVersions +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListTrafficPolicyVersionsRequest method. +// req, resp := client.ListTrafficPolicyVersionsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicyVersions +func (c *Route53) ListTrafficPolicyVersionsRequest(input *ListTrafficPolicyVersionsInput) (req *request.Request, output *ListTrafficPolicyVersionsOutput) { + op := &request.Operation{ + Name: opListTrafficPolicyVersions, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/trafficpolicies/{Id}/versions", + } + + if input == nil { + input = &ListTrafficPolicyVersionsInput{} + } + + output = &ListTrafficPolicyVersionsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListTrafficPolicyVersions API operation for Amazon Route 53. +// +// Gets information about all of the versions for a specified traffic policy. +// +// Traffic policy versions are listed in numerical order by VersionNumber. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListTrafficPolicyVersions for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchTrafficPolicy "NoSuchTrafficPolicy" +// No traffic policy exists with the specified ID. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListTrafficPolicyVersions +func (c *Route53) ListTrafficPolicyVersions(input *ListTrafficPolicyVersionsInput) (*ListTrafficPolicyVersionsOutput, error) { + req, out := c.ListTrafficPolicyVersionsRequest(input) + return out, req.Send() +} + +// ListTrafficPolicyVersionsWithContext is the same as ListTrafficPolicyVersions with the addition of +// the ability to pass a context and additional request options. +// +// See ListTrafficPolicyVersions for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListTrafficPolicyVersionsWithContext(ctx aws.Context, input *ListTrafficPolicyVersionsInput, opts ...request.Option) (*ListTrafficPolicyVersionsOutput, error) { + req, out := c.ListTrafficPolicyVersionsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opListVPCAssociationAuthorizations = "ListVPCAssociationAuthorizations" + +// ListVPCAssociationAuthorizationsRequest generates a "aws/request.Request" representing the +// client's request for the ListVPCAssociationAuthorizations operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See ListVPCAssociationAuthorizations for more information on using the ListVPCAssociationAuthorizations +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the ListVPCAssociationAuthorizationsRequest method. +// req, resp := client.ListVPCAssociationAuthorizationsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListVPCAssociationAuthorizations +func (c *Route53) ListVPCAssociationAuthorizationsRequest(input *ListVPCAssociationAuthorizationsInput) (req *request.Request, output *ListVPCAssociationAuthorizationsOutput) { + op := &request.Operation{ + Name: opListVPCAssociationAuthorizations, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/hostedzone/{Id}/authorizevpcassociation", + } + + if input == nil { + input = &ListVPCAssociationAuthorizationsInput{} + } + + output = &ListVPCAssociationAuthorizationsOutput{} + req = c.newRequest(op, input, output) + return +} + +// ListVPCAssociationAuthorizations API operation for Amazon Route 53. +// +// Gets a list of the VPCs that were created by other accounts and that can +// be associated with a specified hosted zone because you've submitted one or +// more CreateVPCAssociationAuthorization requests. +// +// The response includes a VPCs element with a VPC child element for each VPC +// that can be associated with the hosted zone. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation ListVPCAssociationAuthorizations for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeInvalidPaginationToken "InvalidPaginationToken" +// The value that you specified to get the second or subsequent page of results +// is invalid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/ListVPCAssociationAuthorizations +func (c *Route53) ListVPCAssociationAuthorizations(input *ListVPCAssociationAuthorizationsInput) (*ListVPCAssociationAuthorizationsOutput, error) { + req, out := c.ListVPCAssociationAuthorizationsRequest(input) + return out, req.Send() +} + +// ListVPCAssociationAuthorizationsWithContext is the same as ListVPCAssociationAuthorizations with the addition of +// the ability to pass a context and additional request options. +// +// See ListVPCAssociationAuthorizations for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) ListVPCAssociationAuthorizationsWithContext(ctx aws.Context, input *ListVPCAssociationAuthorizationsInput, opts ...request.Option) (*ListVPCAssociationAuthorizationsOutput, error) { + req, out := c.ListVPCAssociationAuthorizationsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opTestDNSAnswer = "TestDNSAnswer" + +// TestDNSAnswerRequest generates a "aws/request.Request" representing the +// client's request for the TestDNSAnswer operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See TestDNSAnswer for more information on using the TestDNSAnswer +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the TestDNSAnswerRequest method. +// req, resp := client.TestDNSAnswerRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/TestDNSAnswer +func (c *Route53) TestDNSAnswerRequest(input *TestDNSAnswerInput) (req *request.Request, output *TestDNSAnswerOutput) { + op := &request.Operation{ + Name: opTestDNSAnswer, + HTTPMethod: "GET", + HTTPPath: "/2013-04-01/testdnsanswer", + } + + if input == nil { + input = &TestDNSAnswerInput{} + } + + output = &TestDNSAnswerOutput{} + req = c.newRequest(op, input, output) + return +} + +// TestDNSAnswer API operation for Amazon Route 53. +// +// Gets the value that Amazon Route 53 returns in response to a DNS request +// for a specified record name and type. You can optionally specify the IP address +// of a DNS resolver, an EDNS0 client subnet IP address, and a subnet mask. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation TestDNSAnswer for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/TestDNSAnswer +func (c *Route53) TestDNSAnswer(input *TestDNSAnswerInput) (*TestDNSAnswerOutput, error) { + req, out := c.TestDNSAnswerRequest(input) + return out, req.Send() +} + +// TestDNSAnswerWithContext is the same as TestDNSAnswer with the addition of +// the ability to pass a context and additional request options. +// +// See TestDNSAnswer for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) TestDNSAnswerWithContext(ctx aws.Context, input *TestDNSAnswerInput, opts ...request.Option) (*TestDNSAnswerOutput, error) { + req, out := c.TestDNSAnswerRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateHealthCheck = "UpdateHealthCheck" + +// UpdateHealthCheckRequest generates a "aws/request.Request" representing the +// client's request for the UpdateHealthCheck operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateHealthCheck for more information on using the UpdateHealthCheck +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateHealthCheckRequest method. +// req, resp := client.UpdateHealthCheckRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateHealthCheck +func (c *Route53) UpdateHealthCheckRequest(input *UpdateHealthCheckInput) (req *request.Request, output *UpdateHealthCheckOutput) { + op := &request.Operation{ + Name: opUpdateHealthCheck, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/healthcheck/{HealthCheckId}", + } + + if input == nil { + input = &UpdateHealthCheckInput{} + } + + output = &UpdateHealthCheckOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateHealthCheck API operation for Amazon Route 53. +// +// Updates an existing health check. Note that some values can't be updated. +// +// For more information about updating health checks, see Creating, Updating, +// and Deleting Health Checks (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-creating-deleting.html) +// in the Amazon Route 53 Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation UpdateHealthCheck for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHealthCheck "NoSuchHealthCheck" +// No health check exists with the specified ID. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeHealthCheckVersionMismatch "HealthCheckVersionMismatch" +// The value of HealthCheckVersion in the request doesn't match the value of +// HealthCheckVersion in the health check. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateHealthCheck +func (c *Route53) UpdateHealthCheck(input *UpdateHealthCheckInput) (*UpdateHealthCheckOutput, error) { + req, out := c.UpdateHealthCheckRequest(input) + return out, req.Send() +} + +// UpdateHealthCheckWithContext is the same as UpdateHealthCheck with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateHealthCheck for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) UpdateHealthCheckWithContext(ctx aws.Context, input *UpdateHealthCheckInput, opts ...request.Option) (*UpdateHealthCheckOutput, error) { + req, out := c.UpdateHealthCheckRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateHostedZoneComment = "UpdateHostedZoneComment" + +// UpdateHostedZoneCommentRequest generates a "aws/request.Request" representing the +// client's request for the UpdateHostedZoneComment operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateHostedZoneComment for more information on using the UpdateHostedZoneComment +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateHostedZoneCommentRequest method. +// req, resp := client.UpdateHostedZoneCommentRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateHostedZoneComment +func (c *Route53) UpdateHostedZoneCommentRequest(input *UpdateHostedZoneCommentInput) (req *request.Request, output *UpdateHostedZoneCommentOutput) { + op := &request.Operation{ + Name: opUpdateHostedZoneComment, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/hostedzone/{Id}", + } + + if input == nil { + input = &UpdateHostedZoneCommentInput{} + } + + output = &UpdateHostedZoneCommentOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateHostedZoneComment API operation for Amazon Route 53. +// +// Updates the comment for a specified hosted zone. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation UpdateHostedZoneComment for usage and error information. +// +// Returned Error Codes: +// * ErrCodeNoSuchHostedZone "NoSuchHostedZone" +// No hosted zone exists with the ID that you specified. +// +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateHostedZoneComment +func (c *Route53) UpdateHostedZoneComment(input *UpdateHostedZoneCommentInput) (*UpdateHostedZoneCommentOutput, error) { + req, out := c.UpdateHostedZoneCommentRequest(input) + return out, req.Send() +} + +// UpdateHostedZoneCommentWithContext is the same as UpdateHostedZoneComment with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateHostedZoneComment for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) UpdateHostedZoneCommentWithContext(ctx aws.Context, input *UpdateHostedZoneCommentInput, opts ...request.Option) (*UpdateHostedZoneCommentOutput, error) { + req, out := c.UpdateHostedZoneCommentRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateTrafficPolicyComment = "UpdateTrafficPolicyComment" + +// UpdateTrafficPolicyCommentRequest generates a "aws/request.Request" representing the +// client's request for the UpdateTrafficPolicyComment operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateTrafficPolicyComment for more information on using the UpdateTrafficPolicyComment +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateTrafficPolicyCommentRequest method. +// req, resp := client.UpdateTrafficPolicyCommentRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateTrafficPolicyComment +func (c *Route53) UpdateTrafficPolicyCommentRequest(input *UpdateTrafficPolicyCommentInput) (req *request.Request, output *UpdateTrafficPolicyCommentOutput) { + op := &request.Operation{ + Name: opUpdateTrafficPolicyComment, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/trafficpolicy/{Id}/{Version}", + } + + if input == nil { + input = &UpdateTrafficPolicyCommentInput{} + } + + output = &UpdateTrafficPolicyCommentOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateTrafficPolicyComment API operation for Amazon Route 53. +// +// Updates the comment for a specified traffic policy version. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation UpdateTrafficPolicyComment for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchTrafficPolicy "NoSuchTrafficPolicy" +// No traffic policy exists with the specified ID. +// +// * ErrCodeConcurrentModification "ConcurrentModification" +// Another user submitted a request to create, update, or delete the object +// at the same time that you did. Retry the request. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateTrafficPolicyComment +func (c *Route53) UpdateTrafficPolicyComment(input *UpdateTrafficPolicyCommentInput) (*UpdateTrafficPolicyCommentOutput, error) { + req, out := c.UpdateTrafficPolicyCommentRequest(input) + return out, req.Send() +} + +// UpdateTrafficPolicyCommentWithContext is the same as UpdateTrafficPolicyComment with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateTrafficPolicyComment for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) UpdateTrafficPolicyCommentWithContext(ctx aws.Context, input *UpdateTrafficPolicyCommentInput, opts ...request.Option) (*UpdateTrafficPolicyCommentOutput, error) { + req, out := c.UpdateTrafficPolicyCommentRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateTrafficPolicyInstance = "UpdateTrafficPolicyInstance" + +// UpdateTrafficPolicyInstanceRequest generates a "aws/request.Request" representing the +// client's request for the UpdateTrafficPolicyInstance operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateTrafficPolicyInstance for more information on using the UpdateTrafficPolicyInstance +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateTrafficPolicyInstanceRequest method. +// req, resp := client.UpdateTrafficPolicyInstanceRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateTrafficPolicyInstance +func (c *Route53) UpdateTrafficPolicyInstanceRequest(input *UpdateTrafficPolicyInstanceInput) (req *request.Request, output *UpdateTrafficPolicyInstanceOutput) { + op := &request.Operation{ + Name: opUpdateTrafficPolicyInstance, + HTTPMethod: "POST", + HTTPPath: "/2013-04-01/trafficpolicyinstance/{Id}", + } + + if input == nil { + input = &UpdateTrafficPolicyInstanceInput{} + } + + output = &UpdateTrafficPolicyInstanceOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateTrafficPolicyInstance API operation for Amazon Route 53. +// +// Updates the resource record sets in a specified hosted zone that were created +// based on the settings in a specified traffic policy version. +// +// When you update a traffic policy instance, Amazon Route 53 continues to respond +// to DNS queries for the root resource record set name (such as example.com) +// while it replaces one group of resource record sets with another. Route 53 +// performs the following operations: +// +// Route 53 creates a new group of resource record sets based on the specified +// traffic policy. This is true regardless of how significant the differences +// are between the existing resource record sets and the new resource record +// sets. +// +// When all of the new resource record sets have been created, Route 53 starts +// to respond to DNS queries for the root resource record set name (such as +// example.com) by using the new resource record sets. +// +// Route 53 deletes the old group of resource record sets that are associated +// with the root resource record set name. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for Amazon Route 53's +// API operation UpdateTrafficPolicyInstance for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidInput "InvalidInput" +// The input is not valid. +// +// * ErrCodeNoSuchTrafficPolicy "NoSuchTrafficPolicy" +// No traffic policy exists with the specified ID. +// +// * ErrCodeNoSuchTrafficPolicyInstance "NoSuchTrafficPolicyInstance" +// No traffic policy instance exists with the specified ID. +// +// * ErrCodePriorRequestNotComplete "PriorRequestNotComplete" +// If Amazon Route 53 can't process a request before the next request arrives, +// it will reject subsequent requests for the same hosted zone and return an +// HTTP 400 error (Bad request). If Route 53 returns this error repeatedly for +// the same request, we recommend that you wait, in intervals of increasing +// duration, before you try the request again. +// +// * ErrCodeConflictingTypes "ConflictingTypes" +// You tried to update a traffic policy instance by using a traffic policy version +// that has a different DNS type than the current type for the instance. You +// specified the type in the JSON document in the CreateTrafficPolicy or CreateTrafficPolicyVersionrequest. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01/UpdateTrafficPolicyInstance +func (c *Route53) UpdateTrafficPolicyInstance(input *UpdateTrafficPolicyInstanceInput) (*UpdateTrafficPolicyInstanceOutput, error) { + req, out := c.UpdateTrafficPolicyInstanceRequest(input) + return out, req.Send() +} + +// UpdateTrafficPolicyInstanceWithContext is the same as UpdateTrafficPolicyInstance with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateTrafficPolicyInstance for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) UpdateTrafficPolicyInstanceWithContext(ctx aws.Context, input *UpdateTrafficPolicyInstanceInput, opts ...request.Option) (*UpdateTrafficPolicyInstanceOutput, error) { + req, out := c.UpdateTrafficPolicyInstanceRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// A complex type that contains the type of limit that you specified in the +// request and the current value for that limit. +type AccountLimit struct { + _ struct{} `type:"structure"` + + // The limit that you requested. Valid values include the following: + // + // * MAX_HEALTH_CHECKS_BY_OWNER: The maximum number of health checks that + // you can create using the current account. + // + // * MAX_HOSTED_ZONES_BY_OWNER: The maximum number of hosted zones that you + // can create using the current account. + // + // * MAX_REUSABLE_DELEGATION_SETS_BY_OWNER: The maximum number of reusable + // delegation sets that you can create using the current account. + // + // * MAX_TRAFFIC_POLICIES_BY_OWNER: The maximum number of traffic policies + // that you can create using the current account. + // + // * MAX_TRAFFIC_POLICY_INSTANCES_BY_OWNER: The maximum number of traffic + // policy instances that you can create using the current account. (Traffic + // policy instances are referred to as traffic flow policy records in the + // Amazon Route 53 console.) + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"AccountLimitType"` + + // The current value for the limit that is specified by Type (https://docs.aws.amazon.com/Route53/latest/APIReference/API_AccountLimit.html#Route53-Type-AccountLimit-Type). + // + // Value is a required field + Value *int64 `min:"1" type:"long" required:"true"` +} + +// String returns the string representation +func (s AccountLimit) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AccountLimit) GoString() string { + return s.String() +} + +// SetType sets the Type field's value. +func (s *AccountLimit) SetType(v string) *AccountLimit { + s.Type = &v + return s +} + +// SetValue sets the Value field's value. +func (s *AccountLimit) SetValue(v int64) *AccountLimit { + s.Value = &v + return s +} + +// A complex type that identifies the CloudWatch alarm that you want Amazon +// Route 53 health checkers to use to determine whether the specified health +// check is healthy. +type AlarmIdentifier struct { + _ struct{} `type:"structure"` + + // The name of the CloudWatch alarm that you want Amazon Route 53 health checkers + // to use to determine whether this health check is healthy. + // + // Route 53 supports CloudWatch alarms with the following features: + // + // * Standard-resolution metrics. High-resolution metrics aren't supported. + // For more information, see High-Resolution Metrics (http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/publishingMetrics.html#high-resolution-metrics) + // in the Amazon CloudWatch User Guide. + // + // * Statistics: Average, Minimum, Maximum, Sum, and SampleCount. Extended + // statistics aren't supported. + // + // Name is a required field + Name *string `min:"1" type:"string" required:"true"` + + // For the CloudWatch alarm that you want Route 53 health checkers to use to + // determine whether this health check is healthy, the region that the alarm + // was created in. + // + // For the current list of CloudWatch regions, see Amazon CloudWatch (http://docs.aws.amazon.com/general/latest/gr/rande.html#cw_region) + // in the AWS Regions and Endpoints chapter of the Amazon Web Services General + // Reference. + // + // Region is a required field + Region *string `min:"1" type:"string" required:"true" enum:"CloudWatchRegion"` +} + +// String returns the string representation +func (s AlarmIdentifier) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AlarmIdentifier) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AlarmIdentifier) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AlarmIdentifier"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Name", 1)) + } + if s.Region == nil { + invalidParams.Add(request.NewErrParamRequired("Region")) + } + if s.Region != nil && len(*s.Region) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Region", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetName sets the Name field's value. +func (s *AlarmIdentifier) SetName(v string) *AlarmIdentifier { + s.Name = &v + return s +} + +// SetRegion sets the Region field's value. +func (s *AlarmIdentifier) SetRegion(v string) *AlarmIdentifier { + s.Region = &v + return s +} + +// Alias resource record sets only: Information about the AWS resource, such +// as a CloudFront distribution or an Amazon S3 bucket, that you want to route +// traffic to. +// +// When creating resource record sets for a private hosted zone, note the following: +// +// * Creating geolocation alias resource record sets or latency alias resource +// record sets in a private hosted zone is unsupported. +// +// * For information about creating failover resource record sets in a private +// hosted zone, see Configuring Failover in a Private Hosted Zone (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-private-hosted-zones.html). +type AliasTarget struct { + _ struct{} `type:"structure"` + + // Alias resource record sets only: The value that you specify depends on where + // you want to route queries: + // + // Amazon API Gateway custom regional APIs and edge-optimized APIs + // + // Specify the applicable domain name for your API. You can get the applicable + // value using the AWS CLI command get-domain-names (https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-domain-names.html): + // + // * For regional APIs, specify the value of regionalDomainName. + // + // * For edge-optimized APIs, specify the value of distributionDomainName. + // This is the name of the associated CloudFront distribution, such as da1b2c3d4e5.cloudfront.net. + // + // The name of the record that you're creating must match a custom domain name + // for your API, such as api.example.com. + // + // Amazon Virtual Private Cloud interface VPC endpoint + // + // Enter the API endpoint for the interface endpoint, such as vpce-123456789abcdef01-example-us-east-1a.elasticloadbalancing.us-east-1.vpce.amazonaws.com. + // For edge-optimized APIs, this is the domain name for the corresponding CloudFront + // distribution. You can get the value of DnsName using the AWS CLI command + // describe-vpc-endpoints (https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-vpc-endpoints.html). + // + // CloudFront distribution + // + // Specify the domain name that CloudFront assigned when you created your distribution. + // + // Your CloudFront distribution must include an alternate domain name that matches + // the name of the resource record set. For example, if the name of the resource + // record set is acme.example.com, your CloudFront distribution must include + // acme.example.com as one of the alternate domain names. For more information, + // see Using Alternate Domain Names (CNAMEs) (http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html) + // in the Amazon CloudFront Developer Guide. + // + // You can't create a resource record set in a private hosted zone to route + // traffic to a CloudFront distribution. + // + // For failover alias records, you can't specify a CloudFront distribution for + // both the primary and secondary records. A distribution must include an alternate + // domain name that matches the name of the record. However, the primary and + // secondary records have the same name, and you can't include the same alternate + // domain name in more than one distribution. + // + // Elastic Beanstalk environment + // + // If the domain name for your Elastic Beanstalk environment includes the region + // that you deployed the environment in, you can create an alias record that + // routes traffic to the environment. For example, the domain name my-environment.us-west-2.elasticbeanstalk.com + // is a regionalized domain name. + // + // For environments that were created before early 2016, the domain name doesn't + // include the region. To route traffic to these environments, you must create + // a CNAME record instead of an alias record. Note that you can't create a CNAME + // record for the root domain name. For example, if your domain name is example.com, + // you can create a record that routes traffic for acme.example.com to your + // Elastic Beanstalk environment, but you can't create a record that routes + // traffic for example.com to your Elastic Beanstalk environment. + // + // For Elastic Beanstalk environments that have regionalized subdomains, specify + // the CNAME attribute for the environment. You can use the following methods + // to get the value of the CNAME attribute: + // + // * AWS Management Console: For information about how to get the value by + // using the console, see Using Custom Domains with AWS Elastic Beanstalk + // (http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customdomains.html) + // in the AWS Elastic Beanstalk Developer Guide. + // + // * Elastic Beanstalk API: Use the DescribeEnvironments action to get the + // value of the CNAME attribute. For more information, see DescribeEnvironments + // (http://docs.aws.amazon.com/elasticbeanstalk/latest/api/API_DescribeEnvironments.html) + // in the AWS Elastic Beanstalk API Reference. + // + // * AWS CLI: Use the describe-environments command to get the value of the + // CNAME attribute. For more information, see describe-environments (http://docs.aws.amazon.com/cli/latest/reference/elasticbeanstalk/describe-environments.html) + // in the AWS Command Line Interface Reference. + // + // ELB load balancer + // + // Specify the DNS name that is associated with the load balancer. Get the DNS + // name by using the AWS Management Console, the ELB API, or the AWS CLI. + // + // * AWS Management Console: Go to the EC2 page, choose Load Balancers in + // the navigation pane, choose the load balancer, choose the Description + // tab, and get the value of the DNS name field. If you're routing traffic + // to a Classic Load Balancer, get the value that begins with dualstack. + // If you're routing traffic to another type of load balancer, get the value + // that applies to the record type, A or AAAA. + // + // * Elastic Load Balancing API: Use DescribeLoadBalancers to get the value + // of DNSName. For more information, see the applicable guide: Classic Load + // Balancers: DescribeLoadBalancers (http://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancers.html) + // Application and Network Load Balancers: DescribeLoadBalancers (http://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_DescribeLoadBalancers.html) + // + // * AWS CLI: Use describe-load-balancers to get the value of DNSName. For + // more information, see the applicable guide: Classic Load Balancers: describe-load-balancers + // (http://docs.aws.amazon.com/cli/latest/reference/elb/describe-load-balancers.html) + // Application and Network Load Balancers: describe-load-balancers (http://docs.aws.amazon.com/cli/latest/reference/elbv2/describe-load-balancers.html) + // + // Amazon S3 bucket that is configured as a static website + // + // Specify the domain name of the Amazon S3 website endpoint that you created + // the bucket in, for example, s3-website.us-east-2.amazonaws.com. For more + // information about valid values, see the table Amazon Simple Storage Service + // (S3) Website Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) + // in the Amazon Web Services General Reference. For more information about + // using S3 buckets for websites, see Getting Started with Amazon Route 53 (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started.html) + // in the Amazon Route 53 Developer Guide. + // + // Another Route 53 resource record set + // + // Specify the value of the Name element for a resource record set in the current + // hosted zone. + // + // If you're creating an alias record that has the same name as the hosted zone + // (known as the zone apex), you can't specify the domain name for a record + // for which the value of Type is CNAME. This is because the alias record must + // have the same type as the record that you're routing traffic to, and creating + // a CNAME record for the zone apex isn't supported even for an alias record. + // + // DNSName is a required field + DNSName *string `type:"string" required:"true"` + + // Applies only to alias, failover alias, geolocation alias, latency alias, + // and weighted alias resource record sets: When EvaluateTargetHealth is true, + // an alias resource record set inherits the health of the referenced AWS resource, + // such as an ELB load balancer or another resource record set in the hosted + // zone. + // + // Note the following: + // + // CloudFront distributions + // + // You can't set EvaluateTargetHealth to true when the alias target is a CloudFront + // distribution. + // + // Elastic Beanstalk environments that have regionalized subdomains + // + // If you specify an Elastic Beanstalk environment in DNSName and the environment + // contains an ELB load balancer, Elastic Load Balancing routes queries only + // to the healthy Amazon EC2 instances that are registered with the load balancer. + // (An environment automatically contains an ELB load balancer if it includes + // more than one Amazon EC2 instance.) If you set EvaluateTargetHealth to true + // and either no Amazon EC2 instances are healthy or the load balancer itself + // is unhealthy, Route 53 routes queries to other available resources that are + // healthy, if any. + // + // If the environment contains a single Amazon EC2 instance, there are no special + // requirements. + // + // ELB load balancers + // + // Health checking behavior depends on the type of load balancer: + // + // * Classic Load Balancers: If you specify an ELB Classic Load Balancer + // in DNSName, Elastic Load Balancing routes queries only to the healthy + // Amazon EC2 instances that are registered with the load balancer. If you + // set EvaluateTargetHealth to true and either no EC2 instances are healthy + // or the load balancer itself is unhealthy, Route 53 routes queries to other + // resources. + // + // * Application and Network Load Balancers: If you specify an ELB Application + // or Network Load Balancer and you set EvaluateTargetHealth to true, Route + // 53 routes queries to the load balancer based on the health of the target + // groups that are associated with the load balancer: For an Application + // or Network Load Balancer to be considered healthy, every target group + // that contains targets must contain at least one healthy target. If any + // target group contains only unhealthy targets, the load balancer is considered + // unhealthy, and Route 53 routes queries to other resources. A target group + // that has no registered targets is considered unhealthy. + // + // When you create a load balancer, you configure settings for Elastic Load + // Balancing health checks; they're not Route 53 health checks, but they perform + // a similar function. Do not create Route 53 health checks for the EC2 instances + // that you register with an ELB load balancer. + // + // S3 buckets + // + // There are no special requirements for setting EvaluateTargetHealth to true + // when the alias target is an S3 bucket. + // + // Other records in the same hosted zone + // + // If the AWS resource that you specify in DNSName is a record or a group of + // records (for example, a group of weighted records) but is not another alias + // record, we recommend that you associate a health check with all of the records + // in the alias target. For more information, see What Happens When You Omit + // Health Checks? (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-complex-configs.html#dns-failover-complex-configs-hc-omitting) + // in the Amazon Route 53 Developer Guide. + // + // For more information and examples, see Amazon Route 53 Health Checks and + // DNS Failover (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover.html) + // in the Amazon Route 53 Developer Guide. + // + // EvaluateTargetHealth is a required field + EvaluateTargetHealth *bool `type:"boolean" required:"true"` + + // Alias resource records sets only: The value used depends on where you want + // to route traffic: + // + // Amazon API Gateway custom regional APIs and edge-optimized APIs + // + // Specify the hosted zone ID for your API. You can get the applicable value + // using the AWS CLI command get-domain-names (https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-domain-names.html): + // + // * For regional APIs, specify the value of regionalHostedZoneId. + // + // * For edge-optimized APIs, specify the value of distributionHostedZoneId. + // + // Amazon Virtual Private Cloud interface VPC endpoint + // + // Specify the hosted zone ID for your interface endpoint. You can get the value + // of HostedZoneId using the AWS CLI command describe-vpc-endpoints (https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-vpc-endpoints.html). + // + // CloudFront distribution + // + // Specify Z2FDTNDATAQYW2. + // + // Alias resource record sets for CloudFront can't be created in a private zone. + // + // Elastic Beanstalk environment + // + // Specify the hosted zone ID for the region that you created the environment + // in. The environment must have a regionalized subdomain. For a list of regions + // and the corresponding hosted zone IDs, see AWS Elastic Beanstalk (http://docs.aws.amazon.com/general/latest/gr/rande.html#elasticbeanstalk_region) + // in the "AWS Regions and Endpoints" chapter of the Amazon Web Services General + // Reference. + // + // ELB load balancer + // + // Specify the value of the hosted zone ID for the load balancer. Use the following + // methods to get the hosted zone ID: + // + // * Elastic Load Balancing (https://docs.aws.amazon.com/general/latest/gr/rande.html#elb_region) + // table in the "AWS Regions and Endpoints" chapter of the Amazon Web Services + // General Reference: Use the value that corresponds with the region that + // you created your load balancer in. Note that there are separate columns + // for Application and Classic Load Balancers and for Network Load Balancers. + // + // * AWS Management Console: Go to the Amazon EC2 page, choose Load Balancers + // in the navigation pane, select the load balancer, and get the value of + // the Hosted zone field on the Description tab. + // + // * Elastic Load Balancing API: Use DescribeLoadBalancers to get the applicable + // value. For more information, see the applicable guide: Classic Load Balancers: + // Use DescribeLoadBalancers (http://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeLoadBalancers.html) + // to get the value of CanonicalHostedZoneNameId. Application and Network + // Load Balancers: Use DescribeLoadBalancers (http://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_DescribeLoadBalancers.html) + // to get the value of CanonicalHostedZoneId. + // + // * AWS CLI: Use describe-load-balancers to get the applicable value. For + // more information, see the applicable guide: Classic Load Balancers: Use + // describe-load-balancers (http://docs.aws.amazon.com/cli/latest/reference/elb/describe-load-balancers.html) + // to get the value of CanonicalHostedZoneNameId. Application and Network + // Load Balancers: Use describe-load-balancers (http://docs.aws.amazon.com/cli/latest/reference/elbv2/describe-load-balancers.html) + // to get the value of CanonicalHostedZoneId. + // + // An Amazon S3 bucket configured as a static website + // + // Specify the hosted zone ID for the region that you created the bucket in. + // For more information about valid values, see the Amazon Simple Storage Service + // Website Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) + // table in the "AWS Regions and Endpoints" chapter of the Amazon Web Services + // General Reference. + // + // Another Route 53 resource record set in your hosted zone + // + // Specify the hosted zone ID of your hosted zone. (An alias resource record + // set can't reference a resource record set in a different hosted zone.) + // + // HostedZoneId is a required field + HostedZoneId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s AliasTarget) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AliasTarget) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AliasTarget) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AliasTarget"} + if s.DNSName == nil { + invalidParams.Add(request.NewErrParamRequired("DNSName")) + } + if s.EvaluateTargetHealth == nil { + invalidParams.Add(request.NewErrParamRequired("EvaluateTargetHealth")) + } + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDNSName sets the DNSName field's value. +func (s *AliasTarget) SetDNSName(v string) *AliasTarget { + s.DNSName = &v + return s +} + +// SetEvaluateTargetHealth sets the EvaluateTargetHealth field's value. +func (s *AliasTarget) SetEvaluateTargetHealth(v bool) *AliasTarget { + s.EvaluateTargetHealth = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *AliasTarget) SetHostedZoneId(v string) *AliasTarget { + s.HostedZoneId = &v + return s +} + +// A complex type that contains information about the request to associate a +// VPC with a private hosted zone. +type AssociateVPCWithHostedZoneInput struct { + _ struct{} `locationName:"AssociateVPCWithHostedZoneRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // Optional: A comment about the association request. + Comment *string `type:"string"` + + // The ID of the private hosted zone that you want to associate an Amazon VPC + // with. + // + // Note that you can't associate a VPC with a hosted zone that doesn't have + // an existing VPC association. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` + + // A complex type that contains information about the VPC that you want to associate + // with a private hosted zone. + // + // VPC is a required field + VPC *VPC `type:"structure" required:"true"` +} + +// String returns the string representation +func (s AssociateVPCWithHostedZoneInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateVPCWithHostedZoneInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssociateVPCWithHostedZoneInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssociateVPCWithHostedZoneInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.HostedZoneId != nil && len(*s.HostedZoneId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HostedZoneId", 1)) + } + if s.VPC == nil { + invalidParams.Add(request.NewErrParamRequired("VPC")) + } + if s.VPC != nil { + if err := s.VPC.Validate(); err != nil { + invalidParams.AddNested("VPC", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetComment sets the Comment field's value. +func (s *AssociateVPCWithHostedZoneInput) SetComment(v string) *AssociateVPCWithHostedZoneInput { + s.Comment = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *AssociateVPCWithHostedZoneInput) SetHostedZoneId(v string) *AssociateVPCWithHostedZoneInput { + s.HostedZoneId = &v + return s +} + +// SetVPC sets the VPC field's value. +func (s *AssociateVPCWithHostedZoneInput) SetVPC(v *VPC) *AssociateVPCWithHostedZoneInput { + s.VPC = v + return s +} + +// A complex type that contains the response information for the AssociateVPCWithHostedZone +// request. +type AssociateVPCWithHostedZoneOutput struct { + _ struct{} `type:"structure"` + + // A complex type that describes the changes made to your hosted zone. + // + // ChangeInfo is a required field + ChangeInfo *ChangeInfo `type:"structure" required:"true"` +} + +// String returns the string representation +func (s AssociateVPCWithHostedZoneOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssociateVPCWithHostedZoneOutput) GoString() string { + return s.String() +} + +// SetChangeInfo sets the ChangeInfo field's value. +func (s *AssociateVPCWithHostedZoneOutput) SetChangeInfo(v *ChangeInfo) *AssociateVPCWithHostedZoneOutput { + s.ChangeInfo = v + return s +} + +// The information for each resource record set that you want to change. +type Change struct { + _ struct{} `type:"structure"` + + // The action to perform: + // + // * CREATE: Creates a resource record set that has the specified values. + // + // * DELETE: Deletes a existing resource record set. To delete the resource + // record set that is associated with a traffic policy instance, use DeleteTrafficPolicyInstance + // (https://docs.aws.amazon.com/Route53/latest/APIReference/API_DeleteTrafficPolicyInstance.html). + // Amazon Route 53 will delete the resource record set automatically. If + // you delete the resource record set by using ChangeResourceRecordSets, + // Route 53 doesn't automatically delete the traffic policy instance, and + // you'll continue to be charged for it even though it's no longer in use. + // + // * UPSERT: If a resource record set doesn't already exist, Route 53 creates + // it. If a resource record set does exist, Route 53 updates it with the + // values in the request. + // + // Action is a required field + Action *string `type:"string" required:"true" enum:"ChangeAction"` + + // Information about the resource record set to create, delete, or update. + // + // ResourceRecordSet is a required field + ResourceRecordSet *ResourceRecordSet `type:"structure" required:"true"` +} + +// String returns the string representation +func (s Change) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Change) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *Change) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "Change"} + if s.Action == nil { + invalidParams.Add(request.NewErrParamRequired("Action")) + } + if s.ResourceRecordSet == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceRecordSet")) + } + if s.ResourceRecordSet != nil { + if err := s.ResourceRecordSet.Validate(); err != nil { + invalidParams.AddNested("ResourceRecordSet", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAction sets the Action field's value. +func (s *Change) SetAction(v string) *Change { + s.Action = &v + return s +} + +// SetResourceRecordSet sets the ResourceRecordSet field's value. +func (s *Change) SetResourceRecordSet(v *ResourceRecordSet) *Change { + s.ResourceRecordSet = v + return s +} + +// The information for a change request. +type ChangeBatch struct { + _ struct{} `type:"structure"` + + // Information about the changes to make to the record sets. + // + // Changes is a required field + Changes []*Change `locationNameList:"Change" min:"1" type:"list" required:"true"` + + // Optional: Any comments you want to include about a change batch request. + Comment *string `type:"string"` +} + +// String returns the string representation +func (s ChangeBatch) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ChangeBatch) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ChangeBatch) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ChangeBatch"} + if s.Changes == nil { + invalidParams.Add(request.NewErrParamRequired("Changes")) + } + if s.Changes != nil && len(s.Changes) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Changes", 1)) + } + if s.Changes != nil { + for i, v := range s.Changes { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Changes", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetChanges sets the Changes field's value. +func (s *ChangeBatch) SetChanges(v []*Change) *ChangeBatch { + s.Changes = v + return s +} + +// SetComment sets the Comment field's value. +func (s *ChangeBatch) SetComment(v string) *ChangeBatch { + s.Comment = &v + return s +} + +// A complex type that describes change information about changes made to your +// hosted zone. +type ChangeInfo struct { + _ struct{} `type:"structure"` + + // A complex type that describes change information about changes made to your + // hosted zone. + // + // This element contains an ID that you use when performing a GetChange (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetChange.html) + // action to get detailed information about the change. + Comment *string `type:"string"` + + // The ID of the request. + // + // Id is a required field + Id *string `type:"string" required:"true"` + + // The current state of the request. PENDING indicates that this request has + // not yet been applied to all Amazon Route 53 DNS servers. + // + // Status is a required field + Status *string `type:"string" required:"true" enum:"ChangeStatus"` + + // The date and time that the change request was submitted in ISO 8601 format + // (https://en.wikipedia.org/wiki/ISO_8601) and Coordinated Universal Time (UTC). + // For example, the value 2017-03-27T17:48:16.751Z represents March 27, 2017 + // at 17:48:16.751 UTC. + // + // SubmittedAt is a required field + SubmittedAt *time.Time `type:"timestamp" required:"true"` +} + +// String returns the string representation +func (s ChangeInfo) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ChangeInfo) GoString() string { + return s.String() +} + +// SetComment sets the Comment field's value. +func (s *ChangeInfo) SetComment(v string) *ChangeInfo { + s.Comment = &v + return s +} + +// SetId sets the Id field's value. +func (s *ChangeInfo) SetId(v string) *ChangeInfo { + s.Id = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *ChangeInfo) SetStatus(v string) *ChangeInfo { + s.Status = &v + return s +} + +// SetSubmittedAt sets the SubmittedAt field's value. +func (s *ChangeInfo) SetSubmittedAt(v time.Time) *ChangeInfo { + s.SubmittedAt = &v + return s +} + +// A complex type that contains change information for the resource record set. +type ChangeResourceRecordSetsInput struct { + _ struct{} `locationName:"ChangeResourceRecordSetsRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // A complex type that contains an optional comment and the Changes element. + // + // ChangeBatch is a required field + ChangeBatch *ChangeBatch `type:"structure" required:"true"` + + // The ID of the hosted zone that contains the resource record sets that you + // want to change. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` +} + +// String returns the string representation +func (s ChangeResourceRecordSetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ChangeResourceRecordSetsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ChangeResourceRecordSetsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ChangeResourceRecordSetsInput"} + if s.ChangeBatch == nil { + invalidParams.Add(request.NewErrParamRequired("ChangeBatch")) + } + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.HostedZoneId != nil && len(*s.HostedZoneId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HostedZoneId", 1)) + } + if s.ChangeBatch != nil { + if err := s.ChangeBatch.Validate(); err != nil { + invalidParams.AddNested("ChangeBatch", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetChangeBatch sets the ChangeBatch field's value. +func (s *ChangeResourceRecordSetsInput) SetChangeBatch(v *ChangeBatch) *ChangeResourceRecordSetsInput { + s.ChangeBatch = v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *ChangeResourceRecordSetsInput) SetHostedZoneId(v string) *ChangeResourceRecordSetsInput { + s.HostedZoneId = &v + return s +} + +// A complex type containing the response for the request. +type ChangeResourceRecordSetsOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains information about changes made to your hosted + // zone. + // + // This element contains an ID that you use when performing a GetChange (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetChange.html) + // action to get detailed information about the change. + // + // ChangeInfo is a required field + ChangeInfo *ChangeInfo `type:"structure" required:"true"` +} + +// String returns the string representation +func (s ChangeResourceRecordSetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ChangeResourceRecordSetsOutput) GoString() string { + return s.String() +} + +// SetChangeInfo sets the ChangeInfo field's value. +func (s *ChangeResourceRecordSetsOutput) SetChangeInfo(v *ChangeInfo) *ChangeResourceRecordSetsOutput { + s.ChangeInfo = v + return s +} + +// A complex type that contains information about the tags that you want to +// add, edit, or delete. +type ChangeTagsForResourceInput struct { + _ struct{} `locationName:"ChangeTagsForResourceRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // A complex type that contains a list of the tags that you want to add to the + // specified health check or hosted zone and/or the tags that you want to edit + // Value for. + // + // You can add a maximum of 10 tags to a health check or a hosted zone. + AddTags []*Tag `locationNameList:"Tag" min:"1" type:"list"` + + // A complex type that contains a list of the tags that you want to delete from + // the specified health check or hosted zone. You can specify up to 10 keys. + RemoveTagKeys []*string `locationNameList:"Key" min:"1" type:"list"` + + // The ID of the resource for which you want to add, change, or delete tags. + // + // ResourceId is a required field + ResourceId *string `location:"uri" locationName:"ResourceId" type:"string" required:"true"` + + // The type of the resource. + // + // * The resource type for health checks is healthcheck. + // + // * The resource type for hosted zones is hostedzone. + // + // ResourceType is a required field + ResourceType *string `location:"uri" locationName:"ResourceType" type:"string" required:"true" enum:"TagResourceType"` +} + +// String returns the string representation +func (s ChangeTagsForResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ChangeTagsForResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ChangeTagsForResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ChangeTagsForResourceInput"} + if s.AddTags != nil && len(s.AddTags) < 1 { + invalidParams.Add(request.NewErrParamMinLen("AddTags", 1)) + } + if s.RemoveTagKeys != nil && len(s.RemoveTagKeys) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RemoveTagKeys", 1)) + } + if s.ResourceId == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceId")) + } + if s.ResourceId != nil && len(*s.ResourceId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceId", 1)) + } + if s.ResourceType == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceType")) + } + if s.ResourceType != nil && len(*s.ResourceType) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceType", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAddTags sets the AddTags field's value. +func (s *ChangeTagsForResourceInput) SetAddTags(v []*Tag) *ChangeTagsForResourceInput { + s.AddTags = v + return s +} + +// SetRemoveTagKeys sets the RemoveTagKeys field's value. +func (s *ChangeTagsForResourceInput) SetRemoveTagKeys(v []*string) *ChangeTagsForResourceInput { + s.RemoveTagKeys = v + return s +} + +// SetResourceId sets the ResourceId field's value. +func (s *ChangeTagsForResourceInput) SetResourceId(v string) *ChangeTagsForResourceInput { + s.ResourceId = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *ChangeTagsForResourceInput) SetResourceType(v string) *ChangeTagsForResourceInput { + s.ResourceType = &v + return s +} + +// Empty response for the request. +type ChangeTagsForResourceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s ChangeTagsForResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ChangeTagsForResourceOutput) GoString() string { + return s.String() +} + +// A complex type that contains information about the CloudWatch alarm that +// Amazon Route 53 is monitoring for this health check. +type CloudWatchAlarmConfiguration struct { + _ struct{} `type:"structure"` + + // For the metric that the CloudWatch alarm is associated with, the arithmetic + // operation that is used for the comparison. + // + // ComparisonOperator is a required field + ComparisonOperator *string `type:"string" required:"true" enum:"ComparisonOperator"` + + // For the metric that the CloudWatch alarm is associated with, a complex type + // that contains information about the dimensions for the metric. For information, + // see Amazon CloudWatch Namespaces, Dimensions, and Metrics Reference (http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html) + // in the Amazon CloudWatch User Guide. + Dimensions []*Dimension `locationNameList:"Dimension" type:"list"` + + // For the metric that the CloudWatch alarm is associated with, the number of + // periods that the metric is compared to the threshold. + // + // EvaluationPeriods is a required field + EvaluationPeriods *int64 `min:"1" type:"integer" required:"true"` + + // The name of the CloudWatch metric that the alarm is associated with. + // + // MetricName is a required field + MetricName *string `min:"1" type:"string" required:"true"` + + // The namespace of the metric that the alarm is associated with. For more information, + // see Amazon CloudWatch Namespaces, Dimensions, and Metrics Reference (http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/CW_Support_For_AWS.html) + // in the Amazon CloudWatch User Guide. + // + // Namespace is a required field + Namespace *string `min:"1" type:"string" required:"true"` + + // For the metric that the CloudWatch alarm is associated with, the duration + // of one evaluation period in seconds. + // + // Period is a required field + Period *int64 `min:"60" type:"integer" required:"true"` + + // For the metric that the CloudWatch alarm is associated with, the statistic + // that is applied to the metric. + // + // Statistic is a required field + Statistic *string `type:"string" required:"true" enum:"Statistic"` + + // For the metric that the CloudWatch alarm is associated with, the value the + // metric is compared with. + // + // Threshold is a required field + Threshold *float64 `type:"double" required:"true"` +} + +// String returns the string representation +func (s CloudWatchAlarmConfiguration) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CloudWatchAlarmConfiguration) GoString() string { + return s.String() +} + +// SetComparisonOperator sets the ComparisonOperator field's value. +func (s *CloudWatchAlarmConfiguration) SetComparisonOperator(v string) *CloudWatchAlarmConfiguration { + s.ComparisonOperator = &v + return s +} + +// SetDimensions sets the Dimensions field's value. +func (s *CloudWatchAlarmConfiguration) SetDimensions(v []*Dimension) *CloudWatchAlarmConfiguration { + s.Dimensions = v + return s +} + +// SetEvaluationPeriods sets the EvaluationPeriods field's value. +func (s *CloudWatchAlarmConfiguration) SetEvaluationPeriods(v int64) *CloudWatchAlarmConfiguration { + s.EvaluationPeriods = &v + return s +} + +// SetMetricName sets the MetricName field's value. +func (s *CloudWatchAlarmConfiguration) SetMetricName(v string) *CloudWatchAlarmConfiguration { + s.MetricName = &v + return s +} + +// SetNamespace sets the Namespace field's value. +func (s *CloudWatchAlarmConfiguration) SetNamespace(v string) *CloudWatchAlarmConfiguration { + s.Namespace = &v + return s +} + +// SetPeriod sets the Period field's value. +func (s *CloudWatchAlarmConfiguration) SetPeriod(v int64) *CloudWatchAlarmConfiguration { + s.Period = &v + return s +} + +// SetStatistic sets the Statistic field's value. +func (s *CloudWatchAlarmConfiguration) SetStatistic(v string) *CloudWatchAlarmConfiguration { + s.Statistic = &v + return s +} + +// SetThreshold sets the Threshold field's value. +func (s *CloudWatchAlarmConfiguration) SetThreshold(v float64) *CloudWatchAlarmConfiguration { + s.Threshold = &v + return s +} + +// A complex type that contains the health check request information. +type CreateHealthCheckInput struct { + _ struct{} `locationName:"CreateHealthCheckRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // A unique string that identifies the request and that allows you to retry + // a failed CreateHealthCheck request without the risk of creating two identical + // health checks: + // + // * If you send a CreateHealthCheck request with the same CallerReference + // and settings as a previous request, and if the health check doesn't exist, + // Amazon Route 53 creates the health check. If the health check does exist, + // Route 53 returns the settings for the existing health check. + // + // * If you send a CreateHealthCheck request with the same CallerReference + // as a deleted health check, regardless of the settings, Route 53 returns + // a HealthCheckAlreadyExists error. + // + // * If you send a CreateHealthCheck request with the same CallerReference + // as an existing health check but with different settings, Route 53 returns + // a HealthCheckAlreadyExists error. + // + // * If you send a CreateHealthCheck request with a unique CallerReference + // but settings identical to an existing health check, Route 53 creates the + // health check. + // + // CallerReference is a required field + CallerReference *string `min:"1" type:"string" required:"true"` + + // A complex type that contains settings for a new health check. + // + // HealthCheckConfig is a required field + HealthCheckConfig *HealthCheckConfig `type:"structure" required:"true"` +} + +// String returns the string representation +func (s CreateHealthCheckInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateHealthCheckInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateHealthCheckInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateHealthCheckInput"} + if s.CallerReference == nil { + invalidParams.Add(request.NewErrParamRequired("CallerReference")) + } + if s.CallerReference != nil && len(*s.CallerReference) < 1 { + invalidParams.Add(request.NewErrParamMinLen("CallerReference", 1)) + } + if s.HealthCheckConfig == nil { + invalidParams.Add(request.NewErrParamRequired("HealthCheckConfig")) + } + if s.HealthCheckConfig != nil { + if err := s.HealthCheckConfig.Validate(); err != nil { + invalidParams.AddNested("HealthCheckConfig", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCallerReference sets the CallerReference field's value. +func (s *CreateHealthCheckInput) SetCallerReference(v string) *CreateHealthCheckInput { + s.CallerReference = &v + return s +} + +// SetHealthCheckConfig sets the HealthCheckConfig field's value. +func (s *CreateHealthCheckInput) SetHealthCheckConfig(v *HealthCheckConfig) *CreateHealthCheckInput { + s.HealthCheckConfig = v + return s +} + +// A complex type containing the response information for the new health check. +type CreateHealthCheckOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains identifying information about the health check. + // + // HealthCheck is a required field + HealthCheck *HealthCheck `type:"structure" required:"true"` + + // The unique URL representing the new health check. + // + // Location is a required field + Location *string `location:"header" locationName:"Location" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateHealthCheckOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateHealthCheckOutput) GoString() string { + return s.String() +} + +// SetHealthCheck sets the HealthCheck field's value. +func (s *CreateHealthCheckOutput) SetHealthCheck(v *HealthCheck) *CreateHealthCheckOutput { + s.HealthCheck = v + return s +} + +// SetLocation sets the Location field's value. +func (s *CreateHealthCheckOutput) SetLocation(v string) *CreateHealthCheckOutput { + s.Location = &v + return s +} + +// A complex type that contains information about the request to create a public +// or private hosted zone. +type CreateHostedZoneInput struct { + _ struct{} `locationName:"CreateHostedZoneRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // A unique string that identifies the request and that allows failed CreateHostedZone + // requests to be retried without the risk of executing the operation twice. + // You must use a unique CallerReference string every time you submit a CreateHostedZone + // request. CallerReference can be any unique string, for example, a date/time + // stamp. + // + // CallerReference is a required field + CallerReference *string `min:"1" type:"string" required:"true"` + + // If you want to associate a reusable delegation set with this hosted zone, + // the ID that Amazon Route 53 assigned to the reusable delegation set when + // you created it. For more information about reusable delegation sets, see + // CreateReusableDelegationSet (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateReusableDelegationSet.html). + DelegationSetId *string `type:"string"` + + // (Optional) A complex type that contains the following optional values: + // + // * For public and private hosted zones, an optional comment + // + // * For private hosted zones, an optional PrivateZone element + // + // If you don't specify a comment or the PrivateZone element, omit HostedZoneConfig + // and the other elements. + HostedZoneConfig *HostedZoneConfig `type:"structure"` + + // The name of the domain. Specify a fully qualified domain name, for example, + // www.example.com. The trailing dot is optional; Amazon Route 53 assumes that + // the domain name is fully qualified. This means that Route 53 treats www.example.com + // (without a trailing dot) and www.example.com. (with a trailing dot) as identical. + // + // If you're creating a public hosted zone, this is the name you have registered + // with your DNS registrar. If your domain name is registered with a registrar + // other than Route 53, change the name servers for your domain to the set of + // NameServers that CreateHostedZone returns in DelegationSet. + // + // Name is a required field + Name *string `type:"string" required:"true"` + + // (Private hosted zones only) A complex type that contains information about + // the Amazon VPC that you're associating with this hosted zone. + // + // You can specify only one Amazon VPC when you create a private hosted zone. + // To associate additional Amazon VPCs with the hosted zone, use AssociateVPCWithHostedZone + // (https://docs.aws.amazon.com/Route53/latest/APIReference/API_AssociateVPCWithHostedZone.html) + // after you create a hosted zone. + VPC *VPC `type:"structure"` +} + +// String returns the string representation +func (s CreateHostedZoneInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateHostedZoneInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateHostedZoneInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateHostedZoneInput"} + if s.CallerReference == nil { + invalidParams.Add(request.NewErrParamRequired("CallerReference")) + } + if s.CallerReference != nil && len(*s.CallerReference) < 1 { + invalidParams.Add(request.NewErrParamMinLen("CallerReference", 1)) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.VPC != nil { + if err := s.VPC.Validate(); err != nil { + invalidParams.AddNested("VPC", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCallerReference sets the CallerReference field's value. +func (s *CreateHostedZoneInput) SetCallerReference(v string) *CreateHostedZoneInput { + s.CallerReference = &v + return s +} + +// SetDelegationSetId sets the DelegationSetId field's value. +func (s *CreateHostedZoneInput) SetDelegationSetId(v string) *CreateHostedZoneInput { + s.DelegationSetId = &v + return s +} + +// SetHostedZoneConfig sets the HostedZoneConfig field's value. +func (s *CreateHostedZoneInput) SetHostedZoneConfig(v *HostedZoneConfig) *CreateHostedZoneInput { + s.HostedZoneConfig = v + return s +} + +// SetName sets the Name field's value. +func (s *CreateHostedZoneInput) SetName(v string) *CreateHostedZoneInput { + s.Name = &v + return s +} + +// SetVPC sets the VPC field's value. +func (s *CreateHostedZoneInput) SetVPC(v *VPC) *CreateHostedZoneInput { + s.VPC = v + return s +} + +// A complex type containing the response information for the hosted zone. +type CreateHostedZoneOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains information about the CreateHostedZone request. + // + // ChangeInfo is a required field + ChangeInfo *ChangeInfo `type:"structure" required:"true"` + + // A complex type that describes the name servers for this hosted zone. + // + // DelegationSet is a required field + DelegationSet *DelegationSet `type:"structure" required:"true"` + + // A complex type that contains general information about the hosted zone. + // + // HostedZone is a required field + HostedZone *HostedZone `type:"structure" required:"true"` + + // The unique URL representing the new hosted zone. + // + // Location is a required field + Location *string `location:"header" locationName:"Location" type:"string" required:"true"` + + // A complex type that contains information about an Amazon VPC that you associated + // with this hosted zone. + VPC *VPC `type:"structure"` +} + +// String returns the string representation +func (s CreateHostedZoneOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateHostedZoneOutput) GoString() string { + return s.String() +} + +// SetChangeInfo sets the ChangeInfo field's value. +func (s *CreateHostedZoneOutput) SetChangeInfo(v *ChangeInfo) *CreateHostedZoneOutput { + s.ChangeInfo = v + return s +} + +// SetDelegationSet sets the DelegationSet field's value. +func (s *CreateHostedZoneOutput) SetDelegationSet(v *DelegationSet) *CreateHostedZoneOutput { + s.DelegationSet = v + return s +} + +// SetHostedZone sets the HostedZone field's value. +func (s *CreateHostedZoneOutput) SetHostedZone(v *HostedZone) *CreateHostedZoneOutput { + s.HostedZone = v + return s +} + +// SetLocation sets the Location field's value. +func (s *CreateHostedZoneOutput) SetLocation(v string) *CreateHostedZoneOutput { + s.Location = &v + return s +} + +// SetVPC sets the VPC field's value. +func (s *CreateHostedZoneOutput) SetVPC(v *VPC) *CreateHostedZoneOutput { + s.VPC = v + return s +} + +type CreateQueryLoggingConfigInput struct { + _ struct{} `locationName:"CreateQueryLoggingConfigRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // The Amazon Resource Name (ARN) for the log group that you want to Amazon + // Route 53 to send query logs to. This is the format of the ARN: + // + // arn:aws:logs:region:account-id:log-group:log_group_name + // + // To get the ARN for a log group, you can use the CloudWatch console, the DescribeLogGroups + // (https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogGroups.html) + // API action, the describe-log-groups (https://docs.aws.amazon.com/cli/latest/reference/logs/describe-log-groups.html) + // command, or the applicable command in one of the AWS SDKs. + // + // CloudWatchLogsLogGroupArn is a required field + CloudWatchLogsLogGroupArn *string `type:"string" required:"true"` + + // The ID of the hosted zone that you want to log queries for. You can log queries + // only for public hosted zones. + // + // HostedZoneId is a required field + HostedZoneId *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateQueryLoggingConfigInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateQueryLoggingConfigInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateQueryLoggingConfigInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateQueryLoggingConfigInput"} + if s.CloudWatchLogsLogGroupArn == nil { + invalidParams.Add(request.NewErrParamRequired("CloudWatchLogsLogGroupArn")) + } + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCloudWatchLogsLogGroupArn sets the CloudWatchLogsLogGroupArn field's value. +func (s *CreateQueryLoggingConfigInput) SetCloudWatchLogsLogGroupArn(v string) *CreateQueryLoggingConfigInput { + s.CloudWatchLogsLogGroupArn = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *CreateQueryLoggingConfigInput) SetHostedZoneId(v string) *CreateQueryLoggingConfigInput { + s.HostedZoneId = &v + return s +} + +type CreateQueryLoggingConfigOutput struct { + _ struct{} `type:"structure"` + + // The unique URL representing the new query logging configuration. + // + // Location is a required field + Location *string `location:"header" locationName:"Location" type:"string" required:"true"` + + // A complex type that contains the ID for a query logging configuration, the + // ID of the hosted zone that you want to log queries for, and the ARN for the + // log group that you want Amazon Route 53 to send query logs to. + // + // QueryLoggingConfig is a required field + QueryLoggingConfig *QueryLoggingConfig `type:"structure" required:"true"` +} + +// String returns the string representation +func (s CreateQueryLoggingConfigOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateQueryLoggingConfigOutput) GoString() string { + return s.String() +} + +// SetLocation sets the Location field's value. +func (s *CreateQueryLoggingConfigOutput) SetLocation(v string) *CreateQueryLoggingConfigOutput { + s.Location = &v + return s +} + +// SetQueryLoggingConfig sets the QueryLoggingConfig field's value. +func (s *CreateQueryLoggingConfigOutput) SetQueryLoggingConfig(v *QueryLoggingConfig) *CreateQueryLoggingConfigOutput { + s.QueryLoggingConfig = v + return s +} + +type CreateReusableDelegationSetInput struct { + _ struct{} `locationName:"CreateReusableDelegationSetRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // A unique string that identifies the request, and that allows you to retry + // failed CreateReusableDelegationSet requests without the risk of executing + // the operation twice. You must use a unique CallerReference string every time + // you submit a CreateReusableDelegationSet request. CallerReference can be + // any unique string, for example a date/time stamp. + // + // CallerReference is a required field + CallerReference *string `min:"1" type:"string" required:"true"` + + // If you want to mark the delegation set for an existing hosted zone as reusable, + // the ID for that hosted zone. + HostedZoneId *string `type:"string"` +} + +// String returns the string representation +func (s CreateReusableDelegationSetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateReusableDelegationSetInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateReusableDelegationSetInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateReusableDelegationSetInput"} + if s.CallerReference == nil { + invalidParams.Add(request.NewErrParamRequired("CallerReference")) + } + if s.CallerReference != nil && len(*s.CallerReference) < 1 { + invalidParams.Add(request.NewErrParamMinLen("CallerReference", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetCallerReference sets the CallerReference field's value. +func (s *CreateReusableDelegationSetInput) SetCallerReference(v string) *CreateReusableDelegationSetInput { + s.CallerReference = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *CreateReusableDelegationSetInput) SetHostedZoneId(v string) *CreateReusableDelegationSetInput { + s.HostedZoneId = &v + return s +} + +type CreateReusableDelegationSetOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains name server information. + // + // DelegationSet is a required field + DelegationSet *DelegationSet `type:"structure" required:"true"` + + // The unique URL representing the new reusable delegation set. + // + // Location is a required field + Location *string `location:"header" locationName:"Location" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateReusableDelegationSetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateReusableDelegationSetOutput) GoString() string { + return s.String() +} + +// SetDelegationSet sets the DelegationSet field's value. +func (s *CreateReusableDelegationSetOutput) SetDelegationSet(v *DelegationSet) *CreateReusableDelegationSetOutput { + s.DelegationSet = v + return s +} + +// SetLocation sets the Location field's value. +func (s *CreateReusableDelegationSetOutput) SetLocation(v string) *CreateReusableDelegationSetOutput { + s.Location = &v + return s +} + +// A complex type that contains information about the traffic policy that you +// want to create. +type CreateTrafficPolicyInput struct { + _ struct{} `locationName:"CreateTrafficPolicyRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // (Optional) Any comments that you want to include about the traffic policy. + Comment *string `type:"string"` + + // The definition of this traffic policy in JSON format. For more information, + // see Traffic Policy Document Format (https://docs.aws.amazon.com/Route53/latest/APIReference/api-policies-traffic-policy-document-format.html). + // + // Document is a required field + Document *string `type:"string" required:"true"` + + // The name of the traffic policy. + // + // Name is a required field + Name *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateTrafficPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTrafficPolicyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateTrafficPolicyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateTrafficPolicyInput"} + if s.Document == nil { + invalidParams.Add(request.NewErrParamRequired("Document")) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetComment sets the Comment field's value. +func (s *CreateTrafficPolicyInput) SetComment(v string) *CreateTrafficPolicyInput { + s.Comment = &v + return s +} + +// SetDocument sets the Document field's value. +func (s *CreateTrafficPolicyInput) SetDocument(v string) *CreateTrafficPolicyInput { + s.Document = &v + return s +} + +// SetName sets the Name field's value. +func (s *CreateTrafficPolicyInput) SetName(v string) *CreateTrafficPolicyInput { + s.Name = &v + return s +} + +// A complex type that contains information about the resource record sets that +// you want to create based on a specified traffic policy. +type CreateTrafficPolicyInstanceInput struct { + _ struct{} `locationName:"CreateTrafficPolicyInstanceRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // The ID of the hosted zone that you want Amazon Route 53 to create resource + // record sets in by using the configuration in a traffic policy. + // + // HostedZoneId is a required field + HostedZoneId *string `type:"string" required:"true"` + + // The domain name (such as example.com) or subdomain name (such as www.example.com) + // for which Amazon Route 53 responds to DNS queries by using the resource record + // sets that Route 53 creates for this traffic policy instance. + // + // Name is a required field + Name *string `type:"string" required:"true"` + + // (Optional) The TTL that you want Amazon Route 53 to assign to all of the + // resource record sets that it creates in the specified hosted zone. + // + // TTL is a required field + TTL *int64 `type:"long" required:"true"` + + // The ID of the traffic policy that you want to use to create resource record + // sets in the specified hosted zone. + // + // TrafficPolicyId is a required field + TrafficPolicyId *string `min:"1" type:"string" required:"true"` + + // The version of the traffic policy that you want to use to create resource + // record sets in the specified hosted zone. + // + // TrafficPolicyVersion is a required field + TrafficPolicyVersion *int64 `min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s CreateTrafficPolicyInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTrafficPolicyInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateTrafficPolicyInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateTrafficPolicyInstanceInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.TTL == nil { + invalidParams.Add(request.NewErrParamRequired("TTL")) + } + if s.TrafficPolicyId == nil { + invalidParams.Add(request.NewErrParamRequired("TrafficPolicyId")) + } + if s.TrafficPolicyId != nil && len(*s.TrafficPolicyId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TrafficPolicyId", 1)) + } + if s.TrafficPolicyVersion == nil { + invalidParams.Add(request.NewErrParamRequired("TrafficPolicyVersion")) + } + if s.TrafficPolicyVersion != nil && *s.TrafficPolicyVersion < 1 { + invalidParams.Add(request.NewErrParamMinValue("TrafficPolicyVersion", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *CreateTrafficPolicyInstanceInput) SetHostedZoneId(v string) *CreateTrafficPolicyInstanceInput { + s.HostedZoneId = &v + return s +} + +// SetName sets the Name field's value. +func (s *CreateTrafficPolicyInstanceInput) SetName(v string) *CreateTrafficPolicyInstanceInput { + s.Name = &v + return s +} + +// SetTTL sets the TTL field's value. +func (s *CreateTrafficPolicyInstanceInput) SetTTL(v int64) *CreateTrafficPolicyInstanceInput { + s.TTL = &v + return s +} + +// SetTrafficPolicyId sets the TrafficPolicyId field's value. +func (s *CreateTrafficPolicyInstanceInput) SetTrafficPolicyId(v string) *CreateTrafficPolicyInstanceInput { + s.TrafficPolicyId = &v + return s +} + +// SetTrafficPolicyVersion sets the TrafficPolicyVersion field's value. +func (s *CreateTrafficPolicyInstanceInput) SetTrafficPolicyVersion(v int64) *CreateTrafficPolicyInstanceInput { + s.TrafficPolicyVersion = &v + return s +} + +// A complex type that contains the response information for the CreateTrafficPolicyInstance +// request. +type CreateTrafficPolicyInstanceOutput struct { + _ struct{} `type:"structure"` + + // A unique URL that represents a new traffic policy instance. + // + // Location is a required field + Location *string `location:"header" locationName:"Location" type:"string" required:"true"` + + // A complex type that contains settings for the new traffic policy instance. + // + // TrafficPolicyInstance is a required field + TrafficPolicyInstance *TrafficPolicyInstance `type:"structure" required:"true"` +} + +// String returns the string representation +func (s CreateTrafficPolicyInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTrafficPolicyInstanceOutput) GoString() string { + return s.String() +} + +// SetLocation sets the Location field's value. +func (s *CreateTrafficPolicyInstanceOutput) SetLocation(v string) *CreateTrafficPolicyInstanceOutput { + s.Location = &v + return s +} + +// SetTrafficPolicyInstance sets the TrafficPolicyInstance field's value. +func (s *CreateTrafficPolicyInstanceOutput) SetTrafficPolicyInstance(v *TrafficPolicyInstance) *CreateTrafficPolicyInstanceOutput { + s.TrafficPolicyInstance = v + return s +} + +// A complex type that contains the response information for the CreateTrafficPolicy +// request. +type CreateTrafficPolicyOutput struct { + _ struct{} `type:"structure"` + + // A unique URL that represents a new traffic policy. + // + // Location is a required field + Location *string `location:"header" locationName:"Location" type:"string" required:"true"` + + // A complex type that contains settings for the new traffic policy. + // + // TrafficPolicy is a required field + TrafficPolicy *TrafficPolicy `type:"structure" required:"true"` +} + +// String returns the string representation +func (s CreateTrafficPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTrafficPolicyOutput) GoString() string { + return s.String() +} + +// SetLocation sets the Location field's value. +func (s *CreateTrafficPolicyOutput) SetLocation(v string) *CreateTrafficPolicyOutput { + s.Location = &v + return s +} + +// SetTrafficPolicy sets the TrafficPolicy field's value. +func (s *CreateTrafficPolicyOutput) SetTrafficPolicy(v *TrafficPolicy) *CreateTrafficPolicyOutput { + s.TrafficPolicy = v + return s +} + +// A complex type that contains information about the traffic policy that you +// want to create a new version for. +type CreateTrafficPolicyVersionInput struct { + _ struct{} `locationName:"CreateTrafficPolicyVersionRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // The comment that you specified in the CreateTrafficPolicyVersion request, + // if any. + Comment *string `type:"string"` + + // The definition of this version of the traffic policy, in JSON format. You + // specified the JSON in the CreateTrafficPolicyVersion request. For more information + // about the JSON format, see CreateTrafficPolicy (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateTrafficPolicy.html). + // + // Document is a required field + Document *string `type:"string" required:"true"` + + // The ID of the traffic policy for which you want to create a new version. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateTrafficPolicyVersionInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTrafficPolicyVersionInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateTrafficPolicyVersionInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateTrafficPolicyVersionInput"} + if s.Document == nil { + invalidParams.Add(request.NewErrParamRequired("Document")) + } + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetComment sets the Comment field's value. +func (s *CreateTrafficPolicyVersionInput) SetComment(v string) *CreateTrafficPolicyVersionInput { + s.Comment = &v + return s +} + +// SetDocument sets the Document field's value. +func (s *CreateTrafficPolicyVersionInput) SetDocument(v string) *CreateTrafficPolicyVersionInput { + s.Document = &v + return s +} + +// SetId sets the Id field's value. +func (s *CreateTrafficPolicyVersionInput) SetId(v string) *CreateTrafficPolicyVersionInput { + s.Id = &v + return s +} + +// A complex type that contains the response information for the CreateTrafficPolicyVersion +// request. +type CreateTrafficPolicyVersionOutput struct { + _ struct{} `type:"structure"` + + // A unique URL that represents a new traffic policy version. + // + // Location is a required field + Location *string `location:"header" locationName:"Location" type:"string" required:"true"` + + // A complex type that contains settings for the new version of the traffic + // policy. + // + // TrafficPolicy is a required field + TrafficPolicy *TrafficPolicy `type:"structure" required:"true"` +} + +// String returns the string representation +func (s CreateTrafficPolicyVersionOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateTrafficPolicyVersionOutput) GoString() string { + return s.String() +} + +// SetLocation sets the Location field's value. +func (s *CreateTrafficPolicyVersionOutput) SetLocation(v string) *CreateTrafficPolicyVersionOutput { + s.Location = &v + return s +} + +// SetTrafficPolicy sets the TrafficPolicy field's value. +func (s *CreateTrafficPolicyVersionOutput) SetTrafficPolicy(v *TrafficPolicy) *CreateTrafficPolicyVersionOutput { + s.TrafficPolicy = v + return s +} + +// A complex type that contains information about the request to authorize associating +// a VPC with your private hosted zone. Authorization is only required when +// a private hosted zone and a VPC were created by using different accounts. +type CreateVPCAssociationAuthorizationInput struct { + _ struct{} `locationName:"CreateVPCAssociationAuthorizationRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // The ID of the private hosted zone that you want to authorize associating + // a VPC with. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` + + // A complex type that contains the VPC ID and region for the VPC that you want + // to authorize associating with your hosted zone. + // + // VPC is a required field + VPC *VPC `type:"structure" required:"true"` +} + +// String returns the string representation +func (s CreateVPCAssociationAuthorizationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVPCAssociationAuthorizationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateVPCAssociationAuthorizationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateVPCAssociationAuthorizationInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.HostedZoneId != nil && len(*s.HostedZoneId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HostedZoneId", 1)) + } + if s.VPC == nil { + invalidParams.Add(request.NewErrParamRequired("VPC")) + } + if s.VPC != nil { + if err := s.VPC.Validate(); err != nil { + invalidParams.AddNested("VPC", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *CreateVPCAssociationAuthorizationInput) SetHostedZoneId(v string) *CreateVPCAssociationAuthorizationInput { + s.HostedZoneId = &v + return s +} + +// SetVPC sets the VPC field's value. +func (s *CreateVPCAssociationAuthorizationInput) SetVPC(v *VPC) *CreateVPCAssociationAuthorizationInput { + s.VPC = v + return s +} + +// A complex type that contains the response information from a CreateVPCAssociationAuthorization +// request. +type CreateVPCAssociationAuthorizationOutput struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone that you authorized associating a VPC with. + // + // HostedZoneId is a required field + HostedZoneId *string `type:"string" required:"true"` + + // The VPC that you authorized associating with a hosted zone. + // + // VPC is a required field + VPC *VPC `type:"structure" required:"true"` +} + +// String returns the string representation +func (s CreateVPCAssociationAuthorizationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateVPCAssociationAuthorizationOutput) GoString() string { + return s.String() +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *CreateVPCAssociationAuthorizationOutput) SetHostedZoneId(v string) *CreateVPCAssociationAuthorizationOutput { + s.HostedZoneId = &v + return s +} + +// SetVPC sets the VPC field's value. +func (s *CreateVPCAssociationAuthorizationOutput) SetVPC(v *VPC) *CreateVPCAssociationAuthorizationOutput { + s.VPC = v + return s +} + +// A complex type that lists the name servers in a delegation set, as well as +// the CallerReference and the ID for the delegation set. +type DelegationSet struct { + _ struct{} `type:"structure"` + + // The value that you specified for CallerReference when you created the reusable + // delegation set. + CallerReference *string `min:"1" type:"string"` + + // The ID that Amazon Route 53 assigns to a reusable delegation set. + Id *string `type:"string"` + + // A complex type that contains a list of the authoritative name servers for + // a hosted zone or for a reusable delegation set. + // + // NameServers is a required field + NameServers []*string `locationNameList:"NameServer" min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s DelegationSet) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DelegationSet) GoString() string { + return s.String() +} + +// SetCallerReference sets the CallerReference field's value. +func (s *DelegationSet) SetCallerReference(v string) *DelegationSet { + s.CallerReference = &v + return s +} + +// SetId sets the Id field's value. +func (s *DelegationSet) SetId(v string) *DelegationSet { + s.Id = &v + return s +} + +// SetNameServers sets the NameServers field's value. +func (s *DelegationSet) SetNameServers(v []*string) *DelegationSet { + s.NameServers = v + return s +} + +// This action deletes a health check. +type DeleteHealthCheckInput struct { + _ struct{} `type:"structure"` + + // The ID of the health check that you want to delete. + // + // HealthCheckId is a required field + HealthCheckId *string `location:"uri" locationName:"HealthCheckId" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteHealthCheckInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteHealthCheckInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteHealthCheckInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteHealthCheckInput"} + if s.HealthCheckId == nil { + invalidParams.Add(request.NewErrParamRequired("HealthCheckId")) + } + if s.HealthCheckId != nil && len(*s.HealthCheckId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HealthCheckId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHealthCheckId sets the HealthCheckId field's value. +func (s *DeleteHealthCheckInput) SetHealthCheckId(v string) *DeleteHealthCheckInput { + s.HealthCheckId = &v + return s +} + +// An empty element. +type DeleteHealthCheckOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteHealthCheckOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteHealthCheckOutput) GoString() string { + return s.String() +} + +// A request to delete a hosted zone. +type DeleteHostedZoneInput struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone you want to delete. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteHostedZoneInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteHostedZoneInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteHostedZoneInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteHostedZoneInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *DeleteHostedZoneInput) SetId(v string) *DeleteHostedZoneInput { + s.Id = &v + return s +} + +// A complex type that contains the response to a DeleteHostedZone request. +type DeleteHostedZoneOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains the ID, the status, and the date and time of + // a request to delete a hosted zone. + // + // ChangeInfo is a required field + ChangeInfo *ChangeInfo `type:"structure" required:"true"` +} + +// String returns the string representation +func (s DeleteHostedZoneOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteHostedZoneOutput) GoString() string { + return s.String() +} + +// SetChangeInfo sets the ChangeInfo field's value. +func (s *DeleteHostedZoneOutput) SetChangeInfo(v *ChangeInfo) *DeleteHostedZoneOutput { + s.ChangeInfo = v + return s +} + +type DeleteQueryLoggingConfigInput struct { + _ struct{} `type:"structure"` + + // The ID of the configuration that you want to delete. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteQueryLoggingConfigInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteQueryLoggingConfigInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteQueryLoggingConfigInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteQueryLoggingConfigInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *DeleteQueryLoggingConfigInput) SetId(v string) *DeleteQueryLoggingConfigInput { + s.Id = &v + return s +} + +type DeleteQueryLoggingConfigOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteQueryLoggingConfigOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteQueryLoggingConfigOutput) GoString() string { + return s.String() +} + +// A request to delete a reusable delegation set. +type DeleteReusableDelegationSetInput struct { + _ struct{} `type:"structure"` + + // The ID of the reusable delegation set that you want to delete. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteReusableDelegationSetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteReusableDelegationSetInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteReusableDelegationSetInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteReusableDelegationSetInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *DeleteReusableDelegationSetInput) SetId(v string) *DeleteReusableDelegationSetInput { + s.Id = &v + return s +} + +// An empty element. +type DeleteReusableDelegationSetOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteReusableDelegationSetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteReusableDelegationSetOutput) GoString() string { + return s.String() +} + +// A request to delete a specified traffic policy version. +type DeleteTrafficPolicyInput struct { + _ struct{} `type:"structure"` + + // The ID of the traffic policy that you want to delete. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` + + // The version number of the traffic policy that you want to delete. + // + // Version is a required field + Version *int64 `location:"uri" locationName:"Version" min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s DeleteTrafficPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTrafficPolicyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteTrafficPolicyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteTrafficPolicyInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + if s.Version == nil { + invalidParams.Add(request.NewErrParamRequired("Version")) + } + if s.Version != nil && *s.Version < 1 { + invalidParams.Add(request.NewErrParamMinValue("Version", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *DeleteTrafficPolicyInput) SetId(v string) *DeleteTrafficPolicyInput { + s.Id = &v + return s +} + +// SetVersion sets the Version field's value. +func (s *DeleteTrafficPolicyInput) SetVersion(v int64) *DeleteTrafficPolicyInput { + s.Version = &v + return s +} + +// A request to delete a specified traffic policy instance. +type DeleteTrafficPolicyInstanceInput struct { + _ struct{} `type:"structure"` + + // The ID of the traffic policy instance that you want to delete. + // + // When you delete a traffic policy instance, Amazon Route 53 also deletes all + // of the resource record sets that were created when you created the traffic + // policy instance. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DeleteTrafficPolicyInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTrafficPolicyInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteTrafficPolicyInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteTrafficPolicyInstanceInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *DeleteTrafficPolicyInstanceInput) SetId(v string) *DeleteTrafficPolicyInstanceInput { + s.Id = &v + return s +} + +// An empty element. +type DeleteTrafficPolicyInstanceOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteTrafficPolicyInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTrafficPolicyInstanceOutput) GoString() string { + return s.String() +} + +// An empty element. +type DeleteTrafficPolicyOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteTrafficPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteTrafficPolicyOutput) GoString() string { + return s.String() +} + +// A complex type that contains information about the request to remove authorization +// to associate a VPC that was created by one AWS account with a hosted zone +// that was created with a different AWS account. +type DeleteVPCAssociationAuthorizationInput struct { + _ struct{} `locationName:"DeleteVPCAssociationAuthorizationRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // When removing authorization to associate a VPC that was created by one AWS + // account with a hosted zone that was created with a different AWS account, + // the ID of the hosted zone. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` + + // When removing authorization to associate a VPC that was created by one AWS + // account with a hosted zone that was created with a different AWS account, + // a complex type that includes the ID and region of the VPC. + // + // VPC is a required field + VPC *VPC `type:"structure" required:"true"` +} + +// String returns the string representation +func (s DeleteVPCAssociationAuthorizationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVPCAssociationAuthorizationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteVPCAssociationAuthorizationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteVPCAssociationAuthorizationInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.HostedZoneId != nil && len(*s.HostedZoneId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HostedZoneId", 1)) + } + if s.VPC == nil { + invalidParams.Add(request.NewErrParamRequired("VPC")) + } + if s.VPC != nil { + if err := s.VPC.Validate(); err != nil { + invalidParams.AddNested("VPC", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *DeleteVPCAssociationAuthorizationInput) SetHostedZoneId(v string) *DeleteVPCAssociationAuthorizationInput { + s.HostedZoneId = &v + return s +} + +// SetVPC sets the VPC field's value. +func (s *DeleteVPCAssociationAuthorizationInput) SetVPC(v *VPC) *DeleteVPCAssociationAuthorizationInput { + s.VPC = v + return s +} + +// Empty response for the request. +type DeleteVPCAssociationAuthorizationOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteVPCAssociationAuthorizationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteVPCAssociationAuthorizationOutput) GoString() string { + return s.String() +} + +// For the metric that the CloudWatch alarm is associated with, a complex type +// that contains information about one dimension. +type Dimension struct { + _ struct{} `type:"structure"` + + // For the metric that the CloudWatch alarm is associated with, the name of + // one dimension. + // + // Name is a required field + Name *string `min:"1" type:"string" required:"true"` + + // For the metric that the CloudWatch alarm is associated with, the value of + // one dimension. + // + // Value is a required field + Value *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s Dimension) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Dimension) GoString() string { + return s.String() +} + +// SetName sets the Name field's value. +func (s *Dimension) SetName(v string) *Dimension { + s.Name = &v + return s +} + +// SetValue sets the Value field's value. +func (s *Dimension) SetValue(v string) *Dimension { + s.Value = &v + return s +} + +// A complex type that contains information about the VPC that you want to disassociate +// from a specified private hosted zone. +type DisassociateVPCFromHostedZoneInput struct { + _ struct{} `locationName:"DisassociateVPCFromHostedZoneRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // Optional: A comment about the disassociation request. + Comment *string `type:"string"` + + // The ID of the private hosted zone that you want to disassociate a VPC from. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` + + // A complex type that contains information about the VPC that you're disassociating + // from the specified hosted zone. + // + // VPC is a required field + VPC *VPC `type:"structure" required:"true"` +} + +// String returns the string representation +func (s DisassociateVPCFromHostedZoneInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateVPCFromHostedZoneInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DisassociateVPCFromHostedZoneInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DisassociateVPCFromHostedZoneInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.HostedZoneId != nil && len(*s.HostedZoneId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HostedZoneId", 1)) + } + if s.VPC == nil { + invalidParams.Add(request.NewErrParamRequired("VPC")) + } + if s.VPC != nil { + if err := s.VPC.Validate(); err != nil { + invalidParams.AddNested("VPC", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetComment sets the Comment field's value. +func (s *DisassociateVPCFromHostedZoneInput) SetComment(v string) *DisassociateVPCFromHostedZoneInput { + s.Comment = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *DisassociateVPCFromHostedZoneInput) SetHostedZoneId(v string) *DisassociateVPCFromHostedZoneInput { + s.HostedZoneId = &v + return s +} + +// SetVPC sets the VPC field's value. +func (s *DisassociateVPCFromHostedZoneInput) SetVPC(v *VPC) *DisassociateVPCFromHostedZoneInput { + s.VPC = v + return s +} + +// A complex type that contains the response information for the disassociate +// request. +type DisassociateVPCFromHostedZoneOutput struct { + _ struct{} `type:"structure"` + + // A complex type that describes the changes made to the specified private hosted + // zone. + // + // ChangeInfo is a required field + ChangeInfo *ChangeInfo `type:"structure" required:"true"` +} + +// String returns the string representation +func (s DisassociateVPCFromHostedZoneOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DisassociateVPCFromHostedZoneOutput) GoString() string { + return s.String() +} + +// SetChangeInfo sets the ChangeInfo field's value. +func (s *DisassociateVPCFromHostedZoneOutput) SetChangeInfo(v *ChangeInfo) *DisassociateVPCFromHostedZoneOutput { + s.ChangeInfo = v + return s +} + +// A complex type that contains information about a geographic location. +type GeoLocation struct { + _ struct{} `type:"structure"` + + // The two-letter code for the continent. + // + // Valid values: AF | AN | AS | EU | OC | NA | SA + // + // Constraint: Specifying ContinentCode with either CountryCode or SubdivisionCode + // returns an InvalidInput error. + ContinentCode *string `min:"2" type:"string"` + + // The two-letter code for the country. + CountryCode *string `min:"1" type:"string"` + + // The code for the subdivision. Route 53 currently supports only states in + // the United States. + SubdivisionCode *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s GeoLocation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GeoLocation) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GeoLocation) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GeoLocation"} + if s.ContinentCode != nil && len(*s.ContinentCode) < 2 { + invalidParams.Add(request.NewErrParamMinLen("ContinentCode", 2)) + } + if s.CountryCode != nil && len(*s.CountryCode) < 1 { + invalidParams.Add(request.NewErrParamMinLen("CountryCode", 1)) + } + if s.SubdivisionCode != nil && len(*s.SubdivisionCode) < 1 { + invalidParams.Add(request.NewErrParamMinLen("SubdivisionCode", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetContinentCode sets the ContinentCode field's value. +func (s *GeoLocation) SetContinentCode(v string) *GeoLocation { + s.ContinentCode = &v + return s +} + +// SetCountryCode sets the CountryCode field's value. +func (s *GeoLocation) SetCountryCode(v string) *GeoLocation { + s.CountryCode = &v + return s +} + +// SetSubdivisionCode sets the SubdivisionCode field's value. +func (s *GeoLocation) SetSubdivisionCode(v string) *GeoLocation { + s.SubdivisionCode = &v + return s +} + +// A complex type that contains the codes and full continent, country, and subdivision +// names for the specified geolocation code. +type GeoLocationDetails struct { + _ struct{} `type:"structure"` + + // The two-letter code for the continent. + ContinentCode *string `min:"2" type:"string"` + + // The full name of the continent. + ContinentName *string `min:"1" type:"string"` + + // The two-letter code for the country. + CountryCode *string `min:"1" type:"string"` + + // The name of the country. + CountryName *string `min:"1" type:"string"` + + // The code for the subdivision. Route 53 currently supports only states in + // the United States. + SubdivisionCode *string `min:"1" type:"string"` + + // The full name of the subdivision. Route 53 currently supports only states + // in the United States. + SubdivisionName *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s GeoLocationDetails) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GeoLocationDetails) GoString() string { + return s.String() +} + +// SetContinentCode sets the ContinentCode field's value. +func (s *GeoLocationDetails) SetContinentCode(v string) *GeoLocationDetails { + s.ContinentCode = &v + return s +} + +// SetContinentName sets the ContinentName field's value. +func (s *GeoLocationDetails) SetContinentName(v string) *GeoLocationDetails { + s.ContinentName = &v + return s +} + +// SetCountryCode sets the CountryCode field's value. +func (s *GeoLocationDetails) SetCountryCode(v string) *GeoLocationDetails { + s.CountryCode = &v + return s +} + +// SetCountryName sets the CountryName field's value. +func (s *GeoLocationDetails) SetCountryName(v string) *GeoLocationDetails { + s.CountryName = &v + return s +} + +// SetSubdivisionCode sets the SubdivisionCode field's value. +func (s *GeoLocationDetails) SetSubdivisionCode(v string) *GeoLocationDetails { + s.SubdivisionCode = &v + return s +} + +// SetSubdivisionName sets the SubdivisionName field's value. +func (s *GeoLocationDetails) SetSubdivisionName(v string) *GeoLocationDetails { + s.SubdivisionName = &v + return s +} + +// A complex type that contains information about the request to create a hosted +// zone. +type GetAccountLimitInput struct { + _ struct{} `type:"structure"` + + // The limit that you want to get. Valid values include the following: + // + // * MAX_HEALTH_CHECKS_BY_OWNER: The maximum number of health checks that + // you can create using the current account. + // + // * MAX_HOSTED_ZONES_BY_OWNER: The maximum number of hosted zones that you + // can create using the current account. + // + // * MAX_REUSABLE_DELEGATION_SETS_BY_OWNER: The maximum number of reusable + // delegation sets that you can create using the current account. + // + // * MAX_TRAFFIC_POLICIES_BY_OWNER: The maximum number of traffic policies + // that you can create using the current account. + // + // * MAX_TRAFFIC_POLICY_INSTANCES_BY_OWNER: The maximum number of traffic + // policy instances that you can create using the current account. (Traffic + // policy instances are referred to as traffic flow policy records in the + // Amazon Route 53 console.) + // + // Type is a required field + Type *string `location:"uri" locationName:"Type" type:"string" required:"true" enum:"AccountLimitType"` +} + +// String returns the string representation +func (s GetAccountLimitInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetAccountLimitInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetAccountLimitInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetAccountLimitInput"} + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + if s.Type != nil && len(*s.Type) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Type", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetType sets the Type field's value. +func (s *GetAccountLimitInput) SetType(v string) *GetAccountLimitInput { + s.Type = &v + return s +} + +// A complex type that contains the requested limit. +type GetAccountLimitOutput struct { + _ struct{} `type:"structure"` + + // The current number of entities that you have created of the specified type. + // For example, if you specified MAX_HEALTH_CHECKS_BY_OWNER for the value of + // Type in the request, the value of Count is the current number of health checks + // that you have created using the current account. + // + // Count is a required field + Count *int64 `type:"long" required:"true"` + + // The current setting for the specified limit. For example, if you specified + // MAX_HEALTH_CHECKS_BY_OWNER for the value of Type in the request, the value + // of Limit is the maximum number of health checks that you can create using + // the current account. + // + // Limit is a required field + Limit *AccountLimit `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetAccountLimitOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetAccountLimitOutput) GoString() string { + return s.String() +} + +// SetCount sets the Count field's value. +func (s *GetAccountLimitOutput) SetCount(v int64) *GetAccountLimitOutput { + s.Count = &v + return s +} + +// SetLimit sets the Limit field's value. +func (s *GetAccountLimitOutput) SetLimit(v *AccountLimit) *GetAccountLimitOutput { + s.Limit = v + return s +} + +// The input for a GetChange request. +type GetChangeInput struct { + _ struct{} `type:"structure"` + + // The ID of the change batch request. The value that you specify here is the + // value that ChangeResourceRecordSets returned in the Id element when you submitted + // the request. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetChangeInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetChangeInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetChangeInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetChangeInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *GetChangeInput) SetId(v string) *GetChangeInput { + s.Id = &v + return s +} + +// A complex type that contains the ChangeInfo element. +type GetChangeOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains information about the specified change batch. + // + // ChangeInfo is a required field + ChangeInfo *ChangeInfo `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetChangeOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetChangeOutput) GoString() string { + return s.String() +} + +// SetChangeInfo sets the ChangeInfo field's value. +func (s *GetChangeOutput) SetChangeInfo(v *ChangeInfo) *GetChangeOutput { + s.ChangeInfo = v + return s +} + +// Empty request. +type GetCheckerIpRangesInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetCheckerIpRangesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCheckerIpRangesInput) GoString() string { + return s.String() +} + +// A complex type that contains the CheckerIpRanges element. +type GetCheckerIpRangesOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains sorted list of IP ranges in CIDR format for + // Amazon Route 53 health checkers. + // + // CheckerIpRanges is a required field + CheckerIpRanges []*string `type:"list" required:"true"` +} + +// String returns the string representation +func (s GetCheckerIpRangesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCheckerIpRangesOutput) GoString() string { + return s.String() +} + +// SetCheckerIpRanges sets the CheckerIpRanges field's value. +func (s *GetCheckerIpRangesOutput) SetCheckerIpRanges(v []*string) *GetCheckerIpRangesOutput { + s.CheckerIpRanges = v + return s +} + +// A request for information about whether a specified geographic location is +// supported for Amazon Route 53 geolocation resource record sets. +type GetGeoLocationInput struct { + _ struct{} `type:"structure"` + + // Amazon Route 53 supports the following continent codes: + // + // * AF: Africa + // + // * AN: Antarctica + // + // * AS: Asia + // + // * EU: Europe + // + // * OC: Oceania + // + // * NA: North America + // + // * SA: South America + ContinentCode *string `location:"querystring" locationName:"continentcode" min:"2" type:"string"` + + // Amazon Route 53 uses the two-letter country codes that are specified in ISO + // standard 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). + CountryCode *string `location:"querystring" locationName:"countrycode" min:"1" type:"string"` + + // Amazon Route 53 uses the one- to three-letter subdivision codes that are + // specified in ISO standard 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). + // Route 53 doesn't support subdivision codes for all countries. If you specify + // subdivisioncode, you must also specify countrycode. + SubdivisionCode *string `location:"querystring" locationName:"subdivisioncode" min:"1" type:"string"` +} + +// String returns the string representation +func (s GetGeoLocationInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetGeoLocationInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetGeoLocationInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetGeoLocationInput"} + if s.ContinentCode != nil && len(*s.ContinentCode) < 2 { + invalidParams.Add(request.NewErrParamMinLen("ContinentCode", 2)) + } + if s.CountryCode != nil && len(*s.CountryCode) < 1 { + invalidParams.Add(request.NewErrParamMinLen("CountryCode", 1)) + } + if s.SubdivisionCode != nil && len(*s.SubdivisionCode) < 1 { + invalidParams.Add(request.NewErrParamMinLen("SubdivisionCode", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetContinentCode sets the ContinentCode field's value. +func (s *GetGeoLocationInput) SetContinentCode(v string) *GetGeoLocationInput { + s.ContinentCode = &v + return s +} + +// SetCountryCode sets the CountryCode field's value. +func (s *GetGeoLocationInput) SetCountryCode(v string) *GetGeoLocationInput { + s.CountryCode = &v + return s +} + +// SetSubdivisionCode sets the SubdivisionCode field's value. +func (s *GetGeoLocationInput) SetSubdivisionCode(v string) *GetGeoLocationInput { + s.SubdivisionCode = &v + return s +} + +// A complex type that contains the response information for the specified geolocation +// code. +type GetGeoLocationOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains the codes and full continent, country, and subdivision + // names for the specified geolocation code. + // + // GeoLocationDetails is a required field + GeoLocationDetails *GeoLocationDetails `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetGeoLocationOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetGeoLocationOutput) GoString() string { + return s.String() +} + +// SetGeoLocationDetails sets the GeoLocationDetails field's value. +func (s *GetGeoLocationOutput) SetGeoLocationDetails(v *GeoLocationDetails) *GetGeoLocationOutput { + s.GeoLocationDetails = v + return s +} + +// A request for the number of health checks that are associated with the current +// AWS account. +type GetHealthCheckCountInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetHealthCheckCountInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHealthCheckCountInput) GoString() string { + return s.String() +} + +// A complex type that contains the response to a GetHealthCheckCount request. +type GetHealthCheckCountOutput struct { + _ struct{} `type:"structure"` + + // The number of health checks associated with the current AWS account. + // + // HealthCheckCount is a required field + HealthCheckCount *int64 `type:"long" required:"true"` +} + +// String returns the string representation +func (s GetHealthCheckCountOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHealthCheckCountOutput) GoString() string { + return s.String() +} + +// SetHealthCheckCount sets the HealthCheckCount field's value. +func (s *GetHealthCheckCountOutput) SetHealthCheckCount(v int64) *GetHealthCheckCountOutput { + s.HealthCheckCount = &v + return s +} + +// A request to get information about a specified health check. +type GetHealthCheckInput struct { + _ struct{} `type:"structure"` + + // The identifier that Amazon Route 53 assigned to the health check when you + // created it. When you add or update a resource record set, you use this value + // to specify which health check to use. The value can be up to 64 characters + // long. + // + // HealthCheckId is a required field + HealthCheckId *string `location:"uri" locationName:"HealthCheckId" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetHealthCheckInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHealthCheckInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetHealthCheckInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetHealthCheckInput"} + if s.HealthCheckId == nil { + invalidParams.Add(request.NewErrParamRequired("HealthCheckId")) + } + if s.HealthCheckId != nil && len(*s.HealthCheckId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HealthCheckId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHealthCheckId sets the HealthCheckId field's value. +func (s *GetHealthCheckInput) SetHealthCheckId(v string) *GetHealthCheckInput { + s.HealthCheckId = &v + return s +} + +// A request for the reason that a health check failed most recently. +type GetHealthCheckLastFailureReasonInput struct { + _ struct{} `type:"structure"` + + // The ID for the health check for which you want the last failure reason. When + // you created the health check, CreateHealthCheck returned the ID in the response, + // in the HealthCheckId element. + // + // If you want to get the last failure reason for a calculated health check, + // you must use the Amazon Route 53 console or the CloudWatch console. You can't + // use GetHealthCheckLastFailureReason for a calculated health check. + // + // HealthCheckId is a required field + HealthCheckId *string `location:"uri" locationName:"HealthCheckId" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetHealthCheckLastFailureReasonInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHealthCheckLastFailureReasonInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetHealthCheckLastFailureReasonInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetHealthCheckLastFailureReasonInput"} + if s.HealthCheckId == nil { + invalidParams.Add(request.NewErrParamRequired("HealthCheckId")) + } + if s.HealthCheckId != nil && len(*s.HealthCheckId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HealthCheckId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHealthCheckId sets the HealthCheckId field's value. +func (s *GetHealthCheckLastFailureReasonInput) SetHealthCheckId(v string) *GetHealthCheckLastFailureReasonInput { + s.HealthCheckId = &v + return s +} + +// A complex type that contains the response to a GetHealthCheckLastFailureReason +// request. +type GetHealthCheckLastFailureReasonOutput struct { + _ struct{} `type:"structure"` + + // A list that contains one Observation element for each Amazon Route 53 health + // checker that is reporting a last failure reason. + // + // HealthCheckObservations is a required field + HealthCheckObservations []*HealthCheckObservation `locationNameList:"HealthCheckObservation" type:"list" required:"true"` +} + +// String returns the string representation +func (s GetHealthCheckLastFailureReasonOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHealthCheckLastFailureReasonOutput) GoString() string { + return s.String() +} + +// SetHealthCheckObservations sets the HealthCheckObservations field's value. +func (s *GetHealthCheckLastFailureReasonOutput) SetHealthCheckObservations(v []*HealthCheckObservation) *GetHealthCheckLastFailureReasonOutput { + s.HealthCheckObservations = v + return s +} + +// A complex type that contains the response to a GetHealthCheck request. +type GetHealthCheckOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains information about one health check that is associated + // with the current AWS account. + // + // HealthCheck is a required field + HealthCheck *HealthCheck `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetHealthCheckOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHealthCheckOutput) GoString() string { + return s.String() +} + +// SetHealthCheck sets the HealthCheck field's value. +func (s *GetHealthCheckOutput) SetHealthCheck(v *HealthCheck) *GetHealthCheckOutput { + s.HealthCheck = v + return s +} + +// A request to get the status for a health check. +type GetHealthCheckStatusInput struct { + _ struct{} `type:"structure"` + + // The ID for the health check that you want the current status for. When you + // created the health check, CreateHealthCheck returned the ID in the response, + // in the HealthCheckId element. + // + // If you want to check the status of a calculated health check, you must use + // the Amazon Route 53 console or the CloudWatch console. You can't use GetHealthCheckStatus + // to get the status of a calculated health check. + // + // HealthCheckId is a required field + HealthCheckId *string `location:"uri" locationName:"HealthCheckId" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetHealthCheckStatusInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHealthCheckStatusInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetHealthCheckStatusInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetHealthCheckStatusInput"} + if s.HealthCheckId == nil { + invalidParams.Add(request.NewErrParamRequired("HealthCheckId")) + } + if s.HealthCheckId != nil && len(*s.HealthCheckId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HealthCheckId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHealthCheckId sets the HealthCheckId field's value. +func (s *GetHealthCheckStatusInput) SetHealthCheckId(v string) *GetHealthCheckStatusInput { + s.HealthCheckId = &v + return s +} + +// A complex type that contains the response to a GetHealthCheck request. +type GetHealthCheckStatusOutput struct { + _ struct{} `type:"structure"` + + // A list that contains one HealthCheckObservation element for each Amazon Route + // 53 health checker that is reporting a status about the health check endpoint. + // + // HealthCheckObservations is a required field + HealthCheckObservations []*HealthCheckObservation `locationNameList:"HealthCheckObservation" type:"list" required:"true"` +} + +// String returns the string representation +func (s GetHealthCheckStatusOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHealthCheckStatusOutput) GoString() string { + return s.String() +} + +// SetHealthCheckObservations sets the HealthCheckObservations field's value. +func (s *GetHealthCheckStatusOutput) SetHealthCheckObservations(v []*HealthCheckObservation) *GetHealthCheckStatusOutput { + s.HealthCheckObservations = v + return s +} + +// A request to retrieve a count of all the hosted zones that are associated +// with the current AWS account. +type GetHostedZoneCountInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetHostedZoneCountInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostedZoneCountInput) GoString() string { + return s.String() +} + +// A complex type that contains the response to a GetHostedZoneCount request. +type GetHostedZoneCountOutput struct { + _ struct{} `type:"structure"` + + // The total number of public and private hosted zones that are associated with + // the current AWS account. + // + // HostedZoneCount is a required field + HostedZoneCount *int64 `type:"long" required:"true"` +} + +// String returns the string representation +func (s GetHostedZoneCountOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostedZoneCountOutput) GoString() string { + return s.String() +} + +// SetHostedZoneCount sets the HostedZoneCount field's value. +func (s *GetHostedZoneCountOutput) SetHostedZoneCount(v int64) *GetHostedZoneCountOutput { + s.HostedZoneCount = &v + return s +} + +// A request to get information about a specified hosted zone. +type GetHostedZoneInput struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone that you want to get information about. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetHostedZoneInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostedZoneInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetHostedZoneInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetHostedZoneInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *GetHostedZoneInput) SetId(v string) *GetHostedZoneInput { + s.Id = &v + return s +} + +// A complex type that contains information about the request to create a hosted +// zone. +type GetHostedZoneLimitInput struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone that you want to get a limit for. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` + + // The limit that you want to get. Valid values include the following: + // + // * MAX_RRSETS_BY_ZONE: The maximum number of records that you can create + // in the specified hosted zone. + // + // * MAX_VPCS_ASSOCIATED_BY_ZONE: The maximum number of Amazon VPCs that + // you can associate with the specified private hosted zone. + // + // Type is a required field + Type *string `location:"uri" locationName:"Type" type:"string" required:"true" enum:"HostedZoneLimitType"` +} + +// String returns the string representation +func (s GetHostedZoneLimitInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostedZoneLimitInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetHostedZoneLimitInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetHostedZoneLimitInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.HostedZoneId != nil && len(*s.HostedZoneId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HostedZoneId", 1)) + } + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + if s.Type != nil && len(*s.Type) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Type", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *GetHostedZoneLimitInput) SetHostedZoneId(v string) *GetHostedZoneLimitInput { + s.HostedZoneId = &v + return s +} + +// SetType sets the Type field's value. +func (s *GetHostedZoneLimitInput) SetType(v string) *GetHostedZoneLimitInput { + s.Type = &v + return s +} + +// A complex type that contains the requested limit. +type GetHostedZoneLimitOutput struct { + _ struct{} `type:"structure"` + + // The current number of entities that you have created of the specified type. + // For example, if you specified MAX_RRSETS_BY_ZONE for the value of Type in + // the request, the value of Count is the current number of records that you + // have created in the specified hosted zone. + // + // Count is a required field + Count *int64 `type:"long" required:"true"` + + // The current setting for the specified limit. For example, if you specified + // MAX_RRSETS_BY_ZONE for the value of Type in the request, the value of Limit + // is the maximum number of records that you can create in the specified hosted + // zone. + // + // Limit is a required field + Limit *HostedZoneLimit `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetHostedZoneLimitOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostedZoneLimitOutput) GoString() string { + return s.String() +} + +// SetCount sets the Count field's value. +func (s *GetHostedZoneLimitOutput) SetCount(v int64) *GetHostedZoneLimitOutput { + s.Count = &v + return s +} + +// SetLimit sets the Limit field's value. +func (s *GetHostedZoneLimitOutput) SetLimit(v *HostedZoneLimit) *GetHostedZoneLimitOutput { + s.Limit = v + return s +} + +// A complex type that contain the response to a GetHostedZone request. +type GetHostedZoneOutput struct { + _ struct{} `type:"structure"` + + // A complex type that lists the Amazon Route 53 name servers for the specified + // hosted zone. + DelegationSet *DelegationSet `type:"structure"` + + // A complex type that contains general information about the specified hosted + // zone. + // + // HostedZone is a required field + HostedZone *HostedZone `type:"structure" required:"true"` + + // A complex type that contains information about the VPCs that are associated + // with the specified hosted zone. + VPCs []*VPC `locationNameList:"VPC" min:"1" type:"list"` +} + +// String returns the string representation +func (s GetHostedZoneOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetHostedZoneOutput) GoString() string { + return s.String() +} + +// SetDelegationSet sets the DelegationSet field's value. +func (s *GetHostedZoneOutput) SetDelegationSet(v *DelegationSet) *GetHostedZoneOutput { + s.DelegationSet = v + return s +} + +// SetHostedZone sets the HostedZone field's value. +func (s *GetHostedZoneOutput) SetHostedZone(v *HostedZone) *GetHostedZoneOutput { + s.HostedZone = v + return s +} + +// SetVPCs sets the VPCs field's value. +func (s *GetHostedZoneOutput) SetVPCs(v []*VPC) *GetHostedZoneOutput { + s.VPCs = v + return s +} + +type GetQueryLoggingConfigInput struct { + _ struct{} `type:"structure"` + + // The ID of the configuration for DNS query logging that you want to get information + // about. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetQueryLoggingConfigInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetQueryLoggingConfigInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetQueryLoggingConfigInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetQueryLoggingConfigInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *GetQueryLoggingConfigInput) SetId(v string) *GetQueryLoggingConfigInput { + s.Id = &v + return s +} + +type GetQueryLoggingConfigOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains information about the query logging configuration + // that you specified in a GetQueryLoggingConfig (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetQueryLoggingConfig.html) + // request. + // + // QueryLoggingConfig is a required field + QueryLoggingConfig *QueryLoggingConfig `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetQueryLoggingConfigOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetQueryLoggingConfigOutput) GoString() string { + return s.String() +} + +// SetQueryLoggingConfig sets the QueryLoggingConfig field's value. +func (s *GetQueryLoggingConfigOutput) SetQueryLoggingConfig(v *QueryLoggingConfig) *GetQueryLoggingConfigOutput { + s.QueryLoggingConfig = v + return s +} + +// A request to get information about a specified reusable delegation set. +type GetReusableDelegationSetInput struct { + _ struct{} `type:"structure"` + + // The ID of the reusable delegation set that you want to get a list of name + // servers for. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetReusableDelegationSetInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetReusableDelegationSetInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetReusableDelegationSetInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetReusableDelegationSetInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *GetReusableDelegationSetInput) SetId(v string) *GetReusableDelegationSetInput { + s.Id = &v + return s +} + +// A complex type that contains information about the request to create a hosted +// zone. +type GetReusableDelegationSetLimitInput struct { + _ struct{} `type:"structure"` + + // The ID of the delegation set that you want to get the limit for. + // + // DelegationSetId is a required field + DelegationSetId *string `location:"uri" locationName:"Id" type:"string" required:"true"` + + // Specify MAX_ZONES_BY_REUSABLE_DELEGATION_SET to get the maximum number of + // hosted zones that you can associate with the specified reusable delegation + // set. + // + // Type is a required field + Type *string `location:"uri" locationName:"Type" type:"string" required:"true" enum:"ReusableDelegationSetLimitType"` +} + +// String returns the string representation +func (s GetReusableDelegationSetLimitInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetReusableDelegationSetLimitInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetReusableDelegationSetLimitInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetReusableDelegationSetLimitInput"} + if s.DelegationSetId == nil { + invalidParams.Add(request.NewErrParamRequired("DelegationSetId")) + } + if s.DelegationSetId != nil && len(*s.DelegationSetId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("DelegationSetId", 1)) + } + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + if s.Type != nil && len(*s.Type) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Type", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDelegationSetId sets the DelegationSetId field's value. +func (s *GetReusableDelegationSetLimitInput) SetDelegationSetId(v string) *GetReusableDelegationSetLimitInput { + s.DelegationSetId = &v + return s +} + +// SetType sets the Type field's value. +func (s *GetReusableDelegationSetLimitInput) SetType(v string) *GetReusableDelegationSetLimitInput { + s.Type = &v + return s +} + +// A complex type that contains the requested limit. +type GetReusableDelegationSetLimitOutput struct { + _ struct{} `type:"structure"` + + // The current number of hosted zones that you can associate with the specified + // reusable delegation set. + // + // Count is a required field + Count *int64 `type:"long" required:"true"` + + // The current setting for the limit on hosted zones that you can associate + // with the specified reusable delegation set. + // + // Limit is a required field + Limit *ReusableDelegationSetLimit `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetReusableDelegationSetLimitOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetReusableDelegationSetLimitOutput) GoString() string { + return s.String() +} + +// SetCount sets the Count field's value. +func (s *GetReusableDelegationSetLimitOutput) SetCount(v int64) *GetReusableDelegationSetLimitOutput { + s.Count = &v + return s +} + +// SetLimit sets the Limit field's value. +func (s *GetReusableDelegationSetLimitOutput) SetLimit(v *ReusableDelegationSetLimit) *GetReusableDelegationSetLimitOutput { + s.Limit = v + return s +} + +// A complex type that contains the response to the GetReusableDelegationSet +// request. +type GetReusableDelegationSetOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains information about the reusable delegation set. + // + // DelegationSet is a required field + DelegationSet *DelegationSet `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetReusableDelegationSetOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetReusableDelegationSetOutput) GoString() string { + return s.String() +} + +// SetDelegationSet sets the DelegationSet field's value. +func (s *GetReusableDelegationSetOutput) SetDelegationSet(v *DelegationSet) *GetReusableDelegationSetOutput { + s.DelegationSet = v + return s +} + +// Gets information about a specific traffic policy version. +type GetTrafficPolicyInput struct { + _ struct{} `type:"structure"` + + // The ID of the traffic policy that you want to get information about. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` + + // The version number of the traffic policy that you want to get information + // about. + // + // Version is a required field + Version *int64 `location:"uri" locationName:"Version" min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s GetTrafficPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTrafficPolicyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetTrafficPolicyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetTrafficPolicyInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + if s.Version == nil { + invalidParams.Add(request.NewErrParamRequired("Version")) + } + if s.Version != nil && *s.Version < 1 { + invalidParams.Add(request.NewErrParamMinValue("Version", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *GetTrafficPolicyInput) SetId(v string) *GetTrafficPolicyInput { + s.Id = &v + return s +} + +// SetVersion sets the Version field's value. +func (s *GetTrafficPolicyInput) SetVersion(v int64) *GetTrafficPolicyInput { + s.Version = &v + return s +} + +// Request to get the number of traffic policy instances that are associated +// with the current AWS account. +type GetTrafficPolicyInstanceCountInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetTrafficPolicyInstanceCountInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTrafficPolicyInstanceCountInput) GoString() string { + return s.String() +} + +// A complex type that contains information about the resource record sets that +// Amazon Route 53 created based on a specified traffic policy. +type GetTrafficPolicyInstanceCountOutput struct { + _ struct{} `type:"structure"` + + // The number of traffic policy instances that are associated with the current + // AWS account. + // + // TrafficPolicyInstanceCount is a required field + TrafficPolicyInstanceCount *int64 `type:"integer" required:"true"` +} + +// String returns the string representation +func (s GetTrafficPolicyInstanceCountOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTrafficPolicyInstanceCountOutput) GoString() string { + return s.String() +} + +// SetTrafficPolicyInstanceCount sets the TrafficPolicyInstanceCount field's value. +func (s *GetTrafficPolicyInstanceCountOutput) SetTrafficPolicyInstanceCount(v int64) *GetTrafficPolicyInstanceCountOutput { + s.TrafficPolicyInstanceCount = &v + return s +} + +// Gets information about a specified traffic policy instance. +type GetTrafficPolicyInstanceInput struct { + _ struct{} `type:"structure"` + + // The ID of the traffic policy instance that you want to get information about. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetTrafficPolicyInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTrafficPolicyInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetTrafficPolicyInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetTrafficPolicyInstanceInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *GetTrafficPolicyInstanceInput) SetId(v string) *GetTrafficPolicyInstanceInput { + s.Id = &v + return s +} + +// A complex type that contains information about the resource record sets that +// Amazon Route 53 created based on a specified traffic policy. +type GetTrafficPolicyInstanceOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains settings for the traffic policy instance. + // + // TrafficPolicyInstance is a required field + TrafficPolicyInstance *TrafficPolicyInstance `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetTrafficPolicyInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTrafficPolicyInstanceOutput) GoString() string { + return s.String() +} + +// SetTrafficPolicyInstance sets the TrafficPolicyInstance field's value. +func (s *GetTrafficPolicyInstanceOutput) SetTrafficPolicyInstance(v *TrafficPolicyInstance) *GetTrafficPolicyInstanceOutput { + s.TrafficPolicyInstance = v + return s +} + +// A complex type that contains the response information for the request. +type GetTrafficPolicyOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains settings for the specified traffic policy. + // + // TrafficPolicy is a required field + TrafficPolicy *TrafficPolicy `type:"structure" required:"true"` +} + +// String returns the string representation +func (s GetTrafficPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTrafficPolicyOutput) GoString() string { + return s.String() +} + +// SetTrafficPolicy sets the TrafficPolicy field's value. +func (s *GetTrafficPolicyOutput) SetTrafficPolicy(v *TrafficPolicy) *GetTrafficPolicyOutput { + s.TrafficPolicy = v + return s +} + +// A complex type that contains information about one health check that is associated +// with the current AWS account. +type HealthCheck struct { + _ struct{} `type:"structure"` + + // A unique string that you specified when you created the health check. + // + // CallerReference is a required field + CallerReference *string `min:"1" type:"string" required:"true"` + + // A complex type that contains information about the CloudWatch alarm that + // Amazon Route 53 is monitoring for this health check. + CloudWatchAlarmConfiguration *CloudWatchAlarmConfiguration `type:"structure"` + + // A complex type that contains detailed information about one health check. + // + // HealthCheckConfig is a required field + HealthCheckConfig *HealthCheckConfig `type:"structure" required:"true"` + + // The version of the health check. You can optionally pass this value in a + // call to UpdateHealthCheck to prevent overwriting another change to the health + // check. + // + // HealthCheckVersion is a required field + HealthCheckVersion *int64 `min:"1" type:"long" required:"true"` + + // The identifier that Amazon Route 53assigned to the health check when you + // created it. When you add or update a resource record set, you use this value + // to specify which health check to use. The value can be up to 64 characters + // long. + // + // Id is a required field + Id *string `type:"string" required:"true"` + + // If the health check was created by another service, the service that created + // the health check. When a health check is created by another service, you + // can't edit or delete it using Amazon Route 53. + LinkedService *LinkedService `type:"structure"` +} + +// String returns the string representation +func (s HealthCheck) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HealthCheck) GoString() string { + return s.String() +} + +// SetCallerReference sets the CallerReference field's value. +func (s *HealthCheck) SetCallerReference(v string) *HealthCheck { + s.CallerReference = &v + return s +} + +// SetCloudWatchAlarmConfiguration sets the CloudWatchAlarmConfiguration field's value. +func (s *HealthCheck) SetCloudWatchAlarmConfiguration(v *CloudWatchAlarmConfiguration) *HealthCheck { + s.CloudWatchAlarmConfiguration = v + return s +} + +// SetHealthCheckConfig sets the HealthCheckConfig field's value. +func (s *HealthCheck) SetHealthCheckConfig(v *HealthCheckConfig) *HealthCheck { + s.HealthCheckConfig = v + return s +} + +// SetHealthCheckVersion sets the HealthCheckVersion field's value. +func (s *HealthCheck) SetHealthCheckVersion(v int64) *HealthCheck { + s.HealthCheckVersion = &v + return s +} + +// SetId sets the Id field's value. +func (s *HealthCheck) SetId(v string) *HealthCheck { + s.Id = &v + return s +} + +// SetLinkedService sets the LinkedService field's value. +func (s *HealthCheck) SetLinkedService(v *LinkedService) *HealthCheck { + s.LinkedService = v + return s +} + +// A complex type that contains information about the health check. +type HealthCheckConfig struct { + _ struct{} `type:"structure"` + + // A complex type that identifies the CloudWatch alarm that you want Amazon + // Route 53 health checkers to use to determine whether the specified health + // check is healthy. + AlarmIdentifier *AlarmIdentifier `type:"structure"` + + // (CALCULATED Health Checks Only) A complex type that contains one ChildHealthCheck + // element for each health check that you want to associate with a CALCULATED + // health check. + ChildHealthChecks []*string `locationNameList:"ChildHealthCheck" type:"list"` + + // Stops Route 53 from performing health checks. When you disable a health check, + // here's what happens: + // + // * Health checks that check the health of endpoints: Route 53 stops submitting + // requests to your application, server, or other resource. + // + // * Calculated health checks: Route 53 stops aggregating the status of the + // referenced health checks. + // + // * Health checks that monitor CloudWatch alarms: Route 53 stops monitoring + // the corresponding CloudWatch metrics. + // + // After you disable a health check, Route 53 considers the status of the health + // check to always be healthy. If you configured DNS failover, Route 53 continues + // to route traffic to the corresponding resources. If you want to stop routing + // traffic to a resource, change the value of Inverted (https://docs.aws.amazon.com/Route53/latest/APIReference/API_UpdateHealthCheck.html#Route53-UpdateHealthCheck-request-Inverted). + // + // Charges for a health check still apply when the health check is disabled. + // For more information, see Amazon Route 53 Pricing (http://aws.amazon.com/route53/pricing/). + Disabled *bool `type:"boolean"` + + // Specify whether you want Amazon Route 53 to send the value of FullyQualifiedDomainName + // to the endpoint in the client_hello message during TLS negotiation. This + // allows the endpoint to respond to HTTPS health check requests with the applicable + // SSL/TLS certificate. + // + // Some endpoints require that HTTPS requests include the host name in the client_hello + // message. If you don't enable SNI, the status of the health check will be + // SSL alert handshake_failure. A health check can also have that status for + // other reasons. If SNI is enabled and you're still getting the error, check + // the SSL/TLS configuration on your endpoint and confirm that your certificate + // is valid. + // + // The SSL/TLS certificate on your endpoint includes a domain name in the Common + // Name field and possibly several more in the Subject Alternative Names field. + // One of the domain names in the certificate should match the value that you + // specify for FullyQualifiedDomainName. If the endpoint responds to the client_hello + // message with a certificate that does not include the domain name that you + // specified in FullyQualifiedDomainName, a health checker will retry the handshake. + // In the second attempt, the health checker will omit FullyQualifiedDomainName + // from the client_hello message. + EnableSNI *bool `type:"boolean"` + + // The number of consecutive health checks that an endpoint must pass or fail + // for Amazon Route 53 to change the current status of the endpoint from unhealthy + // to healthy or vice versa. For more information, see How Amazon Route 53 Determines + // Whether an Endpoint Is Healthy (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-determining-health-of-endpoints.html) + // in the Amazon Route 53 Developer Guide. + // + // If you don't specify a value for FailureThreshold, the default value is three + // health checks. + FailureThreshold *int64 `min:"1" type:"integer"` + + // Amazon Route 53 behavior depends on whether you specify a value for IPAddress. + // + // If you specify a value for IPAddress: + // + // Amazon Route 53 sends health check requests to the specified IPv4 or IPv6 + // address and passes the value of FullyQualifiedDomainName in the Host header + // for all health checks except TCP health checks. This is typically the fully + // qualified DNS name of the endpoint on which you want Route 53 to perform + // health checks. + // + // When Route 53 checks the health of an endpoint, here is how it constructs + // the Host header: + // + // * If you specify a value of 80 for Port and HTTP or HTTP_STR_MATCH for + // Type, Route 53 passes the value of FullyQualifiedDomainName to the endpoint + // in the Host header. + // + // * If you specify a value of 443 for Port and HTTPS or HTTPS_STR_MATCH + // for Type, Route 53 passes the value of FullyQualifiedDomainName to the + // endpoint in the Host header. + // + // * If you specify another value for Port and any value except TCP for Type, + // Route 53 passes FullyQualifiedDomainName:Port to the endpoint in the Host + // header. + // + // If you don't specify a value for FullyQualifiedDomainName, Route 53 substitutes + // the value of IPAddress in the Host header in each of the preceding cases. + // + // If you don't specify a value for IPAddress : + // + // Route 53 sends a DNS request to the domain that you specify for FullyQualifiedDomainName + // at the interval that you specify for RequestInterval. Using an IPv4 address + // that DNS returns, Route 53 then checks the health of the endpoint. + // + // If you don't specify a value for IPAddress, Route 53 uses only IPv4 to send + // health checks to the endpoint. If there's no resource record set with a type + // of A for the name that you specify for FullyQualifiedDomainName, the health + // check fails with a "DNS resolution failed" error. + // + // If you want to check the health of weighted, latency, or failover resource + // record sets and you choose to specify the endpoint only by FullyQualifiedDomainName, + // we recommend that you create a separate health check for each endpoint. For + // example, create a health check for each HTTP server that is serving content + // for www.example.com. For the value of FullyQualifiedDomainName, specify the + // domain name of the server (such as us-east-2-www.example.com), not the name + // of the resource record sets (www.example.com). + // + // In this configuration, if you create a health check for which the value of + // FullyQualifiedDomainName matches the name of the resource record sets and + // you then associate the health check with those resource record sets, health + // check results will be unpredictable. + // + // In addition, if the value that you specify for Type is HTTP, HTTPS, HTTP_STR_MATCH, + // or HTTPS_STR_MATCH, Route 53 passes the value of FullyQualifiedDomainName + // in the Host header, as it does when you specify a value for IPAddress. If + // the value of Type is TCP, Route 53 doesn't pass a Host header. + FullyQualifiedDomainName *string `type:"string"` + + // The number of child health checks that are associated with a CALCULATED health + // check that Amazon Route 53 must consider healthy for the CALCULATED health + // check to be considered healthy. To specify the child health checks that you + // want to associate with a CALCULATED health check, use the ChildHealthChecks + // (https://docs.aws.amazon.com/Route53/latest/APIReference/API_UpdateHealthCheck.html#Route53-UpdateHealthCheck-request-ChildHealthChecks) + // element. + // + // Note the following: + // + // * If you specify a number greater than the number of child health checks, + // Route 53 always considers this health check to be unhealthy. + // + // * If you specify 0, Route 53 always considers this health check to be + // healthy. + HealthThreshold *int64 `type:"integer"` + + // The IPv4 or IPv6 IP address of the endpoint that you want Amazon Route 53 + // to perform health checks on. If you don't specify a value for IPAddress, + // Route 53 sends a DNS request to resolve the domain name that you specify + // in FullyQualifiedDomainName at the interval that you specify in RequestInterval. + // Using an IP address returned by DNS, Route 53 then checks the health of the + // endpoint. + // + // Use one of the following formats for the value of IPAddress: + // + // * IPv4 address: four values between 0 and 255, separated by periods (.), + // for example, 192.0.2.44. + // + // * IPv6 address: eight groups of four hexadecimal values, separated by + // colons (:), for example, 2001:0db8:85a3:0000:0000:abcd:0001:2345. You + // can also shorten IPv6 addresses as described in RFC 5952, for example, + // 2001:db8:85a3::abcd:1:2345. + // + // If the endpoint is an EC2 instance, we recommend that you create an Elastic + // IP address, associate it with your EC2 instance, and specify the Elastic + // IP address for IPAddress. This ensures that the IP address of your instance + // will never change. + // + // For more information, see FullyQualifiedDomainName (https://docs.aws.amazon.com/Route53/latest/APIReference/API_UpdateHealthCheck.html#Route53-UpdateHealthCheck-request-FullyQualifiedDomainName). + // + // Constraints: Route 53 can't check the health of endpoints for which the IP + // address is in local, private, non-routable, or multicast ranges. For more + // information about IP addresses for which you can't create health checks, + // see the following documents: + // + // * RFC 5735, Special Use IPv4 Addresses (https://tools.ietf.org/html/rfc5735) + // + // * RFC 6598, IANA-Reserved IPv4 Prefix for Shared Address Space (https://tools.ietf.org/html/rfc6598) + // + // * RFC 5156, Special-Use IPv6 Addresses (https://tools.ietf.org/html/rfc5156) + // + // When the value of Type is CALCULATED or CLOUDWATCH_METRIC, omit IPAddress. + IPAddress *string `type:"string"` + + // When CloudWatch has insufficient data about the metric to determine the alarm + // state, the status that you want Amazon Route 53 to assign to the health check: + // + // * Healthy: Route 53 considers the health check to be healthy. + // + // * Unhealthy: Route 53 considers the health check to be unhealthy. + // + // * LastKnownStatus: Route 53 uses the status of the health check from the + // last time that CloudWatch had sufficient data to determine the alarm state. + // For new health checks that have no last known status, the default status + // for the health check is healthy. + InsufficientDataHealthStatus *string `type:"string" enum:"InsufficientDataHealthStatus"` + + // Specify whether you want Amazon Route 53 to invert the status of a health + // check, for example, to consider a health check unhealthy when it otherwise + // would be considered healthy. + Inverted *bool `type:"boolean"` + + // Specify whether you want Amazon Route 53 to measure the latency between health + // checkers in multiple AWS regions and your endpoint, and to display CloudWatch + // latency graphs on the Health Checks page in the Route 53 console. + // + // You can't change the value of MeasureLatency after you create a health check. + MeasureLatency *bool `type:"boolean"` + + // The port on the endpoint on which you want Amazon Route 53 to perform health + // checks. Specify a value for Port only when you specify a value for IPAddress. + Port *int64 `min:"1" type:"integer"` + + // A complex type that contains one Region element for each region from which + // you want Amazon Route 53 health checkers to check the specified endpoint. + // + // If you don't specify any regions, Route 53 health checkers automatically + // performs checks from all of the regions that are listed under Valid Values. + // + // If you update a health check to remove a region that has been performing + // health checks, Route 53 will briefly continue to perform checks from that + // region to ensure that some health checkers are always checking the endpoint + // (for example, if you replace three regions with four different regions). + Regions []*string `locationNameList:"Region" min:"3" type:"list"` + + // The number of seconds between the time that Amazon Route 53 gets a response + // from your endpoint and the time that it sends the next health check request. + // Each Route 53 health checker makes requests at this interval. + // + // You can't change the value of RequestInterval after you create a health check. + // + // If you don't specify a value for RequestInterval, the default value is 30 + // seconds. + RequestInterval *int64 `min:"10" type:"integer"` + + // The path, if any, that you want Amazon Route 53 to request when performing + // health checks. The path can be any value for which your endpoint will return + // an HTTP status code of 2xx or 3xx when the endpoint is healthy, for example, + // the file /docs/route53-health-check.html. You can also include query string + // parameters, for example, /welcome.html?language=jp&login=y. + ResourcePath *string `type:"string"` + + // If the value of Type is HTTP_STR_MATCH or HTTP_STR_MATCH, the string that + // you want Amazon Route 53 to search for in the response body from the specified + // resource. If the string appears in the response body, Route 53 considers + // the resource healthy. + // + // Route 53 considers case when searching for SearchString in the response body. + SearchString *string `type:"string"` + + // The type of health check that you want to create, which indicates how Amazon + // Route 53 determines whether an endpoint is healthy. + // + // You can't change the value of Type after you create a health check. + // + // You can create the following types of health checks: + // + // * HTTP: Route 53 tries to establish a TCP connection. If successful, Route + // 53 submits an HTTP request and waits for an HTTP status code of 200 or + // greater and less than 400. + // + // * HTTPS: Route 53 tries to establish a TCP connection. If successful, + // Route 53 submits an HTTPS request and waits for an HTTP status code of + // 200 or greater and less than 400. If you specify HTTPS for the value of + // Type, the endpoint must support TLS v1.0 or later. + // + // * HTTP_STR_MATCH: Route 53 tries to establish a TCP connection. If successful, + // Route 53 submits an HTTP request and searches the first 5,120 bytes of + // the response body for the string that you specify in SearchString. + // + // * HTTPS_STR_MATCH: Route 53 tries to establish a TCP connection. If successful, + // Route 53 submits an HTTPS request and searches the first 5,120 bytes of + // the response body for the string that you specify in SearchString. + // + // * TCP: Route 53 tries to establish a TCP connection. + // + // * CLOUDWATCH_METRIC: The health check is associated with a CloudWatch + // alarm. If the state of the alarm is OK, the health check is considered + // healthy. If the state is ALARM, the health check is considered unhealthy. + // If CloudWatch doesn't have sufficient data to determine whether the state + // is OK or ALARM, the health check status depends on the setting for InsufficientDataHealthStatus: + // Healthy, Unhealthy, or LastKnownStatus. + // + // * CALCULATED: For health checks that monitor the status of other health + // checks, Route 53 adds up the number of health checks that Route 53 health + // checkers consider to be healthy and compares that number with the value + // of HealthThreshold. + // + // For more information, see How Route 53 Determines Whether an Endpoint Is + // Healthy (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-determining-health-of-endpoints.html) + // in the Amazon Route 53 Developer Guide. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"HealthCheckType"` +} + +// String returns the string representation +func (s HealthCheckConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HealthCheckConfig) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *HealthCheckConfig) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "HealthCheckConfig"} + if s.FailureThreshold != nil && *s.FailureThreshold < 1 { + invalidParams.Add(request.NewErrParamMinValue("FailureThreshold", 1)) + } + if s.Port != nil && *s.Port < 1 { + invalidParams.Add(request.NewErrParamMinValue("Port", 1)) + } + if s.Regions != nil && len(s.Regions) < 3 { + invalidParams.Add(request.NewErrParamMinLen("Regions", 3)) + } + if s.RequestInterval != nil && *s.RequestInterval < 10 { + invalidParams.Add(request.NewErrParamMinValue("RequestInterval", 10)) + } + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + if s.AlarmIdentifier != nil { + if err := s.AlarmIdentifier.Validate(); err != nil { + invalidParams.AddNested("AlarmIdentifier", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAlarmIdentifier sets the AlarmIdentifier field's value. +func (s *HealthCheckConfig) SetAlarmIdentifier(v *AlarmIdentifier) *HealthCheckConfig { + s.AlarmIdentifier = v + return s +} + +// SetChildHealthChecks sets the ChildHealthChecks field's value. +func (s *HealthCheckConfig) SetChildHealthChecks(v []*string) *HealthCheckConfig { + s.ChildHealthChecks = v + return s +} + +// SetDisabled sets the Disabled field's value. +func (s *HealthCheckConfig) SetDisabled(v bool) *HealthCheckConfig { + s.Disabled = &v + return s +} + +// SetEnableSNI sets the EnableSNI field's value. +func (s *HealthCheckConfig) SetEnableSNI(v bool) *HealthCheckConfig { + s.EnableSNI = &v + return s +} + +// SetFailureThreshold sets the FailureThreshold field's value. +func (s *HealthCheckConfig) SetFailureThreshold(v int64) *HealthCheckConfig { + s.FailureThreshold = &v + return s +} + +// SetFullyQualifiedDomainName sets the FullyQualifiedDomainName field's value. +func (s *HealthCheckConfig) SetFullyQualifiedDomainName(v string) *HealthCheckConfig { + s.FullyQualifiedDomainName = &v + return s +} + +// SetHealthThreshold sets the HealthThreshold field's value. +func (s *HealthCheckConfig) SetHealthThreshold(v int64) *HealthCheckConfig { + s.HealthThreshold = &v + return s +} + +// SetIPAddress sets the IPAddress field's value. +func (s *HealthCheckConfig) SetIPAddress(v string) *HealthCheckConfig { + s.IPAddress = &v + return s +} + +// SetInsufficientDataHealthStatus sets the InsufficientDataHealthStatus field's value. +func (s *HealthCheckConfig) SetInsufficientDataHealthStatus(v string) *HealthCheckConfig { + s.InsufficientDataHealthStatus = &v + return s +} + +// SetInverted sets the Inverted field's value. +func (s *HealthCheckConfig) SetInverted(v bool) *HealthCheckConfig { + s.Inverted = &v + return s +} + +// SetMeasureLatency sets the MeasureLatency field's value. +func (s *HealthCheckConfig) SetMeasureLatency(v bool) *HealthCheckConfig { + s.MeasureLatency = &v + return s +} + +// SetPort sets the Port field's value. +func (s *HealthCheckConfig) SetPort(v int64) *HealthCheckConfig { + s.Port = &v + return s +} + +// SetRegions sets the Regions field's value. +func (s *HealthCheckConfig) SetRegions(v []*string) *HealthCheckConfig { + s.Regions = v + return s +} + +// SetRequestInterval sets the RequestInterval field's value. +func (s *HealthCheckConfig) SetRequestInterval(v int64) *HealthCheckConfig { + s.RequestInterval = &v + return s +} + +// SetResourcePath sets the ResourcePath field's value. +func (s *HealthCheckConfig) SetResourcePath(v string) *HealthCheckConfig { + s.ResourcePath = &v + return s +} + +// SetSearchString sets the SearchString field's value. +func (s *HealthCheckConfig) SetSearchString(v string) *HealthCheckConfig { + s.SearchString = &v + return s +} + +// SetType sets the Type field's value. +func (s *HealthCheckConfig) SetType(v string) *HealthCheckConfig { + s.Type = &v + return s +} + +// A complex type that contains the last failure reason as reported by one Amazon +// Route 53 health checker. +type HealthCheckObservation struct { + _ struct{} `type:"structure"` + + // The IP address of the Amazon Route 53 health checker that provided the failure + // reason in StatusReport. + IPAddress *string `type:"string"` + + // The region of the Amazon Route 53 health checker that provided the status + // in StatusReport. + Region *string `min:"1" type:"string" enum:"HealthCheckRegion"` + + // A complex type that contains the last failure reason as reported by one Amazon + // Route 53 health checker and the time of the failed health check. + StatusReport *StatusReport `type:"structure"` +} + +// String returns the string representation +func (s HealthCheckObservation) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HealthCheckObservation) GoString() string { + return s.String() +} + +// SetIPAddress sets the IPAddress field's value. +func (s *HealthCheckObservation) SetIPAddress(v string) *HealthCheckObservation { + s.IPAddress = &v + return s +} + +// SetRegion sets the Region field's value. +func (s *HealthCheckObservation) SetRegion(v string) *HealthCheckObservation { + s.Region = &v + return s +} + +// SetStatusReport sets the StatusReport field's value. +func (s *HealthCheckObservation) SetStatusReport(v *StatusReport) *HealthCheckObservation { + s.StatusReport = v + return s +} + +// A complex type that contains general information about the hosted zone. +type HostedZone struct { + _ struct{} `type:"structure"` + + // The value that you specified for CallerReference when you created the hosted + // zone. + // + // CallerReference is a required field + CallerReference *string `min:"1" type:"string" required:"true"` + + // A complex type that includes the Comment and PrivateZone elements. If you + // omitted the HostedZoneConfig and Comment elements from the request, the Config + // and Comment elements don't appear in the response. + Config *HostedZoneConfig `type:"structure"` + + // The ID that Amazon Route 53 assigned to the hosted zone when you created + // it. + // + // Id is a required field + Id *string `type:"string" required:"true"` + + // If the hosted zone was created by another service, the service that created + // the hosted zone. When a hosted zone is created by another service, you can't + // edit or delete it using Route 53. + LinkedService *LinkedService `type:"structure"` + + // The name of the domain. For public hosted zones, this is the name that you + // have registered with your DNS registrar. + // + // For information about how to specify characters other than a-z, 0-9, and + // - (hyphen) and how to specify internationalized domain names, see CreateHostedZone + // (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateHostedZone.html). + // + // Name is a required field + Name *string `type:"string" required:"true"` + + // The number of resource record sets in the hosted zone. + ResourceRecordSetCount *int64 `type:"long"` +} + +// String returns the string representation +func (s HostedZone) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostedZone) GoString() string { + return s.String() +} + +// SetCallerReference sets the CallerReference field's value. +func (s *HostedZone) SetCallerReference(v string) *HostedZone { + s.CallerReference = &v + return s +} + +// SetConfig sets the Config field's value. +func (s *HostedZone) SetConfig(v *HostedZoneConfig) *HostedZone { + s.Config = v + return s +} + +// SetId sets the Id field's value. +func (s *HostedZone) SetId(v string) *HostedZone { + s.Id = &v + return s +} + +// SetLinkedService sets the LinkedService field's value. +func (s *HostedZone) SetLinkedService(v *LinkedService) *HostedZone { + s.LinkedService = v + return s +} + +// SetName sets the Name field's value. +func (s *HostedZone) SetName(v string) *HostedZone { + s.Name = &v + return s +} + +// SetResourceRecordSetCount sets the ResourceRecordSetCount field's value. +func (s *HostedZone) SetResourceRecordSetCount(v int64) *HostedZone { + s.ResourceRecordSetCount = &v + return s +} + +// A complex type that contains an optional comment about your hosted zone. +// If you don't want to specify a comment, omit both the HostedZoneConfig and +// Comment elements. +type HostedZoneConfig struct { + _ struct{} `type:"structure"` + + // Any comments that you want to include about the hosted zone. + Comment *string `type:"string"` + + // A value that indicates whether this is a private hosted zone. + PrivateZone *bool `type:"boolean"` +} + +// String returns the string representation +func (s HostedZoneConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostedZoneConfig) GoString() string { + return s.String() +} + +// SetComment sets the Comment field's value. +func (s *HostedZoneConfig) SetComment(v string) *HostedZoneConfig { + s.Comment = &v + return s +} + +// SetPrivateZone sets the PrivateZone field's value. +func (s *HostedZoneConfig) SetPrivateZone(v bool) *HostedZoneConfig { + s.PrivateZone = &v + return s +} + +// A complex type that contains the type of limit that you specified in the +// request and the current value for that limit. +type HostedZoneLimit struct { + _ struct{} `type:"structure"` + + // The limit that you requested. Valid values include the following: + // + // * MAX_RRSETS_BY_ZONE: The maximum number of records that you can create + // in the specified hosted zone. + // + // * MAX_VPCS_ASSOCIATED_BY_ZONE: The maximum number of Amazon VPCs that + // you can associate with the specified private hosted zone. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"HostedZoneLimitType"` + + // The current value for the limit that is specified by Type. + // + // Value is a required field + Value *int64 `min:"1" type:"long" required:"true"` +} + +// String returns the string representation +func (s HostedZoneLimit) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HostedZoneLimit) GoString() string { + return s.String() +} + +// SetType sets the Type field's value. +func (s *HostedZoneLimit) SetType(v string) *HostedZoneLimit { + s.Type = &v + return s +} + +// SetValue sets the Value field's value. +func (s *HostedZoneLimit) SetValue(v int64) *HostedZoneLimit { + s.Value = &v + return s +} + +// If a health check or hosted zone was created by another service, LinkedService +// is a complex type that describes the service that created the resource. When +// a resource is created by another service, you can't edit or delete it using +// Amazon Route 53. +type LinkedService struct { + _ struct{} `type:"structure"` + + // If the health check or hosted zone was created by another service, an optional + // description that can be provided by the other service. When a resource is + // created by another service, you can't edit or delete it using Amazon Route + // 53. + Description *string `type:"string"` + + // If the health check or hosted zone was created by another service, the service + // that created the resource. When a resource is created by another service, + // you can't edit or delete it using Amazon Route 53. + ServicePrincipal *string `type:"string"` +} + +// String returns the string representation +func (s LinkedService) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s LinkedService) GoString() string { + return s.String() +} + +// SetDescription sets the Description field's value. +func (s *LinkedService) SetDescription(v string) *LinkedService { + s.Description = &v + return s +} + +// SetServicePrincipal sets the ServicePrincipal field's value. +func (s *LinkedService) SetServicePrincipal(v string) *LinkedService { + s.ServicePrincipal = &v + return s +} + +// A request to get a list of geographic locations that Amazon Route 53 supports +// for geolocation resource record sets. +type ListGeoLocationsInput struct { + _ struct{} `type:"structure"` + + // (Optional) The maximum number of geolocations to be included in the response + // body for this request. If more than maxitems geolocations remain to be listed, + // then the value of the IsTruncated element in the response is true. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` + + // The code for the continent with which you want to start listing locations + // that Amazon Route 53 supports for geolocation. If Route 53 has already returned + // a page or more of results, if IsTruncated is true, and if NextContinentCode + // from the previous response has a value, enter that value in startcontinentcode + // to return the next page of results. + // + // Include startcontinentcode only if you want to list continents. Don't include + // startcontinentcode when you're listing countries or countries with their + // subdivisions. + StartContinentCode *string `location:"querystring" locationName:"startcontinentcode" min:"2" type:"string"` + + // The code for the country with which you want to start listing locations that + // Amazon Route 53 supports for geolocation. If Route 53 has already returned + // a page or more of results, if IsTruncated is true, and if NextCountryCode + // from the previous response has a value, enter that value in startcountrycode + // to return the next page of results. + // + // Route 53 uses the two-letter country codes that are specified in ISO standard + // 3166-1 alpha-2 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). + StartCountryCode *string `location:"querystring" locationName:"startcountrycode" min:"1" type:"string"` + + // The code for the subdivision (for example, state or province) with which + // you want to start listing locations that Amazon Route 53 supports for geolocation. + // If Route 53 has already returned a page or more of results, if IsTruncated + // is true, and if NextSubdivisionCode from the previous response has a value, + // enter that value in startsubdivisioncode to return the next page of results. + // + // To list subdivisions of a country, you must include both startcountrycode + // and startsubdivisioncode. + StartSubdivisionCode *string `location:"querystring" locationName:"startsubdivisioncode" min:"1" type:"string"` +} + +// String returns the string representation +func (s ListGeoLocationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListGeoLocationsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListGeoLocationsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListGeoLocationsInput"} + if s.StartContinentCode != nil && len(*s.StartContinentCode) < 2 { + invalidParams.Add(request.NewErrParamMinLen("StartContinentCode", 2)) + } + if s.StartCountryCode != nil && len(*s.StartCountryCode) < 1 { + invalidParams.Add(request.NewErrParamMinLen("StartCountryCode", 1)) + } + if s.StartSubdivisionCode != nil && len(*s.StartSubdivisionCode) < 1 { + invalidParams.Add(request.NewErrParamMinLen("StartSubdivisionCode", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListGeoLocationsInput) SetMaxItems(v string) *ListGeoLocationsInput { + s.MaxItems = &v + return s +} + +// SetStartContinentCode sets the StartContinentCode field's value. +func (s *ListGeoLocationsInput) SetStartContinentCode(v string) *ListGeoLocationsInput { + s.StartContinentCode = &v + return s +} + +// SetStartCountryCode sets the StartCountryCode field's value. +func (s *ListGeoLocationsInput) SetStartCountryCode(v string) *ListGeoLocationsInput { + s.StartCountryCode = &v + return s +} + +// SetStartSubdivisionCode sets the StartSubdivisionCode field's value. +func (s *ListGeoLocationsInput) SetStartSubdivisionCode(v string) *ListGeoLocationsInput { + s.StartSubdivisionCode = &v + return s +} + +// A complex type containing the response information for the request. +type ListGeoLocationsOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains one GeoLocationDetails element for each location + // that Amazon Route 53 supports for geolocation. + // + // GeoLocationDetailsList is a required field + GeoLocationDetailsList []*GeoLocationDetails `locationNameList:"GeoLocationDetails" type:"list" required:"true"` + + // A value that indicates whether more locations remain to be listed after the + // last location in this response. If so, the value of IsTruncated is true. + // To get more values, submit another request and include the values of NextContinentCode, + // NextCountryCode, and NextSubdivisionCode in the startcontinentcode, startcountrycode, + // and startsubdivisioncode, as applicable. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // The value that you specified for MaxItems in the request. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If IsTruncated is true, you can make a follow-up request to display more + // locations. Enter the value of NextContinentCode in the startcontinentcode + // parameter in another ListGeoLocations request. + NextContinentCode *string `min:"2" type:"string"` + + // If IsTruncated is true, you can make a follow-up request to display more + // locations. Enter the value of NextCountryCode in the startcountrycode parameter + // in another ListGeoLocations request. + NextCountryCode *string `min:"1" type:"string"` + + // If IsTruncated is true, you can make a follow-up request to display more + // locations. Enter the value of NextSubdivisionCode in the startsubdivisioncode + // parameter in another ListGeoLocations request. + NextSubdivisionCode *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s ListGeoLocationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListGeoLocationsOutput) GoString() string { + return s.String() +} + +// SetGeoLocationDetailsList sets the GeoLocationDetailsList field's value. +func (s *ListGeoLocationsOutput) SetGeoLocationDetailsList(v []*GeoLocationDetails) *ListGeoLocationsOutput { + s.GeoLocationDetailsList = v + return s +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListGeoLocationsOutput) SetIsTruncated(v bool) *ListGeoLocationsOutput { + s.IsTruncated = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListGeoLocationsOutput) SetMaxItems(v string) *ListGeoLocationsOutput { + s.MaxItems = &v + return s +} + +// SetNextContinentCode sets the NextContinentCode field's value. +func (s *ListGeoLocationsOutput) SetNextContinentCode(v string) *ListGeoLocationsOutput { + s.NextContinentCode = &v + return s +} + +// SetNextCountryCode sets the NextCountryCode field's value. +func (s *ListGeoLocationsOutput) SetNextCountryCode(v string) *ListGeoLocationsOutput { + s.NextCountryCode = &v + return s +} + +// SetNextSubdivisionCode sets the NextSubdivisionCode field's value. +func (s *ListGeoLocationsOutput) SetNextSubdivisionCode(v string) *ListGeoLocationsOutput { + s.NextSubdivisionCode = &v + return s +} + +// A request to retrieve a list of the health checks that are associated with +// the current AWS account. +type ListHealthChecksInput struct { + _ struct{} `type:"structure"` + + // If the value of IsTruncated in the previous response was true, you have more + // health checks. To get another group, submit another ListHealthChecks request. + // + // For the value of marker, specify the value of NextMarker from the previous + // response, which is the ID of the first health check that Amazon Route 53 + // will return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more health checks to get. + Marker *string `location:"querystring" locationName:"marker" type:"string"` + + // The maximum number of health checks that you want ListHealthChecks to return + // in response to the current request. Amazon Route 53 returns a maximum of + // 100 items. If you set MaxItems to a value greater than 100, Route 53 returns + // only the first 100 health checks. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` +} + +// String returns the string representation +func (s ListHealthChecksInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListHealthChecksInput) GoString() string { + return s.String() +} + +// SetMarker sets the Marker field's value. +func (s *ListHealthChecksInput) SetMarker(v string) *ListHealthChecksInput { + s.Marker = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListHealthChecksInput) SetMaxItems(v string) *ListHealthChecksInput { + s.MaxItems = &v + return s +} + +// A complex type that contains the response to a ListHealthChecks request. +type ListHealthChecksOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains one HealthCheck element for each health check + // that is associated with the current AWS account. + // + // HealthChecks is a required field + HealthChecks []*HealthCheck `locationNameList:"HealthCheck" type:"list" required:"true"` + + // A flag that indicates whether there are more health checks to be listed. + // If the response was truncated, you can get the next group of health checks + // by submitting another ListHealthChecks request and specifying the value of + // NextMarker in the marker parameter. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // For the second and subsequent calls to ListHealthChecks, Marker is the value + // that you specified for the marker parameter in the previous request. + // + // Marker is a required field + Marker *string `type:"string" required:"true"` + + // The value that you specified for the maxitems parameter in the call to ListHealthChecks + // that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If IsTruncated is true, the value of NextMarker identifies the first health + // check that Amazon Route 53 returns if you submit another ListHealthChecks + // request and specify the value of NextMarker in the marker parameter. + NextMarker *string `type:"string"` +} + +// String returns the string representation +func (s ListHealthChecksOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListHealthChecksOutput) GoString() string { + return s.String() +} + +// SetHealthChecks sets the HealthChecks field's value. +func (s *ListHealthChecksOutput) SetHealthChecks(v []*HealthCheck) *ListHealthChecksOutput { + s.HealthChecks = v + return s +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListHealthChecksOutput) SetIsTruncated(v bool) *ListHealthChecksOutput { + s.IsTruncated = &v + return s +} + +// SetMarker sets the Marker field's value. +func (s *ListHealthChecksOutput) SetMarker(v string) *ListHealthChecksOutput { + s.Marker = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListHealthChecksOutput) SetMaxItems(v string) *ListHealthChecksOutput { + s.MaxItems = &v + return s +} + +// SetNextMarker sets the NextMarker field's value. +func (s *ListHealthChecksOutput) SetNextMarker(v string) *ListHealthChecksOutput { + s.NextMarker = &v + return s +} + +// Retrieves a list of the public and private hosted zones that are associated +// with the current AWS account in ASCII order by domain name. +type ListHostedZonesByNameInput struct { + _ struct{} `type:"structure"` + + // (Optional) For your first request to ListHostedZonesByName, include the dnsname + // parameter only if you want to specify the name of the first hosted zone in + // the response. If you don't include the dnsname parameter, Amazon Route 53 + // returns all of the hosted zones that were created by the current AWS account, + // in ASCII order. For subsequent requests, include both dnsname and hostedzoneid + // parameters. For dnsname, specify the value of NextDNSName from the previous + // response. + DNSName *string `location:"querystring" locationName:"dnsname" type:"string"` + + // (Optional) For your first request to ListHostedZonesByName, do not include + // the hostedzoneid parameter. + // + // If you have more hosted zones than the value of maxitems, ListHostedZonesByName + // returns only the first maxitems hosted zones. To get the next group of maxitems + // hosted zones, submit another request to ListHostedZonesByName and include + // both dnsname and hostedzoneid parameters. For the value of hostedzoneid, + // specify the value of the NextHostedZoneId element from the previous response. + HostedZoneId *string `location:"querystring" locationName:"hostedzoneid" type:"string"` + + // The maximum number of hosted zones to be included in the response body for + // this request. If you have more than maxitems hosted zones, then the value + // of the IsTruncated element in the response is true, and the values of NextDNSName + // and NextHostedZoneId specify the first hosted zone in the next group of maxitems + // hosted zones. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` +} + +// String returns the string representation +func (s ListHostedZonesByNameInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListHostedZonesByNameInput) GoString() string { + return s.String() +} + +// SetDNSName sets the DNSName field's value. +func (s *ListHostedZonesByNameInput) SetDNSName(v string) *ListHostedZonesByNameInput { + s.DNSName = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *ListHostedZonesByNameInput) SetHostedZoneId(v string) *ListHostedZonesByNameInput { + s.HostedZoneId = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListHostedZonesByNameInput) SetMaxItems(v string) *ListHostedZonesByNameInput { + s.MaxItems = &v + return s +} + +// A complex type that contains the response information for the request. +type ListHostedZonesByNameOutput struct { + _ struct{} `type:"structure"` + + // For the second and subsequent calls to ListHostedZonesByName, DNSName is + // the value that you specified for the dnsname parameter in the request that + // produced the current response. + DNSName *string `type:"string"` + + // The ID that Amazon Route 53 assigned to the hosted zone when you created + // it. + HostedZoneId *string `type:"string"` + + // A complex type that contains general information about the hosted zone. + // + // HostedZones is a required field + HostedZones []*HostedZone `locationNameList:"HostedZone" type:"list" required:"true"` + + // A flag that indicates whether there are more hosted zones to be listed. If + // the response was truncated, you can get the next group of maxitems hosted + // zones by calling ListHostedZonesByName again and specifying the values of + // NextDNSName and NextHostedZoneId elements in the dnsname and hostedzoneid + // parameters. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // The value that you specified for the maxitems parameter in the call to ListHostedZonesByName + // that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If IsTruncated is true, the value of NextDNSName is the name of the first + // hosted zone in the next group of maxitems hosted zones. Call ListHostedZonesByName + // again and specify the value of NextDNSName and NextHostedZoneId in the dnsname + // and hostedzoneid parameters, respectively. + // + // This element is present only if IsTruncated is true. + NextDNSName *string `type:"string"` + + // If IsTruncated is true, the value of NextHostedZoneId identifies the first + // hosted zone in the next group of maxitems hosted zones. Call ListHostedZonesByName + // again and specify the value of NextDNSName and NextHostedZoneId in the dnsname + // and hostedzoneid parameters, respectively. + // + // This element is present only if IsTruncated is true. + NextHostedZoneId *string `type:"string"` +} + +// String returns the string representation +func (s ListHostedZonesByNameOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListHostedZonesByNameOutput) GoString() string { + return s.String() +} + +// SetDNSName sets the DNSName field's value. +func (s *ListHostedZonesByNameOutput) SetDNSName(v string) *ListHostedZonesByNameOutput { + s.DNSName = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *ListHostedZonesByNameOutput) SetHostedZoneId(v string) *ListHostedZonesByNameOutput { + s.HostedZoneId = &v + return s +} + +// SetHostedZones sets the HostedZones field's value. +func (s *ListHostedZonesByNameOutput) SetHostedZones(v []*HostedZone) *ListHostedZonesByNameOutput { + s.HostedZones = v + return s +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListHostedZonesByNameOutput) SetIsTruncated(v bool) *ListHostedZonesByNameOutput { + s.IsTruncated = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListHostedZonesByNameOutput) SetMaxItems(v string) *ListHostedZonesByNameOutput { + s.MaxItems = &v + return s +} + +// SetNextDNSName sets the NextDNSName field's value. +func (s *ListHostedZonesByNameOutput) SetNextDNSName(v string) *ListHostedZonesByNameOutput { + s.NextDNSName = &v + return s +} + +// SetNextHostedZoneId sets the NextHostedZoneId field's value. +func (s *ListHostedZonesByNameOutput) SetNextHostedZoneId(v string) *ListHostedZonesByNameOutput { + s.NextHostedZoneId = &v + return s +} + +// A request to retrieve a list of the public and private hosted zones that +// are associated with the current AWS account. +type ListHostedZonesInput struct { + _ struct{} `type:"structure"` + + // If you're using reusable delegation sets and you want to list all of the + // hosted zones that are associated with a reusable delegation set, specify + // the ID of that reusable delegation set. + DelegationSetId *string `location:"querystring" locationName:"delegationsetid" type:"string"` + + // If the value of IsTruncated in the previous response was true, you have more + // hosted zones. To get more hosted zones, submit another ListHostedZones request. + // + // For the value of marker, specify the value of NextMarker from the previous + // response, which is the ID of the first hosted zone that Amazon Route 53 will + // return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more hosted zones to get. + Marker *string `location:"querystring" locationName:"marker" type:"string"` + + // (Optional) The maximum number of hosted zones that you want Amazon Route + // 53 to return. If you have more than maxitems hosted zones, the value of IsTruncated + // in the response is true, and the value of NextMarker is the hosted zone ID + // of the first hosted zone that Route 53 will return if you submit another + // request. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` +} + +// String returns the string representation +func (s ListHostedZonesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListHostedZonesInput) GoString() string { + return s.String() +} + +// SetDelegationSetId sets the DelegationSetId field's value. +func (s *ListHostedZonesInput) SetDelegationSetId(v string) *ListHostedZonesInput { + s.DelegationSetId = &v + return s +} + +// SetMarker sets the Marker field's value. +func (s *ListHostedZonesInput) SetMarker(v string) *ListHostedZonesInput { + s.Marker = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListHostedZonesInput) SetMaxItems(v string) *ListHostedZonesInput { + s.MaxItems = &v + return s +} + +type ListHostedZonesOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains general information about the hosted zone. + // + // HostedZones is a required field + HostedZones []*HostedZone `locationNameList:"HostedZone" type:"list" required:"true"` + + // A flag indicating whether there are more hosted zones to be listed. If the + // response was truncated, you can get more hosted zones by submitting another + // ListHostedZones request and specifying the value of NextMarker in the marker + // parameter. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // For the second and subsequent calls to ListHostedZones, Marker is the value + // that you specified for the marker parameter in the request that produced + // the current response. + // + // Marker is a required field + Marker *string `type:"string" required:"true"` + + // The value that you specified for the maxitems parameter in the call to ListHostedZones + // that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If IsTruncated is true, the value of NextMarker identifies the first hosted + // zone in the next group of hosted zones. Submit another ListHostedZones request, + // and specify the value of NextMarker from the response in the marker parameter. + // + // This element is present only if IsTruncated is true. + NextMarker *string `type:"string"` +} + +// String returns the string representation +func (s ListHostedZonesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListHostedZonesOutput) GoString() string { + return s.String() +} + +// SetHostedZones sets the HostedZones field's value. +func (s *ListHostedZonesOutput) SetHostedZones(v []*HostedZone) *ListHostedZonesOutput { + s.HostedZones = v + return s +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListHostedZonesOutput) SetIsTruncated(v bool) *ListHostedZonesOutput { + s.IsTruncated = &v + return s +} + +// SetMarker sets the Marker field's value. +func (s *ListHostedZonesOutput) SetMarker(v string) *ListHostedZonesOutput { + s.Marker = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListHostedZonesOutput) SetMaxItems(v string) *ListHostedZonesOutput { + s.MaxItems = &v + return s +} + +// SetNextMarker sets the NextMarker field's value. +func (s *ListHostedZonesOutput) SetNextMarker(v string) *ListHostedZonesOutput { + s.NextMarker = &v + return s +} + +type ListQueryLoggingConfigsInput struct { + _ struct{} `type:"structure"` + + // (Optional) If you want to list the query logging configuration that is associated + // with a hosted zone, specify the ID in HostedZoneId. + // + // If you don't specify a hosted zone ID, ListQueryLoggingConfigs returns all + // of the configurations that are associated with the current AWS account. + HostedZoneId *string `location:"querystring" locationName:"hostedzoneid" type:"string"` + + // (Optional) The maximum number of query logging configurations that you want + // Amazon Route 53 to return in response to the current request. If the current + // AWS account has more than MaxResults configurations, use the value of NextToken + // (https://docs.aws.amazon.com/Route53/latest/APIReference/API_ListQueryLoggingConfigs.html#API_ListQueryLoggingConfigs_RequestSyntax) + // in the response to get the next page of results. + // + // If you don't specify a value for MaxResults, Route 53 returns up to 100 configurations. + MaxResults *string `location:"querystring" locationName:"maxresults" type:"string"` + + // (Optional) If the current AWS account has more than MaxResults query logging + // configurations, use NextToken to get the second and subsequent pages of results. + // + // For the first ListQueryLoggingConfigs request, omit this value. + // + // For the second and subsequent requests, get the value of NextToken from the + // previous response and specify that value for NextToken in the request. + NextToken *string `location:"querystring" locationName:"nexttoken" type:"string"` +} + +// String returns the string representation +func (s ListQueryLoggingConfigsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListQueryLoggingConfigsInput) GoString() string { + return s.String() +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *ListQueryLoggingConfigsInput) SetHostedZoneId(v string) *ListQueryLoggingConfigsInput { + s.HostedZoneId = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *ListQueryLoggingConfigsInput) SetMaxResults(v string) *ListQueryLoggingConfigsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListQueryLoggingConfigsInput) SetNextToken(v string) *ListQueryLoggingConfigsInput { + s.NextToken = &v + return s +} + +type ListQueryLoggingConfigsOutput struct { + _ struct{} `type:"structure"` + + // If a response includes the last of the query logging configurations that + // are associated with the current AWS account, NextToken doesn't appear in + // the response. + // + // If a response doesn't include the last of the configurations, you can get + // more configurations by submitting another ListQueryLoggingConfigs (https://docs.aws.amazon.com/Route53/latest/APIReference/API_ListQueryLoggingConfigs.html) + // request. Get the value of NextToken that Amazon Route 53 returned in the + // previous response and include it in NextToken in the next request. + NextToken *string `type:"string"` + + // An array that contains one QueryLoggingConfig (https://docs.aws.amazon.com/Route53/latest/APIReference/API_QueryLoggingConfig.html) + // element for each configuration for DNS query logging that is associated with + // the current AWS account. + // + // QueryLoggingConfigs is a required field + QueryLoggingConfigs []*QueryLoggingConfig `locationNameList:"QueryLoggingConfig" type:"list" required:"true"` +} + +// String returns the string representation +func (s ListQueryLoggingConfigsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListQueryLoggingConfigsOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *ListQueryLoggingConfigsOutput) SetNextToken(v string) *ListQueryLoggingConfigsOutput { + s.NextToken = &v + return s +} + +// SetQueryLoggingConfigs sets the QueryLoggingConfigs field's value. +func (s *ListQueryLoggingConfigsOutput) SetQueryLoggingConfigs(v []*QueryLoggingConfig) *ListQueryLoggingConfigsOutput { + s.QueryLoggingConfigs = v + return s +} + +// A request for the resource record sets that are associated with a specified +// hosted zone. +type ListResourceRecordSetsInput struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone that contains the resource record sets that you + // want to list. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` + + // (Optional) The maximum number of resource records sets to include in the + // response body for this request. If the response includes more than maxitems + // resource record sets, the value of the IsTruncated element in the response + // is true, and the values of the NextRecordName and NextRecordType elements + // in the response identify the first resource record set in the next group + // of maxitems resource record sets. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` + + // Resource record sets that have a routing policy other than simple: If results + // were truncated for a given DNS name and type, specify the value of NextRecordIdentifier + // from the previous response to get the next resource record set that has the + // current DNS name and type. + StartRecordIdentifier *string `location:"querystring" locationName:"identifier" min:"1" type:"string"` + + // The first name in the lexicographic ordering of resource record sets that + // you want to list. + StartRecordName *string `location:"querystring" locationName:"name" type:"string"` + + // The type of resource record set to begin the record listing from. + // + // Valid values for basic resource record sets: A | AAAA | CAA | CNAME | MX + // | NAPTR | NS | PTR | SOA | SPF | SRV | TXT + // + // Values for weighted, latency, geolocation, and failover resource record sets: + // A | AAAA | CAA | CNAME | MX | NAPTR | PTR | SPF | SRV | TXT + // + // Values for alias resource record sets: + // + // * API Gateway custom regional API or edge-optimized API: A + // + // * CloudFront distribution: A or AAAA + // + // * Elastic Beanstalk environment that has a regionalized subdomain: A + // + // * Elastic Load Balancing load balancer: A | AAAA + // + // * Amazon S3 bucket: A + // + // * Amazon VPC interface VPC endpoint: A + // + // * Another resource record set in this hosted zone: The type of the resource + // record set that the alias references. + // + // Constraint: Specifying type without specifying name returns an InvalidInput + // error. + StartRecordType *string `location:"querystring" locationName:"type" type:"string" enum:"RRType"` +} + +// String returns the string representation +func (s ListResourceRecordSetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListResourceRecordSetsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListResourceRecordSetsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListResourceRecordSetsInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.HostedZoneId != nil && len(*s.HostedZoneId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HostedZoneId", 1)) + } + if s.StartRecordIdentifier != nil && len(*s.StartRecordIdentifier) < 1 { + invalidParams.Add(request.NewErrParamMinLen("StartRecordIdentifier", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *ListResourceRecordSetsInput) SetHostedZoneId(v string) *ListResourceRecordSetsInput { + s.HostedZoneId = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListResourceRecordSetsInput) SetMaxItems(v string) *ListResourceRecordSetsInput { + s.MaxItems = &v + return s +} + +// SetStartRecordIdentifier sets the StartRecordIdentifier field's value. +func (s *ListResourceRecordSetsInput) SetStartRecordIdentifier(v string) *ListResourceRecordSetsInput { + s.StartRecordIdentifier = &v + return s +} + +// SetStartRecordName sets the StartRecordName field's value. +func (s *ListResourceRecordSetsInput) SetStartRecordName(v string) *ListResourceRecordSetsInput { + s.StartRecordName = &v + return s +} + +// SetStartRecordType sets the StartRecordType field's value. +func (s *ListResourceRecordSetsInput) SetStartRecordType(v string) *ListResourceRecordSetsInput { + s.StartRecordType = &v + return s +} + +// A complex type that contains list information for the resource record set. +type ListResourceRecordSetsOutput struct { + _ struct{} `type:"structure"` + + // A flag that indicates whether more resource record sets remain to be listed. + // If your results were truncated, you can make a follow-up pagination request + // by using the NextRecordName element. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // The maximum number of records you requested. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // Resource record sets that have a routing policy other than simple: If results + // were truncated for a given DNS name and type, the value of SetIdentifier + // for the next resource record set that has the current DNS name and type. + // + // For information about routing policies, see Choosing a Routing Policy (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html) + // in the Amazon Route 53 Developer Guide. + NextRecordIdentifier *string `min:"1" type:"string"` + + // If the results were truncated, the name of the next record in the list. + // + // This element is present only if IsTruncated is true. + NextRecordName *string `type:"string"` + + // If the results were truncated, the type of the next record in the list. + // + // This element is present only if IsTruncated is true. + NextRecordType *string `type:"string" enum:"RRType"` + + // Information about multiple resource record sets. + // + // ResourceRecordSets is a required field + ResourceRecordSets []*ResourceRecordSet `locationNameList:"ResourceRecordSet" type:"list" required:"true"` +} + +// String returns the string representation +func (s ListResourceRecordSetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListResourceRecordSetsOutput) GoString() string { + return s.String() +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListResourceRecordSetsOutput) SetIsTruncated(v bool) *ListResourceRecordSetsOutput { + s.IsTruncated = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListResourceRecordSetsOutput) SetMaxItems(v string) *ListResourceRecordSetsOutput { + s.MaxItems = &v + return s +} + +// SetNextRecordIdentifier sets the NextRecordIdentifier field's value. +func (s *ListResourceRecordSetsOutput) SetNextRecordIdentifier(v string) *ListResourceRecordSetsOutput { + s.NextRecordIdentifier = &v + return s +} + +// SetNextRecordName sets the NextRecordName field's value. +func (s *ListResourceRecordSetsOutput) SetNextRecordName(v string) *ListResourceRecordSetsOutput { + s.NextRecordName = &v + return s +} + +// SetNextRecordType sets the NextRecordType field's value. +func (s *ListResourceRecordSetsOutput) SetNextRecordType(v string) *ListResourceRecordSetsOutput { + s.NextRecordType = &v + return s +} + +// SetResourceRecordSets sets the ResourceRecordSets field's value. +func (s *ListResourceRecordSetsOutput) SetResourceRecordSets(v []*ResourceRecordSet) *ListResourceRecordSetsOutput { + s.ResourceRecordSets = v + return s +} + +// A request to get a list of the reusable delegation sets that are associated +// with the current AWS account. +type ListReusableDelegationSetsInput struct { + _ struct{} `type:"structure"` + + // If the value of IsTruncated in the previous response was true, you have more + // reusable delegation sets. To get another group, submit another ListReusableDelegationSets + // request. + // + // For the value of marker, specify the value of NextMarker from the previous + // response, which is the ID of the first reusable delegation set that Amazon + // Route 53 will return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more reusable delegation sets to get. + Marker *string `location:"querystring" locationName:"marker" type:"string"` + + // The number of reusable delegation sets that you want Amazon Route 53 to return + // in the response to this request. If you specify a value greater than 100, + // Route 53 returns only the first 100 reusable delegation sets. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` +} + +// String returns the string representation +func (s ListReusableDelegationSetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListReusableDelegationSetsInput) GoString() string { + return s.String() +} + +// SetMarker sets the Marker field's value. +func (s *ListReusableDelegationSetsInput) SetMarker(v string) *ListReusableDelegationSetsInput { + s.Marker = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListReusableDelegationSetsInput) SetMaxItems(v string) *ListReusableDelegationSetsInput { + s.MaxItems = &v + return s +} + +// A complex type that contains information about the reusable delegation sets +// that are associated with the current AWS account. +type ListReusableDelegationSetsOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains one DelegationSet element for each reusable + // delegation set that was created by the current AWS account. + // + // DelegationSets is a required field + DelegationSets []*DelegationSet `locationNameList:"DelegationSet" type:"list" required:"true"` + + // A flag that indicates whether there are more reusable delegation sets to + // be listed. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // For the second and subsequent calls to ListReusableDelegationSets, Marker + // is the value that you specified for the marker parameter in the request that + // produced the current response. + // + // Marker is a required field + Marker *string `type:"string" required:"true"` + + // The value that you specified for the maxitems parameter in the call to ListReusableDelegationSets + // that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If IsTruncated is true, the value of NextMarker identifies the next reusable + // delegation set that Amazon Route 53 will return if you submit another ListReusableDelegationSets + // request and specify the value of NextMarker in the marker parameter. + NextMarker *string `type:"string"` +} + +// String returns the string representation +func (s ListReusableDelegationSetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListReusableDelegationSetsOutput) GoString() string { + return s.String() +} + +// SetDelegationSets sets the DelegationSets field's value. +func (s *ListReusableDelegationSetsOutput) SetDelegationSets(v []*DelegationSet) *ListReusableDelegationSetsOutput { + s.DelegationSets = v + return s +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListReusableDelegationSetsOutput) SetIsTruncated(v bool) *ListReusableDelegationSetsOutput { + s.IsTruncated = &v + return s +} + +// SetMarker sets the Marker field's value. +func (s *ListReusableDelegationSetsOutput) SetMarker(v string) *ListReusableDelegationSetsOutput { + s.Marker = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListReusableDelegationSetsOutput) SetMaxItems(v string) *ListReusableDelegationSetsOutput { + s.MaxItems = &v + return s +} + +// SetNextMarker sets the NextMarker field's value. +func (s *ListReusableDelegationSetsOutput) SetNextMarker(v string) *ListReusableDelegationSetsOutput { + s.NextMarker = &v + return s +} + +// A complex type containing information about a request for a list of the tags +// that are associated with an individual resource. +type ListTagsForResourceInput struct { + _ struct{} `type:"structure"` + + // The ID of the resource for which you want to retrieve tags. + // + // ResourceId is a required field + ResourceId *string `location:"uri" locationName:"ResourceId" type:"string" required:"true"` + + // The type of the resource. + // + // * The resource type for health checks is healthcheck. + // + // * The resource type for hosted zones is hostedzone. + // + // ResourceType is a required field + ResourceType *string `location:"uri" locationName:"ResourceType" type:"string" required:"true" enum:"TagResourceType"` +} + +// String returns the string representation +func (s ListTagsForResourceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTagsForResourceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTagsForResourceInput"} + if s.ResourceId == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceId")) + } + if s.ResourceId != nil && len(*s.ResourceId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceId", 1)) + } + if s.ResourceType == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceType")) + } + if s.ResourceType != nil && len(*s.ResourceType) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceType", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceId sets the ResourceId field's value. +func (s *ListTagsForResourceInput) SetResourceId(v string) *ListTagsForResourceInput { + s.ResourceId = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *ListTagsForResourceInput) SetResourceType(v string) *ListTagsForResourceInput { + s.ResourceType = &v + return s +} + +// A complex type that contains information about the health checks or hosted +// zones for which you want to list tags. +type ListTagsForResourceOutput struct { + _ struct{} `type:"structure"` + + // A ResourceTagSet containing tags associated with the specified resource. + // + // ResourceTagSet is a required field + ResourceTagSet *ResourceTagSet `type:"structure" required:"true"` +} + +// String returns the string representation +func (s ListTagsForResourceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourceOutput) GoString() string { + return s.String() +} + +// SetResourceTagSet sets the ResourceTagSet field's value. +func (s *ListTagsForResourceOutput) SetResourceTagSet(v *ResourceTagSet) *ListTagsForResourceOutput { + s.ResourceTagSet = v + return s +} + +// A complex type that contains information about the health checks or hosted +// zones for which you want to list tags. +type ListTagsForResourcesInput struct { + _ struct{} `locationName:"ListTagsForResourcesRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // A complex type that contains the ResourceId element for each resource for + // which you want to get a list of tags. + // + // ResourceIds is a required field + ResourceIds []*string `locationNameList:"ResourceId" min:"1" type:"list" required:"true"` + + // The type of the resources. + // + // * The resource type for health checks is healthcheck. + // + // * The resource type for hosted zones is hostedzone. + // + // ResourceType is a required field + ResourceType *string `location:"uri" locationName:"ResourceType" type:"string" required:"true" enum:"TagResourceType"` +} + +// String returns the string representation +func (s ListTagsForResourcesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourcesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTagsForResourcesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTagsForResourcesInput"} + if s.ResourceIds == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceIds")) + } + if s.ResourceIds != nil && len(s.ResourceIds) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceIds", 1)) + } + if s.ResourceType == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceType")) + } + if s.ResourceType != nil && len(*s.ResourceType) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceType", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetResourceIds sets the ResourceIds field's value. +func (s *ListTagsForResourcesInput) SetResourceIds(v []*string) *ListTagsForResourcesInput { + s.ResourceIds = v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *ListTagsForResourcesInput) SetResourceType(v string) *ListTagsForResourcesInput { + s.ResourceType = &v + return s +} + +// A complex type containing tags for the specified resources. +type ListTagsForResourcesOutput struct { + _ struct{} `type:"structure"` + + // A list of ResourceTagSets containing tags associated with the specified resources. + // + // ResourceTagSets is a required field + ResourceTagSets []*ResourceTagSet `locationNameList:"ResourceTagSet" type:"list" required:"true"` +} + +// String returns the string representation +func (s ListTagsForResourcesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTagsForResourcesOutput) GoString() string { + return s.String() +} + +// SetResourceTagSets sets the ResourceTagSets field's value. +func (s *ListTagsForResourcesOutput) SetResourceTagSets(v []*ResourceTagSet) *ListTagsForResourcesOutput { + s.ResourceTagSets = v + return s +} + +// A complex type that contains the information about the request to list the +// traffic policies that are associated with the current AWS account. +type ListTrafficPoliciesInput struct { + _ struct{} `type:"structure"` + + // (Optional) The maximum number of traffic policies that you want Amazon Route + // 53 to return in response to this request. If you have more than MaxItems + // traffic policies, the value of IsTruncated in the response is true, and the + // value of TrafficPolicyIdMarker is the ID of the first traffic policy that + // Route 53 will return if you submit another request. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` + + // (Conditional) For your first request to ListTrafficPolicies, don't include + // the TrafficPolicyIdMarker parameter. + // + // If you have more traffic policies than the value of MaxItems, ListTrafficPolicies + // returns only the first MaxItems traffic policies. To get the next group of + // policies, submit another request to ListTrafficPolicies. For the value of + // TrafficPolicyIdMarker, specify the value of TrafficPolicyIdMarker that was + // returned in the previous response. + TrafficPolicyIdMarker *string `location:"querystring" locationName:"trafficpolicyid" min:"1" type:"string"` +} + +// String returns the string representation +func (s ListTrafficPoliciesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPoliciesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTrafficPoliciesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTrafficPoliciesInput"} + if s.TrafficPolicyIdMarker != nil && len(*s.TrafficPolicyIdMarker) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TrafficPolicyIdMarker", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPoliciesInput) SetMaxItems(v string) *ListTrafficPoliciesInput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyIdMarker sets the TrafficPolicyIdMarker field's value. +func (s *ListTrafficPoliciesInput) SetTrafficPolicyIdMarker(v string) *ListTrafficPoliciesInput { + s.TrafficPolicyIdMarker = &v + return s +} + +// A complex type that contains the response information for the request. +type ListTrafficPoliciesOutput struct { + _ struct{} `type:"structure"` + + // A flag that indicates whether there are more traffic policies to be listed. + // If the response was truncated, you can get the next group of traffic policies + // by submitting another ListTrafficPolicies request and specifying the value + // of TrafficPolicyIdMarker in the TrafficPolicyIdMarker request parameter. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // The value that you specified for the MaxItems parameter in the ListTrafficPolicies + // request that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If the value of IsTruncated is true, TrafficPolicyIdMarker is the ID of the + // first traffic policy in the next group of MaxItems traffic policies. + // + // TrafficPolicyIdMarker is a required field + TrafficPolicyIdMarker *string `min:"1" type:"string" required:"true"` + + // A list that contains one TrafficPolicySummary element for each traffic policy + // that was created by the current AWS account. + // + // TrafficPolicySummaries is a required field + TrafficPolicySummaries []*TrafficPolicySummary `locationNameList:"TrafficPolicySummary" type:"list" required:"true"` +} + +// String returns the string representation +func (s ListTrafficPoliciesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPoliciesOutput) GoString() string { + return s.String() +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListTrafficPoliciesOutput) SetIsTruncated(v bool) *ListTrafficPoliciesOutput { + s.IsTruncated = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPoliciesOutput) SetMaxItems(v string) *ListTrafficPoliciesOutput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyIdMarker sets the TrafficPolicyIdMarker field's value. +func (s *ListTrafficPoliciesOutput) SetTrafficPolicyIdMarker(v string) *ListTrafficPoliciesOutput { + s.TrafficPolicyIdMarker = &v + return s +} + +// SetTrafficPolicySummaries sets the TrafficPolicySummaries field's value. +func (s *ListTrafficPoliciesOutput) SetTrafficPolicySummaries(v []*TrafficPolicySummary) *ListTrafficPoliciesOutput { + s.TrafficPolicySummaries = v + return s +} + +// A request for the traffic policy instances that you created in a specified +// hosted zone. +type ListTrafficPolicyInstancesByHostedZoneInput struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone that you want to list traffic policy instances + // for. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"querystring" locationName:"id" type:"string" required:"true"` + + // The maximum number of traffic policy instances to be included in the response + // body for this request. If you have more than MaxItems traffic policy instances, + // the value of the IsTruncated element in the response is true, and the values + // of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker + // represent the first traffic policy instance that Amazon Route 53 will return + // if you submit another request. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` + + // If the value of IsTruncated in the previous response is true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of trafficpolicyinstancename, + // specify the value of TrafficPolicyInstanceNameMarker from the previous response, + // which is the name of the first traffic policy instance in the next group + // of traffic policy instances. + // + // If the value of IsTruncated in the previous response was false, there are + // no more traffic policy instances to get. + TrafficPolicyInstanceNameMarker *string `location:"querystring" locationName:"trafficpolicyinstancename" type:"string"` + + // If the value of IsTruncated in the previous response is true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of trafficpolicyinstancetype, + // specify the value of TrafficPolicyInstanceTypeMarker from the previous response, + // which is the type of the first traffic policy instance in the next group + // of traffic policy instances. + // + // If the value of IsTruncated in the previous response was false, there are + // no more traffic policy instances to get. + TrafficPolicyInstanceTypeMarker *string `location:"querystring" locationName:"trafficpolicyinstancetype" type:"string" enum:"RRType"` +} + +// String returns the string representation +func (s ListTrafficPolicyInstancesByHostedZoneInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPolicyInstancesByHostedZoneInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTrafficPolicyInstancesByHostedZoneInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTrafficPolicyInstancesByHostedZoneInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneInput) SetHostedZoneId(v string) *ListTrafficPolicyInstancesByHostedZoneInput { + s.HostedZoneId = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneInput) SetMaxItems(v string) *ListTrafficPolicyInstancesByHostedZoneInput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyInstanceNameMarker sets the TrafficPolicyInstanceNameMarker field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneInput) SetTrafficPolicyInstanceNameMarker(v string) *ListTrafficPolicyInstancesByHostedZoneInput { + s.TrafficPolicyInstanceNameMarker = &v + return s +} + +// SetTrafficPolicyInstanceTypeMarker sets the TrafficPolicyInstanceTypeMarker field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneInput) SetTrafficPolicyInstanceTypeMarker(v string) *ListTrafficPolicyInstancesByHostedZoneInput { + s.TrafficPolicyInstanceTypeMarker = &v + return s +} + +// A complex type that contains the response information for the request. +type ListTrafficPolicyInstancesByHostedZoneOutput struct { + _ struct{} `type:"structure"` + + // A flag that indicates whether there are more traffic policy instances to + // be listed. If the response was truncated, you can get the next group of traffic + // policy instances by submitting another ListTrafficPolicyInstancesByHostedZone + // request and specifying the values of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, + // and TrafficPolicyInstanceTypeMarker in the corresponding request parameters. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // The value that you specified for the MaxItems parameter in the ListTrafficPolicyInstancesByHostedZone + // request that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If IsTruncated is true, TrafficPolicyInstanceNameMarker is the name of the + // first traffic policy instance in the next group of traffic policy instances. + TrafficPolicyInstanceNameMarker *string `type:"string"` + + // If IsTruncated is true, TrafficPolicyInstanceTypeMarker is the DNS type of + // the resource record sets that are associated with the first traffic policy + // instance in the next group of traffic policy instances. + TrafficPolicyInstanceTypeMarker *string `type:"string" enum:"RRType"` + + // A list that contains one TrafficPolicyInstance element for each traffic policy + // instance that matches the elements in the request. + // + // TrafficPolicyInstances is a required field + TrafficPolicyInstances []*TrafficPolicyInstance `locationNameList:"TrafficPolicyInstance" type:"list" required:"true"` +} + +// String returns the string representation +func (s ListTrafficPolicyInstancesByHostedZoneOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPolicyInstancesByHostedZoneOutput) GoString() string { + return s.String() +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneOutput) SetIsTruncated(v bool) *ListTrafficPolicyInstancesByHostedZoneOutput { + s.IsTruncated = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneOutput) SetMaxItems(v string) *ListTrafficPolicyInstancesByHostedZoneOutput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyInstanceNameMarker sets the TrafficPolicyInstanceNameMarker field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneOutput) SetTrafficPolicyInstanceNameMarker(v string) *ListTrafficPolicyInstancesByHostedZoneOutput { + s.TrafficPolicyInstanceNameMarker = &v + return s +} + +// SetTrafficPolicyInstanceTypeMarker sets the TrafficPolicyInstanceTypeMarker field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneOutput) SetTrafficPolicyInstanceTypeMarker(v string) *ListTrafficPolicyInstancesByHostedZoneOutput { + s.TrafficPolicyInstanceTypeMarker = &v + return s +} + +// SetTrafficPolicyInstances sets the TrafficPolicyInstances field's value. +func (s *ListTrafficPolicyInstancesByHostedZoneOutput) SetTrafficPolicyInstances(v []*TrafficPolicyInstance) *ListTrafficPolicyInstancesByHostedZoneOutput { + s.TrafficPolicyInstances = v + return s +} + +// A complex type that contains the information about the request to list your +// traffic policy instances. +type ListTrafficPolicyInstancesByPolicyInput struct { + _ struct{} `type:"structure"` + + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstancesByPolicy request. + // + // For the value of hostedzoneid, specify the value of HostedZoneIdMarker from + // the previous response, which is the hosted zone ID of the first traffic policy + // instance that Amazon Route 53 will return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more traffic policy instances to get. + HostedZoneIdMarker *string `location:"querystring" locationName:"hostedzoneid" type:"string"` + + // The maximum number of traffic policy instances to be included in the response + // body for this request. If you have more than MaxItems traffic policy instances, + // the value of the IsTruncated element in the response is true, and the values + // of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker + // represent the first traffic policy instance that Amazon Route 53 will return + // if you submit another request. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` + + // The ID of the traffic policy for which you want to list traffic policy instances. + // + // TrafficPolicyId is a required field + TrafficPolicyId *string `location:"querystring" locationName:"id" min:"1" type:"string" required:"true"` + + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstancesByPolicy request. + // + // For the value of trafficpolicyinstancename, specify the value of TrafficPolicyInstanceNameMarker + // from the previous response, which is the name of the first traffic policy + // instance that Amazon Route 53 will return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more traffic policy instances to get. + TrafficPolicyInstanceNameMarker *string `location:"querystring" locationName:"trafficpolicyinstancename" type:"string"` + + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstancesByPolicy request. + // + // For the value of trafficpolicyinstancetype, specify the value of TrafficPolicyInstanceTypeMarker + // from the previous response, which is the name of the first traffic policy + // instance that Amazon Route 53 will return if you submit another request. + // + // If the value of IsTruncated in the previous response was false, there are + // no more traffic policy instances to get. + TrafficPolicyInstanceTypeMarker *string `location:"querystring" locationName:"trafficpolicyinstancetype" type:"string" enum:"RRType"` + + // The version of the traffic policy for which you want to list traffic policy + // instances. The version must be associated with the traffic policy that is + // specified by TrafficPolicyId. + // + // TrafficPolicyVersion is a required field + TrafficPolicyVersion *int64 `location:"querystring" locationName:"version" min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s ListTrafficPolicyInstancesByPolicyInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPolicyInstancesByPolicyInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTrafficPolicyInstancesByPolicyInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTrafficPolicyInstancesByPolicyInput"} + if s.TrafficPolicyId == nil { + invalidParams.Add(request.NewErrParamRequired("TrafficPolicyId")) + } + if s.TrafficPolicyId != nil && len(*s.TrafficPolicyId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TrafficPolicyId", 1)) + } + if s.TrafficPolicyVersion == nil { + invalidParams.Add(request.NewErrParamRequired("TrafficPolicyVersion")) + } + if s.TrafficPolicyVersion != nil && *s.TrafficPolicyVersion < 1 { + invalidParams.Add(request.NewErrParamMinValue("TrafficPolicyVersion", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHostedZoneIdMarker sets the HostedZoneIdMarker field's value. +func (s *ListTrafficPolicyInstancesByPolicyInput) SetHostedZoneIdMarker(v string) *ListTrafficPolicyInstancesByPolicyInput { + s.HostedZoneIdMarker = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPolicyInstancesByPolicyInput) SetMaxItems(v string) *ListTrafficPolicyInstancesByPolicyInput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyId sets the TrafficPolicyId field's value. +func (s *ListTrafficPolicyInstancesByPolicyInput) SetTrafficPolicyId(v string) *ListTrafficPolicyInstancesByPolicyInput { + s.TrafficPolicyId = &v + return s +} + +// SetTrafficPolicyInstanceNameMarker sets the TrafficPolicyInstanceNameMarker field's value. +func (s *ListTrafficPolicyInstancesByPolicyInput) SetTrafficPolicyInstanceNameMarker(v string) *ListTrafficPolicyInstancesByPolicyInput { + s.TrafficPolicyInstanceNameMarker = &v + return s +} + +// SetTrafficPolicyInstanceTypeMarker sets the TrafficPolicyInstanceTypeMarker field's value. +func (s *ListTrafficPolicyInstancesByPolicyInput) SetTrafficPolicyInstanceTypeMarker(v string) *ListTrafficPolicyInstancesByPolicyInput { + s.TrafficPolicyInstanceTypeMarker = &v + return s +} + +// SetTrafficPolicyVersion sets the TrafficPolicyVersion field's value. +func (s *ListTrafficPolicyInstancesByPolicyInput) SetTrafficPolicyVersion(v int64) *ListTrafficPolicyInstancesByPolicyInput { + s.TrafficPolicyVersion = &v + return s +} + +// A complex type that contains the response information for the request. +type ListTrafficPolicyInstancesByPolicyOutput struct { + _ struct{} `type:"structure"` + + // If IsTruncated is true, HostedZoneIdMarker is the ID of the hosted zone of + // the first traffic policy instance in the next group of traffic policy instances. + HostedZoneIdMarker *string `type:"string"` + + // A flag that indicates whether there are more traffic policy instances to + // be listed. If the response was truncated, you can get the next group of traffic + // policy instances by calling ListTrafficPolicyInstancesByPolicy again and + // specifying the values of the HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, + // and TrafficPolicyInstanceTypeMarker elements in the corresponding request + // parameters. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // The value that you specified for the MaxItems parameter in the call to ListTrafficPolicyInstancesByPolicy + // that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If IsTruncated is true, TrafficPolicyInstanceNameMarker is the name of the + // first traffic policy instance in the next group of MaxItems traffic policy + // instances. + TrafficPolicyInstanceNameMarker *string `type:"string"` + + // If IsTruncated is true, TrafficPolicyInstanceTypeMarker is the DNS type of + // the resource record sets that are associated with the first traffic policy + // instance in the next group of MaxItems traffic policy instances. + TrafficPolicyInstanceTypeMarker *string `type:"string" enum:"RRType"` + + // A list that contains one TrafficPolicyInstance element for each traffic policy + // instance that matches the elements in the request. + // + // TrafficPolicyInstances is a required field + TrafficPolicyInstances []*TrafficPolicyInstance `locationNameList:"TrafficPolicyInstance" type:"list" required:"true"` +} + +// String returns the string representation +func (s ListTrafficPolicyInstancesByPolicyOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPolicyInstancesByPolicyOutput) GoString() string { + return s.String() +} + +// SetHostedZoneIdMarker sets the HostedZoneIdMarker field's value. +func (s *ListTrafficPolicyInstancesByPolicyOutput) SetHostedZoneIdMarker(v string) *ListTrafficPolicyInstancesByPolicyOutput { + s.HostedZoneIdMarker = &v + return s +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListTrafficPolicyInstancesByPolicyOutput) SetIsTruncated(v bool) *ListTrafficPolicyInstancesByPolicyOutput { + s.IsTruncated = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPolicyInstancesByPolicyOutput) SetMaxItems(v string) *ListTrafficPolicyInstancesByPolicyOutput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyInstanceNameMarker sets the TrafficPolicyInstanceNameMarker field's value. +func (s *ListTrafficPolicyInstancesByPolicyOutput) SetTrafficPolicyInstanceNameMarker(v string) *ListTrafficPolicyInstancesByPolicyOutput { + s.TrafficPolicyInstanceNameMarker = &v + return s +} + +// SetTrafficPolicyInstanceTypeMarker sets the TrafficPolicyInstanceTypeMarker field's value. +func (s *ListTrafficPolicyInstancesByPolicyOutput) SetTrafficPolicyInstanceTypeMarker(v string) *ListTrafficPolicyInstancesByPolicyOutput { + s.TrafficPolicyInstanceTypeMarker = &v + return s +} + +// SetTrafficPolicyInstances sets the TrafficPolicyInstances field's value. +func (s *ListTrafficPolicyInstancesByPolicyOutput) SetTrafficPolicyInstances(v []*TrafficPolicyInstance) *ListTrafficPolicyInstancesByPolicyOutput { + s.TrafficPolicyInstances = v + return s +} + +// A request to get information about the traffic policy instances that you +// created by using the current AWS account. +type ListTrafficPolicyInstancesInput struct { + _ struct{} `type:"structure"` + + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of HostedZoneId, specify + // the value of HostedZoneIdMarker from the previous response, which is the + // hosted zone ID of the first traffic policy instance in the next group of + // traffic policy instances. + // + // If the value of IsTruncated in the previous response was false, there are + // no more traffic policy instances to get. + HostedZoneIdMarker *string `location:"querystring" locationName:"hostedzoneid" type:"string"` + + // The maximum number of traffic policy instances that you want Amazon Route + // 53 to return in response to a ListTrafficPolicyInstances request. If you + // have more than MaxItems traffic policy instances, the value of the IsTruncated + // element in the response is true, and the values of HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, + // and TrafficPolicyInstanceTypeMarker represent the first traffic policy instance + // in the next group of MaxItems traffic policy instances. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` + + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of trafficpolicyinstancename, + // specify the value of TrafficPolicyInstanceNameMarker from the previous response, + // which is the name of the first traffic policy instance in the next group + // of traffic policy instances. + // + // If the value of IsTruncated in the previous response was false, there are + // no more traffic policy instances to get. + TrafficPolicyInstanceNameMarker *string `location:"querystring" locationName:"trafficpolicyinstancename" type:"string"` + + // If the value of IsTruncated in the previous response was true, you have more + // traffic policy instances. To get more traffic policy instances, submit another + // ListTrafficPolicyInstances request. For the value of trafficpolicyinstancetype, + // specify the value of TrafficPolicyInstanceTypeMarker from the previous response, + // which is the type of the first traffic policy instance in the next group + // of traffic policy instances. + // + // If the value of IsTruncated in the previous response was false, there are + // no more traffic policy instances to get. + TrafficPolicyInstanceTypeMarker *string `location:"querystring" locationName:"trafficpolicyinstancetype" type:"string" enum:"RRType"` +} + +// String returns the string representation +func (s ListTrafficPolicyInstancesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPolicyInstancesInput) GoString() string { + return s.String() +} + +// SetHostedZoneIdMarker sets the HostedZoneIdMarker field's value. +func (s *ListTrafficPolicyInstancesInput) SetHostedZoneIdMarker(v string) *ListTrafficPolicyInstancesInput { + s.HostedZoneIdMarker = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPolicyInstancesInput) SetMaxItems(v string) *ListTrafficPolicyInstancesInput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyInstanceNameMarker sets the TrafficPolicyInstanceNameMarker field's value. +func (s *ListTrafficPolicyInstancesInput) SetTrafficPolicyInstanceNameMarker(v string) *ListTrafficPolicyInstancesInput { + s.TrafficPolicyInstanceNameMarker = &v + return s +} + +// SetTrafficPolicyInstanceTypeMarker sets the TrafficPolicyInstanceTypeMarker field's value. +func (s *ListTrafficPolicyInstancesInput) SetTrafficPolicyInstanceTypeMarker(v string) *ListTrafficPolicyInstancesInput { + s.TrafficPolicyInstanceTypeMarker = &v + return s +} + +// A complex type that contains the response information for the request. +type ListTrafficPolicyInstancesOutput struct { + _ struct{} `type:"structure"` + + // If IsTruncated is true, HostedZoneIdMarker is the ID of the hosted zone of + // the first traffic policy instance that Route 53 will return if you submit + // another ListTrafficPolicyInstances request. + HostedZoneIdMarker *string `type:"string"` + + // A flag that indicates whether there are more traffic policy instances to + // be listed. If the response was truncated, you can get more traffic policy + // instances by calling ListTrafficPolicyInstances again and specifying the + // values of the HostedZoneIdMarker, TrafficPolicyInstanceNameMarker, and TrafficPolicyInstanceTypeMarker + // in the corresponding request parameters. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // The value that you specified for the MaxItems parameter in the call to ListTrafficPolicyInstances + // that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // If IsTruncated is true, TrafficPolicyInstanceNameMarker is the name of the + // first traffic policy instance that Route 53 will return if you submit another + // ListTrafficPolicyInstances request. + TrafficPolicyInstanceNameMarker *string `type:"string"` + + // If IsTruncated is true, TrafficPolicyInstanceTypeMarker is the DNS type of + // the resource record sets that are associated with the first traffic policy + // instance that Amazon Route 53 will return if you submit another ListTrafficPolicyInstances + // request. + TrafficPolicyInstanceTypeMarker *string `type:"string" enum:"RRType"` + + // A list that contains one TrafficPolicyInstance element for each traffic policy + // instance that matches the elements in the request. + // + // TrafficPolicyInstances is a required field + TrafficPolicyInstances []*TrafficPolicyInstance `locationNameList:"TrafficPolicyInstance" type:"list" required:"true"` +} + +// String returns the string representation +func (s ListTrafficPolicyInstancesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPolicyInstancesOutput) GoString() string { + return s.String() +} + +// SetHostedZoneIdMarker sets the HostedZoneIdMarker field's value. +func (s *ListTrafficPolicyInstancesOutput) SetHostedZoneIdMarker(v string) *ListTrafficPolicyInstancesOutput { + s.HostedZoneIdMarker = &v + return s +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListTrafficPolicyInstancesOutput) SetIsTruncated(v bool) *ListTrafficPolicyInstancesOutput { + s.IsTruncated = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPolicyInstancesOutput) SetMaxItems(v string) *ListTrafficPolicyInstancesOutput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyInstanceNameMarker sets the TrafficPolicyInstanceNameMarker field's value. +func (s *ListTrafficPolicyInstancesOutput) SetTrafficPolicyInstanceNameMarker(v string) *ListTrafficPolicyInstancesOutput { + s.TrafficPolicyInstanceNameMarker = &v + return s +} + +// SetTrafficPolicyInstanceTypeMarker sets the TrafficPolicyInstanceTypeMarker field's value. +func (s *ListTrafficPolicyInstancesOutput) SetTrafficPolicyInstanceTypeMarker(v string) *ListTrafficPolicyInstancesOutput { + s.TrafficPolicyInstanceTypeMarker = &v + return s +} + +// SetTrafficPolicyInstances sets the TrafficPolicyInstances field's value. +func (s *ListTrafficPolicyInstancesOutput) SetTrafficPolicyInstances(v []*TrafficPolicyInstance) *ListTrafficPolicyInstancesOutput { + s.TrafficPolicyInstances = v + return s +} + +// A complex type that contains the information about the request to list your +// traffic policies. +type ListTrafficPolicyVersionsInput struct { + _ struct{} `type:"structure"` + + // Specify the value of Id of the traffic policy for which you want to list + // all versions. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` + + // The maximum number of traffic policy versions that you want Amazon Route + // 53 to include in the response body for this request. If the specified traffic + // policy has more than MaxItems versions, the value of IsTruncated in the response + // is true, and the value of the TrafficPolicyVersionMarker element is the ID + // of the first version that Route 53 will return if you submit another request. + MaxItems *string `location:"querystring" locationName:"maxitems" type:"string"` + + // For your first request to ListTrafficPolicyVersions, don't include the TrafficPolicyVersionMarker + // parameter. + // + // If you have more traffic policy versions than the value of MaxItems, ListTrafficPolicyVersions + // returns only the first group of MaxItems versions. To get more traffic policy + // versions, submit another ListTrafficPolicyVersions request. For the value + // of TrafficPolicyVersionMarker, specify the value of TrafficPolicyVersionMarker + // in the previous response. + TrafficPolicyVersionMarker *string `location:"querystring" locationName:"trafficpolicyversion" type:"string"` +} + +// String returns the string representation +func (s ListTrafficPolicyVersionsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPolicyVersionsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListTrafficPolicyVersionsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListTrafficPolicyVersionsInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *ListTrafficPolicyVersionsInput) SetId(v string) *ListTrafficPolicyVersionsInput { + s.Id = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPolicyVersionsInput) SetMaxItems(v string) *ListTrafficPolicyVersionsInput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicyVersionMarker sets the TrafficPolicyVersionMarker field's value. +func (s *ListTrafficPolicyVersionsInput) SetTrafficPolicyVersionMarker(v string) *ListTrafficPolicyVersionsInput { + s.TrafficPolicyVersionMarker = &v + return s +} + +// A complex type that contains the response information for the request. +type ListTrafficPolicyVersionsOutput struct { + _ struct{} `type:"structure"` + + // A flag that indicates whether there are more traffic policies to be listed. + // If the response was truncated, you can get the next group of traffic policies + // by submitting another ListTrafficPolicyVersions request and specifying the + // value of NextMarker in the marker parameter. + // + // IsTruncated is a required field + IsTruncated *bool `type:"boolean" required:"true"` + + // The value that you specified for the maxitems parameter in the ListTrafficPolicyVersions + // request that produced the current response. + // + // MaxItems is a required field + MaxItems *string `type:"string" required:"true"` + + // A list that contains one TrafficPolicy element for each traffic policy version + // that is associated with the specified traffic policy. + // + // TrafficPolicies is a required field + TrafficPolicies []*TrafficPolicy `locationNameList:"TrafficPolicy" type:"list" required:"true"` + + // If IsTruncated is true, the value of TrafficPolicyVersionMarker identifies + // the first traffic policy that Amazon Route 53 will return if you submit another + // request. Call ListTrafficPolicyVersions again and specify the value of TrafficPolicyVersionMarker + // in the TrafficPolicyVersionMarker request parameter. + // + // This element is present only if IsTruncated is true. + // + // TrafficPolicyVersionMarker is a required field + TrafficPolicyVersionMarker *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ListTrafficPolicyVersionsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListTrafficPolicyVersionsOutput) GoString() string { + return s.String() +} + +// SetIsTruncated sets the IsTruncated field's value. +func (s *ListTrafficPolicyVersionsOutput) SetIsTruncated(v bool) *ListTrafficPolicyVersionsOutput { + s.IsTruncated = &v + return s +} + +// SetMaxItems sets the MaxItems field's value. +func (s *ListTrafficPolicyVersionsOutput) SetMaxItems(v string) *ListTrafficPolicyVersionsOutput { + s.MaxItems = &v + return s +} + +// SetTrafficPolicies sets the TrafficPolicies field's value. +func (s *ListTrafficPolicyVersionsOutput) SetTrafficPolicies(v []*TrafficPolicy) *ListTrafficPolicyVersionsOutput { + s.TrafficPolicies = v + return s +} + +// SetTrafficPolicyVersionMarker sets the TrafficPolicyVersionMarker field's value. +func (s *ListTrafficPolicyVersionsOutput) SetTrafficPolicyVersionMarker(v string) *ListTrafficPolicyVersionsOutput { + s.TrafficPolicyVersionMarker = &v + return s +} + +// A complex type that contains information about that can be associated with +// your hosted zone. +type ListVPCAssociationAuthorizationsInput struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone for which you want a list of VPCs that can be associated + // with the hosted zone. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"uri" locationName:"Id" type:"string" required:"true"` + + // Optional: An integer that specifies the maximum number of VPCs that you want + // Amazon Route 53 to return. If you don't specify a value for MaxResults, Route + // 53 returns up to 50 VPCs per page. + MaxResults *string `location:"querystring" locationName:"maxresults" type:"string"` + + // Optional: If a response includes a NextToken element, there are more VPCs + // that can be associated with the specified hosted zone. To get the next page + // of results, submit another request, and include the value of NextToken from + // the response in the nexttoken parameter in another ListVPCAssociationAuthorizations + // request. + NextToken *string `location:"querystring" locationName:"nexttoken" type:"string"` +} + +// String returns the string representation +func (s ListVPCAssociationAuthorizationsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListVPCAssociationAuthorizationsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ListVPCAssociationAuthorizationsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ListVPCAssociationAuthorizationsInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.HostedZoneId != nil && len(*s.HostedZoneId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HostedZoneId", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *ListVPCAssociationAuthorizationsInput) SetHostedZoneId(v string) *ListVPCAssociationAuthorizationsInput { + s.HostedZoneId = &v + return s +} + +// SetMaxResults sets the MaxResults field's value. +func (s *ListVPCAssociationAuthorizationsInput) SetMaxResults(v string) *ListVPCAssociationAuthorizationsInput { + s.MaxResults = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListVPCAssociationAuthorizationsInput) SetNextToken(v string) *ListVPCAssociationAuthorizationsInput { + s.NextToken = &v + return s +} + +// A complex type that contains the response information for the request. +type ListVPCAssociationAuthorizationsOutput struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone that you can associate the listed VPCs with. + // + // HostedZoneId is a required field + HostedZoneId *string `type:"string" required:"true"` + + // When the response includes a NextToken element, there are more VPCs that + // can be associated with the specified hosted zone. To get the next page of + // VPCs, submit another ListVPCAssociationAuthorizations request, and include + // the value of the NextToken element from the response in the nexttoken request + // parameter. + NextToken *string `type:"string"` + + // The list of VPCs that are authorized to be associated with the specified + // hosted zone. + // + // VPCs is a required field + VPCs []*VPC `locationNameList:"VPC" min:"1" type:"list" required:"true"` +} + +// String returns the string representation +func (s ListVPCAssociationAuthorizationsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ListVPCAssociationAuthorizationsOutput) GoString() string { + return s.String() +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *ListVPCAssociationAuthorizationsOutput) SetHostedZoneId(v string) *ListVPCAssociationAuthorizationsOutput { + s.HostedZoneId = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *ListVPCAssociationAuthorizationsOutput) SetNextToken(v string) *ListVPCAssociationAuthorizationsOutput { + s.NextToken = &v + return s +} + +// SetVPCs sets the VPCs field's value. +func (s *ListVPCAssociationAuthorizationsOutput) SetVPCs(v []*VPC) *ListVPCAssociationAuthorizationsOutput { + s.VPCs = v + return s +} + +// A complex type that contains information about a configuration for DNS query +// logging. +type QueryLoggingConfig struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the CloudWatch Logs log group that Amazon + // Route 53 is publishing logs to. + // + // CloudWatchLogsLogGroupArn is a required field + CloudWatchLogsLogGroupArn *string `type:"string" required:"true"` + + // The ID of the hosted zone that CloudWatch Logs is logging queries for. + // + // HostedZoneId is a required field + HostedZoneId *string `type:"string" required:"true"` + + // The ID for a configuration for DNS query logging. + // + // Id is a required field + Id *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s QueryLoggingConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s QueryLoggingConfig) GoString() string { + return s.String() +} + +// SetCloudWatchLogsLogGroupArn sets the CloudWatchLogsLogGroupArn field's value. +func (s *QueryLoggingConfig) SetCloudWatchLogsLogGroupArn(v string) *QueryLoggingConfig { + s.CloudWatchLogsLogGroupArn = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *QueryLoggingConfig) SetHostedZoneId(v string) *QueryLoggingConfig { + s.HostedZoneId = &v + return s +} + +// SetId sets the Id field's value. +func (s *QueryLoggingConfig) SetId(v string) *QueryLoggingConfig { + s.Id = &v + return s +} + +// Information specific to the resource record. +// +// If you're creating an alias resource record set, omit ResourceRecord. +type ResourceRecord struct { + _ struct{} `type:"structure"` + + // The current or new DNS record value, not to exceed 4,000 characters. In the + // case of a DELETE action, if the current value does not match the actual value, + // an error is returned. For descriptions about how to format Value for different + // record types, see Supported DNS Resource Record Types (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html) + // in the Amazon Route 53 Developer Guide. + // + // You can specify more than one value for all record types except CNAME and + // SOA. + // + // If you're creating an alias resource record set, omit Value. + // + // Value is a required field + Value *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s ResourceRecord) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResourceRecord) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ResourceRecord) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ResourceRecord"} + if s.Value == nil { + invalidParams.Add(request.NewErrParamRequired("Value")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetValue sets the Value field's value. +func (s *ResourceRecord) SetValue(v string) *ResourceRecord { + s.Value = &v + return s +} + +// Information about the resource record set to create or delete. +type ResourceRecordSet struct { + _ struct{} `type:"structure"` + + // Alias resource record sets only: Information about the AWS resource, such + // as a CloudFront distribution or an Amazon S3 bucket, that you want to route + // traffic to. + // + // If you're creating resource records sets for a private hosted zone, note + // the following: + // + // * You can't create an alias resource record set in a private hosted zone + // to route traffic to a CloudFront distribution. + // + // * Creating geolocation alias resource record sets or latency alias resource + // record sets in a private hosted zone is unsupported. + // + // * For information about creating failover resource record sets in a private + // hosted zone, see Configuring Failover in a Private Hosted Zone (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-private-hosted-zones.html) + // in the Amazon Route 53 Developer Guide. + AliasTarget *AliasTarget `type:"structure"` + + // Failover resource record sets only: To configure failover, you add the Failover + // element to two resource record sets. For one resource record set, you specify + // PRIMARY as the value for Failover; for the other resource record set, you + // specify SECONDARY. In addition, you include the HealthCheckId element and + // specify the health check that you want Amazon Route 53 to perform for each + // resource record set. + // + // Except where noted, the following failover behaviors assume that you have + // included the HealthCheckId element in both resource record sets: + // + // * When the primary resource record set is healthy, Route 53 responds to + // DNS queries with the applicable value from the primary resource record + // set regardless of the health of the secondary resource record set. + // + // * When the primary resource record set is unhealthy and the secondary + // resource record set is healthy, Route 53 responds to DNS queries with + // the applicable value from the secondary resource record set. + // + // * When the secondary resource record set is unhealthy, Route 53 responds + // to DNS queries with the applicable value from the primary resource record + // set regardless of the health of the primary resource record set. + // + // * If you omit the HealthCheckId element for the secondary resource record + // set, and if the primary resource record set is unhealthy, Route 53 always + // responds to DNS queries with the applicable value from the secondary resource + // record set. This is true regardless of the health of the associated endpoint. + // + // You can't create non-failover resource record sets that have the same values + // for the Name and Type elements as failover resource record sets. + // + // For failover alias resource record sets, you must also include the EvaluateTargetHealth + // element and set the value to true. + // + // For more information about configuring failover for Route 53, see the following + // topics in the Amazon Route 53 Developer Guide: + // + // * Route 53 Health Checks and DNS Failover (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover.html) + // + // * Configuring Failover in a Private Hosted Zone (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-private-hosted-zones.html) + Failover *string `type:"string" enum:"ResourceRecordSetFailover"` + + // Geolocation resource record sets only: A complex type that lets you control + // how Amazon Route 53 responds to DNS queries based on the geographic origin + // of the query. For example, if you want all queries from Africa to be routed + // to a web server with an IP address of 192.0.2.111, create a resource record + // set with a Type of A and a ContinentCode of AF. + // + // Creating geolocation and geolocation alias resource record sets in private + // hosted zones is not supported. + // + // If you create separate resource record sets for overlapping geographic regions + // (for example, one resource record set for a continent and one for a country + // on the same continent), priority goes to the smallest geographic region. + // This allows you to route most queries for a continent to one resource and + // to route queries for a country on that continent to a different resource. + // + // You can't create two geolocation resource record sets that specify the same + // geographic location. + // + // The value * in the CountryCode element matches all geographic locations that + // aren't specified in other geolocation resource record sets that have the + // same values for the Name and Type elements. + // + // Geolocation works by mapping IP addresses to locations. However, some IP + // addresses aren't mapped to geographic locations, so even if you create geolocation + // resource record sets that cover all seven continents, Route 53 will receive + // some DNS queries from locations that it can't identify. We recommend that + // you create a resource record set for which the value of CountryCode is *, + // which handles both queries that come from locations for which you haven't + // created geolocation resource record sets and queries from IP addresses that + // aren't mapped to a location. If you don't create a * resource record set, + // Route 53 returns a "no answer" response for queries from those locations. + // + // You can't create non-geolocation resource record sets that have the same + // values for the Name and Type elements as geolocation resource record sets. + GeoLocation *GeoLocation `type:"structure"` + + // If you want Amazon Route 53 to return this resource record set in response + // to a DNS query only when the status of a health check is healthy, include + // the HealthCheckId element and specify the ID of the applicable health check. + // + // Route 53 determines whether a resource record set is healthy based on one + // of the following: + // + // * By periodically sending a request to the endpoint that is specified + // in the health check + // + // * By aggregating the status of a specified group of health checks (calculated + // health checks) + // + // * By determining the current state of a CloudWatch alarm (CloudWatch metric + // health checks) + // + // Route 53 doesn't check the health of the endpoint that is specified in the + // resource record set, for example, the endpoint specified by the IP address + // in the Value element. When you add a HealthCheckId element to a resource + // record set, Route 53 checks the health of the endpoint that you specified + // in the health check. + // + // For more information, see the following topics in the Amazon Route 53 Developer + // Guide: + // + // * How Amazon Route 53 Determines Whether an Endpoint Is Healthy (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-determining-health-of-endpoints.html) + // + // * Route 53 Health Checks and DNS Failover (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover.html) + // + // * Configuring Failover in a Private Hosted Zone (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-private-hosted-zones.html) + // + // When to Specify HealthCheckId + // + // Specifying a value for HealthCheckId is useful only when Route 53 is choosing + // between two or more resource record sets to respond to a DNS query, and you + // want Route 53 to base the choice in part on the status of a health check. + // Configuring health checks makes sense only in the following configurations: + // + // * Non-alias resource record sets: You're checking the health of a group + // of non-alias resource record sets that have the same routing policy, name, + // and type (such as multiple weighted records named www.example.com with + // a type of A) and you specify health check IDs for all the resource record + // sets. If the health check status for a resource record set is healthy, + // Route 53 includes the record among the records that it responds to DNS + // queries with. If the health check status for a resource record set is + // unhealthy, Route 53 stops responding to DNS queries using the value for + // that resource record set. If the health check status for all resource + // record sets in the group is unhealthy, Route 53 considers all resource + // record sets in the group healthy and responds to DNS queries accordingly. + // + // * Alias resource record sets: You specify the following settings: You + // set EvaluateTargetHealth to true for an alias resource record set in a + // group of resource record sets that have the same routing policy, name, + // and type (such as multiple weighted records named www.example.com with + // a type of A). You configure the alias resource record set to route traffic + // to a non-alias resource record set in the same hosted zone. You specify + // a health check ID for the non-alias resource record set. If the health + // check status is healthy, Route 53 considers the alias resource record + // set to be healthy and includes the alias record among the records that + // it responds to DNS queries with. If the health check status is unhealthy, + // Route 53 stops responding to DNS queries using the alias resource record + // set. The alias resource record set can also route traffic to a group of + // non-alias resource record sets that have the same routing policy, name, + // and type. In that configuration, associate health checks with all of the + // resource record sets in the group of non-alias resource record sets. + // + // Geolocation Routing + // + // For geolocation resource record sets, if an endpoint is unhealthy, Route + // 53 looks for a resource record set for the larger, associated geographic + // region. For example, suppose you have resource record sets for a state in + // the United States, for the entire United States, for North America, and a + // resource record set that has * for CountryCode is *, which applies to all + // locations. If the endpoint for the state resource record set is unhealthy, + // Route 53 checks for healthy resource record sets in the following order until + // it finds a resource record set for which the endpoint is healthy: + // + // * The United States + // + // * North America + // + // * The default resource record set + // + // Specifying the Health Check Endpoint by Domain Name + // + // If your health checks specify the endpoint only by domain name, we recommend + // that you create a separate health check for each endpoint. For example, create + // a health check for each HTTP server that is serving content for www.example.com. + // For the value of FullyQualifiedDomainName, specify the domain name of the + // server (such as us-east-2-www.example.com), not the name of the resource + // record sets (www.example.com). + // + // Health check results will be unpredictable if you do the following: + // + // * Create a health check that has the same value for FullyQualifiedDomainName + // as the name of a resource record set. + // + // * Associate that health check with the resource record set. + HealthCheckId *string `type:"string"` + + // Multivalue answer resource record sets only: To route traffic approximately + // randomly to multiple resources, such as web servers, create one multivalue + // answer record for each resource and specify true for MultiValueAnswer. Note + // the following: + // + // * If you associate a health check with a multivalue answer resource record + // set, Amazon Route 53 responds to DNS queries with the corresponding IP + // address only when the health check is healthy. + // + // * If you don't associate a health check with a multivalue answer record, + // Route 53 always considers the record to be healthy. + // + // * Route 53 responds to DNS queries with up to eight healthy records; if + // you have eight or fewer healthy records, Route 53 responds to all DNS + // queries with all the healthy records. + // + // * If you have more than eight healthy records, Route 53 responds to different + // DNS resolvers with different combinations of healthy records. + // + // * When all records are unhealthy, Route 53 responds to DNS queries with + // up to eight unhealthy records. + // + // * If a resource becomes unavailable after a resolver caches a response, + // client software typically tries another of the IP addresses in the response. + // + // You can't create multivalue answer alias records. + MultiValueAnswer *bool `type:"boolean"` + + // For ChangeResourceRecordSets requests, the name of the record that you want + // to create, update, or delete. For ListResourceRecordSets responses, the name + // of a record in the specified hosted zone. + // + // ChangeResourceRecordSets Only + // + // Enter a fully qualified domain name, for example, www.example.com. You can + // optionally include a trailing dot. If you omit the trailing dot, Amazon Route + // 53 assumes that the domain name that you specify is fully qualified. This + // means that Route 53 treats www.example.com (without a trailing dot) and www.example.com. + // (with a trailing dot) as identical. + // + // For information about how to specify characters other than a-z, 0-9, and + // - (hyphen) and how to specify internationalized domain names, see DNS Domain + // Name Format (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DomainNameFormat.html) + // in the Amazon Route 53 Developer Guide. + // + // You can use the asterisk (*) wildcard to replace the leftmost label in a + // domain name, for example, *.example.com. Note the following: + // + // * The * must replace the entire label. For example, you can't specify + // *prod.example.com or prod*.example.com. + // + // * The * can't replace any of the middle labels, for example, marketing.*.example.com. + // + // * If you include * in any position other than the leftmost label in a + // domain name, DNS treats it as an * character (ASCII 42), not as a wildcard. + // You can't use the * wildcard for resource records sets that have a type + // of NS. + // + // You can use the * wildcard as the leftmost label in a domain name, for example, + // *.example.com. You can't use an * for one of the middle labels, for example, + // marketing.*.example.com. In addition, the * must replace the entire label; + // for example, you can't specify prod*.example.com. + // + // Name is a required field + Name *string `type:"string" required:"true"` + + // Latency-based resource record sets only: The Amazon EC2 Region where you + // created the resource that this resource record set refers to. The resource + // typically is an AWS resource, such as an EC2 instance or an ELB load balancer, + // and is referred to by an IP address or a DNS domain name, depending on the + // record type. + // + // Creating latency and latency alias resource record sets in private hosted + // zones is not supported. + // + // When Amazon Route 53 receives a DNS query for a domain name and type for + // which you have created latency resource record sets, Route 53 selects the + // latency resource record set that has the lowest latency between the end user + // and the associated Amazon EC2 Region. Route 53 then returns the value that + // is associated with the selected resource record set. + // + // Note the following: + // + // * You can only specify one ResourceRecord per latency resource record + // set. + // + // * You can only create one latency resource record set for each Amazon + // EC2 Region. + // + // * You aren't required to create latency resource record sets for all Amazon + // EC2 Regions. Route 53 will choose the region with the best latency from + // among the regions that you create latency resource record sets for. + // + // * You can't create non-latency resource record sets that have the same + // values for the Name and Type elements as latency resource record sets. + Region *string `min:"1" type:"string" enum:"ResourceRecordSetRegion"` + + // Information about the resource records to act upon. + // + // If you're creating an alias resource record set, omit ResourceRecords. + ResourceRecords []*ResourceRecord `locationNameList:"ResourceRecord" min:"1" type:"list"` + + // Resource record sets that have a routing policy other than simple: An identifier + // that differentiates among multiple resource record sets that have the same + // combination of name and type, such as multiple weighted resource record sets + // named acme.example.com that have a type of A. In a group of resource record + // sets that have the same name and type, the value of SetIdentifier must be + // unique for each resource record set. + // + // For information about routing policies, see Choosing a Routing Policy (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html) + // in the Amazon Route 53 Developer Guide. + SetIdentifier *string `min:"1" type:"string"` + + // The resource record cache time to live (TTL), in seconds. Note the following: + // + // * If you're creating or updating an alias resource record set, omit TTL. + // Amazon Route 53 uses the value of TTL for the alias target. + // + // * If you're associating this resource record set with a health check (if + // you're adding a HealthCheckId element), we recommend that you specify + // a TTL of 60 seconds or less so clients respond quickly to changes in health + // status. + // + // * All of the resource record sets in a group of weighted resource record + // sets must have the same value for TTL. + // + // * If a group of weighted resource record sets includes one or more weighted + // alias resource record sets for which the alias target is an ELB load balancer, + // we recommend that you specify a TTL of 60 seconds for all of the non-alias + // weighted resource record sets that have the same name and type. Values + // other than 60 seconds (the TTL for load balancers) will change the effect + // of the values that you specify for Weight. + TTL *int64 `type:"long"` + + // When you create a traffic policy instance, Amazon Route 53 automatically + // creates a resource record set. TrafficPolicyInstanceId is the ID of the traffic + // policy instance that Route 53 created this resource record set for. + // + // To delete the resource record set that is associated with a traffic policy + // instance, use DeleteTrafficPolicyInstance. Route 53 will delete the resource + // record set automatically. If you delete the resource record set by using + // ChangeResourceRecordSets, Route 53 doesn't automatically delete the traffic + // policy instance, and you'll continue to be charged for it even though it's + // no longer in use. + TrafficPolicyInstanceId *string `min:"1" type:"string"` + + // The DNS record type. For information about different record types and how + // data is encoded for them, see Supported DNS Resource Record Types (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html) + // in the Amazon Route 53 Developer Guide. + // + // Valid values for basic resource record sets: A | AAAA | CAA | CNAME | MX + // | NAPTR | NS | PTR | SOA | SPF | SRV | TXT + // + // Values for weighted, latency, geolocation, and failover resource record sets: + // A | AAAA | CAA | CNAME | MX | NAPTR | PTR | SPF | SRV | TXT. When creating + // a group of weighted, latency, geolocation, or failover resource record sets, + // specify the same value for all of the resource record sets in the group. + // + // Valid values for multivalue answer resource record sets: A | AAAA | MX | + // NAPTR | PTR | SPF | SRV | TXT + // + // SPF records were formerly used to verify the identity of the sender of email + // messages. However, we no longer recommend that you create resource record + // sets for which the value of Type is SPF. RFC 7208, Sender Policy Framework + // (SPF) for Authorizing Use of Domains in Email, Version 1, has been updated + // to say, "...[I]ts existence and mechanism defined in [RFC4408] have led to + // some interoperability issues. Accordingly, its use is no longer appropriate + // for SPF version 1; implementations are not to use it." In RFC 7208, see section + // 14.1, The SPF DNS Record Type (http://tools.ietf.org/html/rfc7208#section-14.1). + // + // Values for alias resource record sets: + // + // * Amazon API Gateway custom regional APIs and edge-optimized APIs: A + // + // * CloudFront distributions: A If IPv6 is enabled for the distribution, + // create two resource record sets to route traffic to your distribution, + // one with a value of A and one with a value of AAAA. + // + // * AWS Elastic Beanstalk environment that has a regionalized subdomain: + // A + // + // * ELB load balancers: A | AAAA + // + // * Amazon S3 buckets: A + // + // * Amazon Virtual Private Cloud interface VPC endpoints A + // + // * Another resource record set in this hosted zone: Specify the type of + // the resource record set that you're creating the alias for. All values + // are supported except NS and SOA. If you're creating an alias record that + // has the same name as the hosted zone (known as the zone apex), you can't + // route traffic to a record for which the value of Type is CNAME. This is + // because the alias record must have the same type as the record you're + // routing traffic to, and creating a CNAME record for the zone apex isn't + // supported even for an alias record. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"RRType"` + + // Weighted resource record sets only: Among resource record sets that have + // the same combination of DNS name and type, a value that determines the proportion + // of DNS queries that Amazon Route 53 responds to using the current resource + // record set. Route 53 calculates the sum of the weights for the resource record + // sets that have the same combination of DNS name and type. Route 53 then responds + // to queries based on the ratio of a resource's weight to the total. Note the + // following: + // + // * You must specify a value for the Weight element for every weighted resource + // record set. + // + // * You can only specify one ResourceRecord per weighted resource record + // set. + // + // * You can't create latency, failover, or geolocation resource record sets + // that have the same values for the Name and Type elements as weighted resource + // record sets. + // + // * You can create a maximum of 100 weighted resource record sets that have + // the same values for the Name and Type elements. + // + // * For weighted (but not weighted alias) resource record sets, if you set + // Weight to 0 for a resource record set, Route 53 never responds to queries + // with the applicable value for that resource record set. However, if you + // set Weight to 0 for all resource record sets that have the same combination + // of DNS name and type, traffic is routed to all resources with equal probability. + // The effect of setting Weight to 0 is different when you associate health + // checks with weighted resource record sets. For more information, see Options + // for Configuring Route 53 Active-Active and Active-Passive Failover (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-configuring-options.html) + // in the Amazon Route 53 Developer Guide. + Weight *int64 `type:"long"` +} + +// String returns the string representation +func (s ResourceRecordSet) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResourceRecordSet) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *ResourceRecordSet) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "ResourceRecordSet"} + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Region != nil && len(*s.Region) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Region", 1)) + } + if s.ResourceRecords != nil && len(s.ResourceRecords) < 1 { + invalidParams.Add(request.NewErrParamMinLen("ResourceRecords", 1)) + } + if s.SetIdentifier != nil && len(*s.SetIdentifier) < 1 { + invalidParams.Add(request.NewErrParamMinLen("SetIdentifier", 1)) + } + if s.TrafficPolicyInstanceId != nil && len(*s.TrafficPolicyInstanceId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TrafficPolicyInstanceId", 1)) + } + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + if s.AliasTarget != nil { + if err := s.AliasTarget.Validate(); err != nil { + invalidParams.AddNested("AliasTarget", err.(request.ErrInvalidParams)) + } + } + if s.GeoLocation != nil { + if err := s.GeoLocation.Validate(); err != nil { + invalidParams.AddNested("GeoLocation", err.(request.ErrInvalidParams)) + } + } + if s.ResourceRecords != nil { + for i, v := range s.ResourceRecords { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ResourceRecords", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAliasTarget sets the AliasTarget field's value. +func (s *ResourceRecordSet) SetAliasTarget(v *AliasTarget) *ResourceRecordSet { + s.AliasTarget = v + return s +} + +// SetFailover sets the Failover field's value. +func (s *ResourceRecordSet) SetFailover(v string) *ResourceRecordSet { + s.Failover = &v + return s +} + +// SetGeoLocation sets the GeoLocation field's value. +func (s *ResourceRecordSet) SetGeoLocation(v *GeoLocation) *ResourceRecordSet { + s.GeoLocation = v + return s +} + +// SetHealthCheckId sets the HealthCheckId field's value. +func (s *ResourceRecordSet) SetHealthCheckId(v string) *ResourceRecordSet { + s.HealthCheckId = &v + return s +} + +// SetMultiValueAnswer sets the MultiValueAnswer field's value. +func (s *ResourceRecordSet) SetMultiValueAnswer(v bool) *ResourceRecordSet { + s.MultiValueAnswer = &v + return s +} + +// SetName sets the Name field's value. +func (s *ResourceRecordSet) SetName(v string) *ResourceRecordSet { + s.Name = &v + return s +} + +// SetRegion sets the Region field's value. +func (s *ResourceRecordSet) SetRegion(v string) *ResourceRecordSet { + s.Region = &v + return s +} + +// SetResourceRecords sets the ResourceRecords field's value. +func (s *ResourceRecordSet) SetResourceRecords(v []*ResourceRecord) *ResourceRecordSet { + s.ResourceRecords = v + return s +} + +// SetSetIdentifier sets the SetIdentifier field's value. +func (s *ResourceRecordSet) SetSetIdentifier(v string) *ResourceRecordSet { + s.SetIdentifier = &v + return s +} + +// SetTTL sets the TTL field's value. +func (s *ResourceRecordSet) SetTTL(v int64) *ResourceRecordSet { + s.TTL = &v + return s +} + +// SetTrafficPolicyInstanceId sets the TrafficPolicyInstanceId field's value. +func (s *ResourceRecordSet) SetTrafficPolicyInstanceId(v string) *ResourceRecordSet { + s.TrafficPolicyInstanceId = &v + return s +} + +// SetType sets the Type field's value. +func (s *ResourceRecordSet) SetType(v string) *ResourceRecordSet { + s.Type = &v + return s +} + +// SetWeight sets the Weight field's value. +func (s *ResourceRecordSet) SetWeight(v int64) *ResourceRecordSet { + s.Weight = &v + return s +} + +// A complex type containing a resource and its associated tags. +type ResourceTagSet struct { + _ struct{} `type:"structure"` + + // The ID for the specified resource. + ResourceId *string `type:"string"` + + // The type of the resource. + // + // * The resource type for health checks is healthcheck. + // + // * The resource type for hosted zones is hostedzone. + ResourceType *string `type:"string" enum:"TagResourceType"` + + // The tags associated with the specified resource. + Tags []*Tag `locationNameList:"Tag" min:"1" type:"list"` +} + +// String returns the string representation +func (s ResourceTagSet) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResourceTagSet) GoString() string { + return s.String() +} + +// SetResourceId sets the ResourceId field's value. +func (s *ResourceTagSet) SetResourceId(v string) *ResourceTagSet { + s.ResourceId = &v + return s +} + +// SetResourceType sets the ResourceType field's value. +func (s *ResourceTagSet) SetResourceType(v string) *ResourceTagSet { + s.ResourceType = &v + return s +} + +// SetTags sets the Tags field's value. +func (s *ResourceTagSet) SetTags(v []*Tag) *ResourceTagSet { + s.Tags = v + return s +} + +// A complex type that contains the type of limit that you specified in the +// request and the current value for that limit. +type ReusableDelegationSetLimit struct { + _ struct{} `type:"structure"` + + // The limit that you requested: MAX_ZONES_BY_REUSABLE_DELEGATION_SET, the maximum + // number of hosted zones that you can associate with the specified reusable + // delegation set. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"ReusableDelegationSetLimitType"` + + // The current value for the MAX_ZONES_BY_REUSABLE_DELEGATION_SET limit. + // + // Value is a required field + Value *int64 `min:"1" type:"long" required:"true"` +} + +// String returns the string representation +func (s ReusableDelegationSetLimit) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ReusableDelegationSetLimit) GoString() string { + return s.String() +} + +// SetType sets the Type field's value. +func (s *ReusableDelegationSetLimit) SetType(v string) *ReusableDelegationSetLimit { + s.Type = &v + return s +} + +// SetValue sets the Value field's value. +func (s *ReusableDelegationSetLimit) SetValue(v int64) *ReusableDelegationSetLimit { + s.Value = &v + return s +} + +// A complex type that contains the status that one Amazon Route 53 health checker +// reports and the time of the health check. +type StatusReport struct { + _ struct{} `type:"structure"` + + // The date and time that the health checker performed the health check in ISO + // 8601 format (https://en.wikipedia.org/wiki/ISO_8601) and Coordinated Universal + // Time (UTC). For example, the value 2017-03-27T17:48:16.751Z represents March + // 27, 2017 at 17:48:16.751 UTC. + CheckedTime *time.Time `type:"timestamp"` + + // A description of the status of the health check endpoint as reported by one + // of the Amazon Route 53 health checkers. + Status *string `type:"string"` +} + +// String returns the string representation +func (s StatusReport) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s StatusReport) GoString() string { + return s.String() +} + +// SetCheckedTime sets the CheckedTime field's value. +func (s *StatusReport) SetCheckedTime(v time.Time) *StatusReport { + s.CheckedTime = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *StatusReport) SetStatus(v string) *StatusReport { + s.Status = &v + return s +} + +// A complex type that contains information about a tag that you want to add +// or edit for the specified health check or hosted zone. +type Tag struct { + _ struct{} `type:"structure"` + + // The value of Key depends on the operation that you want to perform: + // + // * Add a tag to a health check or hosted zone: Key is the name that you + // want to give the new tag. + // + // * Edit a tag: Key is the name of the tag that you want to change the Value + // for. + // + // * Delete a key: Key is the name of the tag you want to remove. + // + // * Give a name to a health check: Edit the default Name tag. In the Amazon + // Route 53 console, the list of your health checks includes a Name column + // that lets you see the name that you've given to each health check. + Key *string `type:"string"` + + // The value of Value depends on the operation that you want to perform: + // + // * Add a tag to a health check or hosted zone: Value is the value that + // you want to give the new tag. + // + // * Edit a tag: Value is the new value that you want to assign the tag. + Value *string `type:"string"` +} + +// String returns the string representation +func (s Tag) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Tag) GoString() string { + return s.String() +} + +// SetKey sets the Key field's value. +func (s *Tag) SetKey(v string) *Tag { + s.Key = &v + return s +} + +// SetValue sets the Value field's value. +func (s *Tag) SetValue(v string) *Tag { + s.Value = &v + return s +} + +// Gets the value that Amazon Route 53 returns in response to a DNS request +// for a specified record name and type. You can optionally specify the IP address +// of a DNS resolver, an EDNS0 client subnet IP address, and a subnet mask. +type TestDNSAnswerInput struct { + _ struct{} `type:"structure"` + + // If the resolver that you specified for resolverip supports EDNS0, specify + // the IPv4 or IPv6 address of a client in the applicable location, for example, + // 192.0.2.44 or 2001:db8:85a3::8a2e:370:7334. + EDNS0ClientSubnetIP *string `location:"querystring" locationName:"edns0clientsubnetip" type:"string"` + + // If you specify an IP address for edns0clientsubnetip, you can optionally + // specify the number of bits of the IP address that you want the checking tool + // to include in the DNS query. For example, if you specify 192.0.2.44 for edns0clientsubnetip + // and 24 for edns0clientsubnetmask, the checking tool will simulate a request + // from 192.0.2.0/24. The default value is 24 bits for IPv4 addresses and 64 + // bits for IPv6 addresses. + // + // The range of valid values depends on whether edns0clientsubnetip is an IPv4 + // or an IPv6 address: + // + // * IPv4: Specify a value between 0 and 32 + // + // * IPv6: Specify a value between 0 and 128 + EDNS0ClientSubnetMask *string `location:"querystring" locationName:"edns0clientsubnetmask" type:"string"` + + // The ID of the hosted zone that you want Amazon Route 53 to simulate a query + // for. + // + // HostedZoneId is a required field + HostedZoneId *string `location:"querystring" locationName:"hostedzoneid" type:"string" required:"true"` + + // The name of the resource record set that you want Amazon Route 53 to simulate + // a query for. + // + // RecordName is a required field + RecordName *string `location:"querystring" locationName:"recordname" type:"string" required:"true"` + + // The type of the resource record set. + // + // RecordType is a required field + RecordType *string `location:"querystring" locationName:"recordtype" type:"string" required:"true" enum:"RRType"` + + // If you want to simulate a request from a specific DNS resolver, specify the + // IP address for that resolver. If you omit this value, TestDnsAnswer uses + // the IP address of a DNS resolver in the AWS US East (N. Virginia) Region + // (us-east-1). + ResolverIP *string `location:"querystring" locationName:"resolverip" type:"string"` +} + +// String returns the string representation +func (s TestDNSAnswerInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TestDNSAnswerInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TestDNSAnswerInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TestDNSAnswerInput"} + if s.HostedZoneId == nil { + invalidParams.Add(request.NewErrParamRequired("HostedZoneId")) + } + if s.RecordName == nil { + invalidParams.Add(request.NewErrParamRequired("RecordName")) + } + if s.RecordType == nil { + invalidParams.Add(request.NewErrParamRequired("RecordType")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEDNS0ClientSubnetIP sets the EDNS0ClientSubnetIP field's value. +func (s *TestDNSAnswerInput) SetEDNS0ClientSubnetIP(v string) *TestDNSAnswerInput { + s.EDNS0ClientSubnetIP = &v + return s +} + +// SetEDNS0ClientSubnetMask sets the EDNS0ClientSubnetMask field's value. +func (s *TestDNSAnswerInput) SetEDNS0ClientSubnetMask(v string) *TestDNSAnswerInput { + s.EDNS0ClientSubnetMask = &v + return s +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *TestDNSAnswerInput) SetHostedZoneId(v string) *TestDNSAnswerInput { + s.HostedZoneId = &v + return s +} + +// SetRecordName sets the RecordName field's value. +func (s *TestDNSAnswerInput) SetRecordName(v string) *TestDNSAnswerInput { + s.RecordName = &v + return s +} + +// SetRecordType sets the RecordType field's value. +func (s *TestDNSAnswerInput) SetRecordType(v string) *TestDNSAnswerInput { + s.RecordType = &v + return s +} + +// SetResolverIP sets the ResolverIP field's value. +func (s *TestDNSAnswerInput) SetResolverIP(v string) *TestDNSAnswerInput { + s.ResolverIP = &v + return s +} + +// A complex type that contains the response to a TestDNSAnswer request. +type TestDNSAnswerOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Route 53 name server used to respond to the request. + // + // Nameserver is a required field + Nameserver *string `type:"string" required:"true"` + + // The protocol that Amazon Route 53 used to respond to the request, either + // UDP or TCP. + // + // Protocol is a required field + Protocol *string `type:"string" required:"true"` + + // A list that contains values that Amazon Route 53 returned for this resource + // record set. + // + // RecordData is a required field + RecordData []*string `locationNameList:"RecordDataEntry" type:"list" required:"true"` + + // The name of the resource record set that you submitted a request for. + // + // RecordName is a required field + RecordName *string `type:"string" required:"true"` + + // The type of the resource record set that you submitted a request for. + // + // RecordType is a required field + RecordType *string `type:"string" required:"true" enum:"RRType"` + + // A code that indicates whether the request is valid or not. The most common + // response code is NOERROR, meaning that the request is valid. If the response + // is not valid, Amazon Route 53 returns a response code that describes the + // error. For a list of possible response codes, see DNS RCODES (http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6) + // on the IANA website. + // + // ResponseCode is a required field + ResponseCode *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s TestDNSAnswerOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TestDNSAnswerOutput) GoString() string { + return s.String() +} + +// SetNameserver sets the Nameserver field's value. +func (s *TestDNSAnswerOutput) SetNameserver(v string) *TestDNSAnswerOutput { + s.Nameserver = &v + return s +} + +// SetProtocol sets the Protocol field's value. +func (s *TestDNSAnswerOutput) SetProtocol(v string) *TestDNSAnswerOutput { + s.Protocol = &v + return s +} + +// SetRecordData sets the RecordData field's value. +func (s *TestDNSAnswerOutput) SetRecordData(v []*string) *TestDNSAnswerOutput { + s.RecordData = v + return s +} + +// SetRecordName sets the RecordName field's value. +func (s *TestDNSAnswerOutput) SetRecordName(v string) *TestDNSAnswerOutput { + s.RecordName = &v + return s +} + +// SetRecordType sets the RecordType field's value. +func (s *TestDNSAnswerOutput) SetRecordType(v string) *TestDNSAnswerOutput { + s.RecordType = &v + return s +} + +// SetResponseCode sets the ResponseCode field's value. +func (s *TestDNSAnswerOutput) SetResponseCode(v string) *TestDNSAnswerOutput { + s.ResponseCode = &v + return s +} + +// A complex type that contains settings for a traffic policy. +type TrafficPolicy struct { + _ struct{} `type:"structure"` + + // The comment that you specify in the CreateTrafficPolicy request, if any. + Comment *string `type:"string"` + + // The definition of a traffic policy in JSON format. You specify the JSON document + // to use for a new traffic policy in the CreateTrafficPolicy request. For more + // information about the JSON format, see Traffic Policy Document Format (https://docs.aws.amazon.com/Route53/latest/APIReference/api-policies-traffic-policy-document-format.html). + // + // Document is a required field + Document *string `type:"string" required:"true"` + + // The ID that Amazon Route 53 assigned to a traffic policy when you created + // it. + // + // Id is a required field + Id *string `min:"1" type:"string" required:"true"` + + // The name that you specified when you created the traffic policy. + // + // Name is a required field + Name *string `type:"string" required:"true"` + + // The DNS type of the resource record sets that Amazon Route 53 creates when + // you use a traffic policy to create a traffic policy instance. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"RRType"` + + // The version number that Amazon Route 53 assigns to a traffic policy. For + // a new traffic policy, the value of Version is always 1. + // + // Version is a required field + Version *int64 `min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s TrafficPolicy) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TrafficPolicy) GoString() string { + return s.String() +} + +// SetComment sets the Comment field's value. +func (s *TrafficPolicy) SetComment(v string) *TrafficPolicy { + s.Comment = &v + return s +} + +// SetDocument sets the Document field's value. +func (s *TrafficPolicy) SetDocument(v string) *TrafficPolicy { + s.Document = &v + return s +} + +// SetId sets the Id field's value. +func (s *TrafficPolicy) SetId(v string) *TrafficPolicy { + s.Id = &v + return s +} + +// SetName sets the Name field's value. +func (s *TrafficPolicy) SetName(v string) *TrafficPolicy { + s.Name = &v + return s +} + +// SetType sets the Type field's value. +func (s *TrafficPolicy) SetType(v string) *TrafficPolicy { + s.Type = &v + return s +} + +// SetVersion sets the Version field's value. +func (s *TrafficPolicy) SetVersion(v int64) *TrafficPolicy { + s.Version = &v + return s +} + +// A complex type that contains settings for the new traffic policy instance. +type TrafficPolicyInstance struct { + _ struct{} `type:"structure"` + + // The ID of the hosted zone that Amazon Route 53 created resource record sets + // in. + // + // HostedZoneId is a required field + HostedZoneId *string `type:"string" required:"true"` + + // The ID that Amazon Route 53 assigned to the new traffic policy instance. + // + // Id is a required field + Id *string `min:"1" type:"string" required:"true"` + + // If State is Failed, an explanation of the reason for the failure. If State + // is another value, Message is empty. + // + // Message is a required field + Message *string `type:"string" required:"true"` + + // The DNS name, such as www.example.com, for which Amazon Route 53 responds + // to queries by using the resource record sets that are associated with this + // traffic policy instance. + // + // Name is a required field + Name *string `type:"string" required:"true"` + + // The value of State is one of the following values: + // + // Applied + // + // Amazon Route 53 has finished creating resource record sets, and changes have + // propagated to all Route 53 edge locations. + // + // Creating + // + // Route 53 is creating the resource record sets. Use GetTrafficPolicyInstance + // to confirm that the CreateTrafficPolicyInstance request completed successfully. + // + // Failed + // + // Route 53 wasn't able to create or update the resource record sets. When the + // value of State is Failed, see Message for an explanation of what caused the + // request to fail. + // + // State is a required field + State *string `type:"string" required:"true"` + + // The TTL that Amazon Route 53 assigned to all of the resource record sets + // that it created in the specified hosted zone. + // + // TTL is a required field + TTL *int64 `type:"long" required:"true"` + + // The ID of the traffic policy that Amazon Route 53 used to create resource + // record sets in the specified hosted zone. + // + // TrafficPolicyId is a required field + TrafficPolicyId *string `min:"1" type:"string" required:"true"` + + // The DNS type that Amazon Route 53 assigned to all of the resource record + // sets that it created for this traffic policy instance. + // + // TrafficPolicyType is a required field + TrafficPolicyType *string `type:"string" required:"true" enum:"RRType"` + + // The version of the traffic policy that Amazon Route 53 used to create resource + // record sets in the specified hosted zone. + // + // TrafficPolicyVersion is a required field + TrafficPolicyVersion *int64 `min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s TrafficPolicyInstance) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TrafficPolicyInstance) GoString() string { + return s.String() +} + +// SetHostedZoneId sets the HostedZoneId field's value. +func (s *TrafficPolicyInstance) SetHostedZoneId(v string) *TrafficPolicyInstance { + s.HostedZoneId = &v + return s +} + +// SetId sets the Id field's value. +func (s *TrafficPolicyInstance) SetId(v string) *TrafficPolicyInstance { + s.Id = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *TrafficPolicyInstance) SetMessage(v string) *TrafficPolicyInstance { + s.Message = &v + return s +} + +// SetName sets the Name field's value. +func (s *TrafficPolicyInstance) SetName(v string) *TrafficPolicyInstance { + s.Name = &v + return s +} + +// SetState sets the State field's value. +func (s *TrafficPolicyInstance) SetState(v string) *TrafficPolicyInstance { + s.State = &v + return s +} + +// SetTTL sets the TTL field's value. +func (s *TrafficPolicyInstance) SetTTL(v int64) *TrafficPolicyInstance { + s.TTL = &v + return s +} + +// SetTrafficPolicyId sets the TrafficPolicyId field's value. +func (s *TrafficPolicyInstance) SetTrafficPolicyId(v string) *TrafficPolicyInstance { + s.TrafficPolicyId = &v + return s +} + +// SetTrafficPolicyType sets the TrafficPolicyType field's value. +func (s *TrafficPolicyInstance) SetTrafficPolicyType(v string) *TrafficPolicyInstance { + s.TrafficPolicyType = &v + return s +} + +// SetTrafficPolicyVersion sets the TrafficPolicyVersion field's value. +func (s *TrafficPolicyInstance) SetTrafficPolicyVersion(v int64) *TrafficPolicyInstance { + s.TrafficPolicyVersion = &v + return s +} + +// A complex type that contains information about the latest version of one +// traffic policy that is associated with the current AWS account. +type TrafficPolicySummary struct { + _ struct{} `type:"structure"` + + // The ID that Amazon Route 53 assigned to the traffic policy when you created + // it. + // + // Id is a required field + Id *string `min:"1" type:"string" required:"true"` + + // The version number of the latest version of the traffic policy. + // + // LatestVersion is a required field + LatestVersion *int64 `min:"1" type:"integer" required:"true"` + + // The name that you specified for the traffic policy when you created it. + // + // Name is a required field + Name *string `type:"string" required:"true"` + + // The number of traffic policies that are associated with the current AWS account. + // + // TrafficPolicyCount is a required field + TrafficPolicyCount *int64 `min:"1" type:"integer" required:"true"` + + // The DNS type of the resource record sets that Amazon Route 53 creates when + // you use a traffic policy to create a traffic policy instance. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"RRType"` +} + +// String returns the string representation +func (s TrafficPolicySummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TrafficPolicySummary) GoString() string { + return s.String() +} + +// SetId sets the Id field's value. +func (s *TrafficPolicySummary) SetId(v string) *TrafficPolicySummary { + s.Id = &v + return s +} + +// SetLatestVersion sets the LatestVersion field's value. +func (s *TrafficPolicySummary) SetLatestVersion(v int64) *TrafficPolicySummary { + s.LatestVersion = &v + return s +} + +// SetName sets the Name field's value. +func (s *TrafficPolicySummary) SetName(v string) *TrafficPolicySummary { + s.Name = &v + return s +} + +// SetTrafficPolicyCount sets the TrafficPolicyCount field's value. +func (s *TrafficPolicySummary) SetTrafficPolicyCount(v int64) *TrafficPolicySummary { + s.TrafficPolicyCount = &v + return s +} + +// SetType sets the Type field's value. +func (s *TrafficPolicySummary) SetType(v string) *TrafficPolicySummary { + s.Type = &v + return s +} + +// A complex type that contains information about a request to update a health +// check. +type UpdateHealthCheckInput struct { + _ struct{} `locationName:"UpdateHealthCheckRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // A complex type that identifies the CloudWatch alarm that you want Amazon + // Route 53 health checkers to use to determine whether the specified health + // check is healthy. + AlarmIdentifier *AlarmIdentifier `type:"structure"` + + // A complex type that contains one ChildHealthCheck element for each health + // check that you want to associate with a CALCULATED health check. + ChildHealthChecks []*string `locationNameList:"ChildHealthCheck" type:"list"` + + // Stops Route 53 from performing health checks. When you disable a health check, + // here's what happens: + // + // * Health checks that check the health of endpoints: Route 53 stops submitting + // requests to your application, server, or other resource. + // + // * Calculated health checks: Route 53 stops aggregating the status of the + // referenced health checks. + // + // * Health checks that monitor CloudWatch alarms: Route 53 stops monitoring + // the corresponding CloudWatch metrics. + // + // After you disable a health check, Route 53 considers the status of the health + // check to always be healthy. If you configured DNS failover, Route 53 continues + // to route traffic to the corresponding resources. If you want to stop routing + // traffic to a resource, change the value of Inverted (https://docs.aws.amazon.com/Route53/latest/APIReference/API_UpdateHealthCheck.html#Route53-UpdateHealthCheck-request-Inverted). + // + // Charges for a health check still apply when the health check is disabled. + // For more information, see Amazon Route 53 Pricing (http://aws.amazon.com/route53/pricing/). + Disabled *bool `type:"boolean"` + + // Specify whether you want Amazon Route 53 to send the value of FullyQualifiedDomainName + // to the endpoint in the client_hello message during TLS negotiation. This + // allows the endpoint to respond to HTTPS health check requests with the applicable + // SSL/TLS certificate. + // + // Some endpoints require that HTTPS requests include the host name in the client_hello + // message. If you don't enable SNI, the status of the health check will be + // SSL alert handshake_failure. A health check can also have that status for + // other reasons. If SNI is enabled and you're still getting the error, check + // the SSL/TLS configuration on your endpoint and confirm that your certificate + // is valid. + // + // The SSL/TLS certificate on your endpoint includes a domain name in the Common + // Name field and possibly several more in the Subject Alternative Names field. + // One of the domain names in the certificate should match the value that you + // specify for FullyQualifiedDomainName. If the endpoint responds to the client_hello + // message with a certificate that does not include the domain name that you + // specified in FullyQualifiedDomainName, a health checker will retry the handshake. + // In the second attempt, the health checker will omit FullyQualifiedDomainName + // from the client_hello message. + EnableSNI *bool `type:"boolean"` + + // The number of consecutive health checks that an endpoint must pass or fail + // for Amazon Route 53 to change the current status of the endpoint from unhealthy + // to healthy or vice versa. For more information, see How Amazon Route 53 Determines + // Whether an Endpoint Is Healthy (http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover-determining-health-of-endpoints.html) + // in the Amazon Route 53 Developer Guide. + // + // If you don't specify a value for FailureThreshold, the default value is three + // health checks. + FailureThreshold *int64 `min:"1" type:"integer"` + + // Amazon Route 53 behavior depends on whether you specify a value for IPAddress. + // + // If a health check already has a value for IPAddress, you can change the value. + // However, you can't update an existing health check to add or remove the value + // of IPAddress. + // + // If you specify a value for IPAddress: + // + // Route 53 sends health check requests to the specified IPv4 or IPv6 address + // and passes the value of FullyQualifiedDomainName in the Host header for all + // health checks except TCP health checks. This is typically the fully qualified + // DNS name of the endpoint on which you want Route 53 to perform health checks. + // + // When Route 53 checks the health of an endpoint, here is how it constructs + // the Host header: + // + // * If you specify a value of 80 for Port and HTTP or HTTP_STR_MATCH for + // Type, Route 53 passes the value of FullyQualifiedDomainName to the endpoint + // in the Host header. + // + // * If you specify a value of 443 for Port and HTTPS or HTTPS_STR_MATCH + // for Type, Route 53 passes the value of FullyQualifiedDomainName to the + // endpoint in the Host header. + // + // * If you specify another value for Port and any value except TCP for Type, + // Route 53 passes FullyQualifiedDomainName:Port to the endpoint in the Host + // header. + // + // If you don't specify a value for FullyQualifiedDomainName, Route 53 substitutes + // the value of IPAddress in the Host header in each of the above cases. + // + // If you don't specify a value for IPAddress: + // + // If you don't specify a value for IPAddress, Route 53 sends a DNS request + // to the domain that you specify in FullyQualifiedDomainName at the interval + // you specify in RequestInterval. Using an IPv4 address that is returned by + // DNS, Route 53 then checks the health of the endpoint. + // + // If you don't specify a value for IPAddress, Route 53 uses only IPv4 to send + // health checks to the endpoint. If there's no resource record set with a type + // of A for the name that you specify for FullyQualifiedDomainName, the health + // check fails with a "DNS resolution failed" error. + // + // If you want to check the health of weighted, latency, or failover resource + // record sets and you choose to specify the endpoint only by FullyQualifiedDomainName, + // we recommend that you create a separate health check for each endpoint. For + // example, create a health check for each HTTP server that is serving content + // for www.example.com. For the value of FullyQualifiedDomainName, specify the + // domain name of the server (such as us-east-2-www.example.com), not the name + // of the resource record sets (www.example.com). + // + // In this configuration, if the value of FullyQualifiedDomainName matches the + // name of the resource record sets and you then associate the health check + // with those resource record sets, health check results will be unpredictable. + // + // In addition, if the value of Type is HTTP, HTTPS, HTTP_STR_MATCH, or HTTPS_STR_MATCH, + // Route 53 passes the value of FullyQualifiedDomainName in the Host header, + // as it does when you specify a value for IPAddress. If the value of Type is + // TCP, Route 53 doesn't pass a Host header. + FullyQualifiedDomainName *string `type:"string"` + + // The ID for the health check for which you want detailed information. When + // you created the health check, CreateHealthCheck returned the ID in the response, + // in the HealthCheckId element. + // + // HealthCheckId is a required field + HealthCheckId *string `location:"uri" locationName:"HealthCheckId" type:"string" required:"true"` + + // A sequential counter that Amazon Route 53 sets to 1 when you create a health + // check and increments by 1 each time you update settings for the health check. + // + // We recommend that you use GetHealthCheck or ListHealthChecks to get the current + // value of HealthCheckVersion for the health check that you want to update, + // and that you include that value in your UpdateHealthCheck request. This prevents + // Route 53 from overwriting an intervening update: + // + // * If the value in the UpdateHealthCheck request matches the value of HealthCheckVersion + // in the health check, Route 53 updates the health check with the new settings. + // + // * If the value of HealthCheckVersion in the health check is greater, the + // health check was changed after you got the version number. Route 53 does + // not update the health check, and it returns a HealthCheckVersionMismatch + // error. + HealthCheckVersion *int64 `min:"1" type:"long"` + + // The number of child health checks that are associated with a CALCULATED health + // that Amazon Route 53 must consider healthy for the CALCULATED health check + // to be considered healthy. To specify the child health checks that you want + // to associate with a CALCULATED health check, use the ChildHealthChecks and + // ChildHealthCheck elements. + // + // Note the following: + // + // * If you specify a number greater than the number of child health checks, + // Route 53 always considers this health check to be unhealthy. + // + // * If you specify 0, Route 53 always considers this health check to be + // healthy. + HealthThreshold *int64 `type:"integer"` + + // The IPv4 or IPv6 IP address for the endpoint that you want Amazon Route 53 + // to perform health checks on. If you don't specify a value for IPAddress, + // Route 53 sends a DNS request to resolve the domain name that you specify + // in FullyQualifiedDomainName at the interval that you specify in RequestInterval. + // Using an IP address that is returned by DNS, Route 53 then checks the health + // of the endpoint. + // + // Use one of the following formats for the value of IPAddress: + // + // * IPv4 address: four values between 0 and 255, separated by periods (.), + // for example, 192.0.2.44. + // + // * IPv6 address: eight groups of four hexadecimal values, separated by + // colons (:), for example, 2001:0db8:85a3:0000:0000:abcd:0001:2345. You + // can also shorten IPv6 addresses as described in RFC 5952, for example, + // 2001:db8:85a3::abcd:1:2345. + // + // If the endpoint is an EC2 instance, we recommend that you create an Elastic + // IP address, associate it with your EC2 instance, and specify the Elastic + // IP address for IPAddress. This ensures that the IP address of your instance + // never changes. For more information, see the applicable documentation: + // + // * Linux: Elastic IP Addresses (EIP) (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) + // in the Amazon EC2 User Guide for Linux Instances + // + // * Windows: Elastic IP Addresses (EIP) (https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/elastic-ip-addresses-eip.html) + // in the Amazon EC2 User Guide for Windows Instances + // + // If a health check already has a value for IPAddress, you can change the value. + // However, you can't update an existing health check to add or remove the value + // of IPAddress. + // + // For more information, see FullyQualifiedDomainName (https://docs.aws.amazon.com/Route53/latest/APIReference/API_UpdateHealthCheck.html#Route53-UpdateHealthCheck-request-FullyQualifiedDomainName). + // + // Constraints: Route 53 can't check the health of endpoints for which the IP + // address is in local, private, non-routable, or multicast ranges. For more + // information about IP addresses for which you can't create health checks, + // see the following documents: + // + // * RFC 5735, Special Use IPv4 Addresses (https://tools.ietf.org/html/rfc5735) + // + // * RFC 6598, IANA-Reserved IPv4 Prefix for Shared Address Space (https://tools.ietf.org/html/rfc6598) + // + // * RFC 5156, Special-Use IPv6 Addresses (https://tools.ietf.org/html/rfc5156) + IPAddress *string `type:"string"` + + // When CloudWatch has insufficient data about the metric to determine the alarm + // state, the status that you want Amazon Route 53 to assign to the health check: + // + // * Healthy: Route 53 considers the health check to be healthy. + // + // * Unhealthy: Route 53 considers the health check to be unhealthy. + // + // * LastKnownStatus: Route 53 uses the status of the health check from the + // last time CloudWatch had sufficient data to determine the alarm state. + // For new health checks that have no last known status, the default status + // for the health check is healthy. + InsufficientDataHealthStatus *string `type:"string" enum:"InsufficientDataHealthStatus"` + + // Specify whether you want Amazon Route 53 to invert the status of a health + // check, for example, to consider a health check unhealthy when it otherwise + // would be considered healthy. + Inverted *bool `type:"boolean"` + + // The port on the endpoint on which you want Amazon Route 53 to perform health + // checks. + Port *int64 `min:"1" type:"integer"` + + // A complex type that contains one Region element for each region that you + // want Amazon Route 53 health checkers to check the specified endpoint from. + Regions []*string `locationNameList:"Region" min:"3" type:"list"` + + // A complex type that contains one ResettableElementName element for each element + // that you want to reset to the default value. Valid values for ResettableElementName + // include the following: + // + // * ChildHealthChecks: Amazon Route 53 resets ChildHealthChecks (https://docs.aws.amazon.com/Route53/latest/APIReference/API_HealthCheckConfig.html#Route53-Type-HealthCheckConfig-ChildHealthChecks) + // to null. + // + // * FullyQualifiedDomainName: Route 53 resets FullyQualifiedDomainName (https://docs.aws.amazon.com/Route53/latest/APIReference/API_UpdateHealthCheck.html#Route53-UpdateHealthCheck-request-FullyQualifiedDomainName). + // to null. + // + // * Regions: Route 53 resets the Regions (https://docs.aws.amazon.com/Route53/latest/APIReference/API_HealthCheckConfig.html#Route53-Type-HealthCheckConfig-Regions) + // list to the default set of regions. + // + // * ResourcePath: Route 53 resets ResourcePath (https://docs.aws.amazon.com/Route53/latest/APIReference/API_HealthCheckConfig.html#Route53-Type-HealthCheckConfig-ResourcePath) + // to null. + ResetElements []*string `locationNameList:"ResettableElementName" type:"list"` + + // The path that you want Amazon Route 53 to request when performing health + // checks. The path can be any value for which your endpoint will return an + // HTTP status code of 2xx or 3xx when the endpoint is healthy, for example + // the file /docs/route53-health-check.html. You can also include query string + // parameters, for example, /welcome.html?language=jp&login=y. + // + // Specify this value only if you want to change it. + ResourcePath *string `type:"string"` + + // If the value of Type is HTTP_STR_MATCH or HTTP_STR_MATCH, the string that + // you want Amazon Route 53 to search for in the response body from the specified + // resource. If the string appears in the response body, Route 53 considers + // the resource healthy. (You can't change the value of Type when you update + // a health check.) + SearchString *string `type:"string"` +} + +// String returns the string representation +func (s UpdateHealthCheckInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateHealthCheckInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateHealthCheckInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateHealthCheckInput"} + if s.FailureThreshold != nil && *s.FailureThreshold < 1 { + invalidParams.Add(request.NewErrParamMinValue("FailureThreshold", 1)) + } + if s.HealthCheckId == nil { + invalidParams.Add(request.NewErrParamRequired("HealthCheckId")) + } + if s.HealthCheckId != nil && len(*s.HealthCheckId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("HealthCheckId", 1)) + } + if s.HealthCheckVersion != nil && *s.HealthCheckVersion < 1 { + invalidParams.Add(request.NewErrParamMinValue("HealthCheckVersion", 1)) + } + if s.Port != nil && *s.Port < 1 { + invalidParams.Add(request.NewErrParamMinValue("Port", 1)) + } + if s.Regions != nil && len(s.Regions) < 3 { + invalidParams.Add(request.NewErrParamMinLen("Regions", 3)) + } + if s.AlarmIdentifier != nil { + if err := s.AlarmIdentifier.Validate(); err != nil { + invalidParams.AddNested("AlarmIdentifier", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAlarmIdentifier sets the AlarmIdentifier field's value. +func (s *UpdateHealthCheckInput) SetAlarmIdentifier(v *AlarmIdentifier) *UpdateHealthCheckInput { + s.AlarmIdentifier = v + return s +} + +// SetChildHealthChecks sets the ChildHealthChecks field's value. +func (s *UpdateHealthCheckInput) SetChildHealthChecks(v []*string) *UpdateHealthCheckInput { + s.ChildHealthChecks = v + return s +} + +// SetDisabled sets the Disabled field's value. +func (s *UpdateHealthCheckInput) SetDisabled(v bool) *UpdateHealthCheckInput { + s.Disabled = &v + return s +} + +// SetEnableSNI sets the EnableSNI field's value. +func (s *UpdateHealthCheckInput) SetEnableSNI(v bool) *UpdateHealthCheckInput { + s.EnableSNI = &v + return s +} + +// SetFailureThreshold sets the FailureThreshold field's value. +func (s *UpdateHealthCheckInput) SetFailureThreshold(v int64) *UpdateHealthCheckInput { + s.FailureThreshold = &v + return s +} + +// SetFullyQualifiedDomainName sets the FullyQualifiedDomainName field's value. +func (s *UpdateHealthCheckInput) SetFullyQualifiedDomainName(v string) *UpdateHealthCheckInput { + s.FullyQualifiedDomainName = &v + return s +} + +// SetHealthCheckId sets the HealthCheckId field's value. +func (s *UpdateHealthCheckInput) SetHealthCheckId(v string) *UpdateHealthCheckInput { + s.HealthCheckId = &v + return s +} + +// SetHealthCheckVersion sets the HealthCheckVersion field's value. +func (s *UpdateHealthCheckInput) SetHealthCheckVersion(v int64) *UpdateHealthCheckInput { + s.HealthCheckVersion = &v + return s +} + +// SetHealthThreshold sets the HealthThreshold field's value. +func (s *UpdateHealthCheckInput) SetHealthThreshold(v int64) *UpdateHealthCheckInput { + s.HealthThreshold = &v + return s +} + +// SetIPAddress sets the IPAddress field's value. +func (s *UpdateHealthCheckInput) SetIPAddress(v string) *UpdateHealthCheckInput { + s.IPAddress = &v + return s +} + +// SetInsufficientDataHealthStatus sets the InsufficientDataHealthStatus field's value. +func (s *UpdateHealthCheckInput) SetInsufficientDataHealthStatus(v string) *UpdateHealthCheckInput { + s.InsufficientDataHealthStatus = &v + return s +} + +// SetInverted sets the Inverted field's value. +func (s *UpdateHealthCheckInput) SetInverted(v bool) *UpdateHealthCheckInput { + s.Inverted = &v + return s +} + +// SetPort sets the Port field's value. +func (s *UpdateHealthCheckInput) SetPort(v int64) *UpdateHealthCheckInput { + s.Port = &v + return s +} + +// SetRegions sets the Regions field's value. +func (s *UpdateHealthCheckInput) SetRegions(v []*string) *UpdateHealthCheckInput { + s.Regions = v + return s +} + +// SetResetElements sets the ResetElements field's value. +func (s *UpdateHealthCheckInput) SetResetElements(v []*string) *UpdateHealthCheckInput { + s.ResetElements = v + return s +} + +// SetResourcePath sets the ResourcePath field's value. +func (s *UpdateHealthCheckInput) SetResourcePath(v string) *UpdateHealthCheckInput { + s.ResourcePath = &v + return s +} + +// SetSearchString sets the SearchString field's value. +func (s *UpdateHealthCheckInput) SetSearchString(v string) *UpdateHealthCheckInput { + s.SearchString = &v + return s +} + +// A complex type that contains the response to the UpdateHealthCheck request. +type UpdateHealthCheckOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains the response to an UpdateHealthCheck request. + // + // HealthCheck is a required field + HealthCheck *HealthCheck `type:"structure" required:"true"` +} + +// String returns the string representation +func (s UpdateHealthCheckOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateHealthCheckOutput) GoString() string { + return s.String() +} + +// SetHealthCheck sets the HealthCheck field's value. +func (s *UpdateHealthCheckOutput) SetHealthCheck(v *HealthCheck) *UpdateHealthCheckOutput { + s.HealthCheck = v + return s +} + +// A request to update the comment for a hosted zone. +type UpdateHostedZoneCommentInput struct { + _ struct{} `locationName:"UpdateHostedZoneCommentRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // The new comment for the hosted zone. If you don't specify a value for Comment, + // Amazon Route 53 deletes the existing value of the Comment element, if any. + Comment *string `type:"string"` + + // The ID for the hosted zone that you want to update the comment for. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" type:"string" required:"true"` +} + +// String returns the string representation +func (s UpdateHostedZoneCommentInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateHostedZoneCommentInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateHostedZoneCommentInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateHostedZoneCommentInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetComment sets the Comment field's value. +func (s *UpdateHostedZoneCommentInput) SetComment(v string) *UpdateHostedZoneCommentInput { + s.Comment = &v + return s +} + +// SetId sets the Id field's value. +func (s *UpdateHostedZoneCommentInput) SetId(v string) *UpdateHostedZoneCommentInput { + s.Id = &v + return s +} + +// A complex type that contains the response to the UpdateHostedZoneComment +// request. +type UpdateHostedZoneCommentOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains the response to the UpdateHostedZoneComment + // request. + // + // HostedZone is a required field + HostedZone *HostedZone `type:"structure" required:"true"` +} + +// String returns the string representation +func (s UpdateHostedZoneCommentOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateHostedZoneCommentOutput) GoString() string { + return s.String() +} + +// SetHostedZone sets the HostedZone field's value. +func (s *UpdateHostedZoneCommentOutput) SetHostedZone(v *HostedZone) *UpdateHostedZoneCommentOutput { + s.HostedZone = v + return s +} + +// A complex type that contains information about the traffic policy that you +// want to update the comment for. +type UpdateTrafficPolicyCommentInput struct { + _ struct{} `locationName:"UpdateTrafficPolicyCommentRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // The new comment for the specified traffic policy and version. + // + // Comment is a required field + Comment *string `type:"string" required:"true"` + + // The value of Id for the traffic policy that you want to update the comment + // for. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` + + // The value of Version for the traffic policy that you want to update the comment + // for. + // + // Version is a required field + Version *int64 `location:"uri" locationName:"Version" min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s UpdateTrafficPolicyCommentInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateTrafficPolicyCommentInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateTrafficPolicyCommentInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateTrafficPolicyCommentInput"} + if s.Comment == nil { + invalidParams.Add(request.NewErrParamRequired("Comment")) + } + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + if s.Version == nil { + invalidParams.Add(request.NewErrParamRequired("Version")) + } + if s.Version != nil && *s.Version < 1 { + invalidParams.Add(request.NewErrParamMinValue("Version", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetComment sets the Comment field's value. +func (s *UpdateTrafficPolicyCommentInput) SetComment(v string) *UpdateTrafficPolicyCommentInput { + s.Comment = &v + return s +} + +// SetId sets the Id field's value. +func (s *UpdateTrafficPolicyCommentInput) SetId(v string) *UpdateTrafficPolicyCommentInput { + s.Id = &v + return s +} + +// SetVersion sets the Version field's value. +func (s *UpdateTrafficPolicyCommentInput) SetVersion(v int64) *UpdateTrafficPolicyCommentInput { + s.Version = &v + return s +} + +// A complex type that contains the response information for the traffic policy. +type UpdateTrafficPolicyCommentOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains settings for the specified traffic policy. + // + // TrafficPolicy is a required field + TrafficPolicy *TrafficPolicy `type:"structure" required:"true"` +} + +// String returns the string representation +func (s UpdateTrafficPolicyCommentOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateTrafficPolicyCommentOutput) GoString() string { + return s.String() +} + +// SetTrafficPolicy sets the TrafficPolicy field's value. +func (s *UpdateTrafficPolicyCommentOutput) SetTrafficPolicy(v *TrafficPolicy) *UpdateTrafficPolicyCommentOutput { + s.TrafficPolicy = v + return s +} + +// A complex type that contains information about the resource record sets that +// you want to update based on a specified traffic policy instance. +type UpdateTrafficPolicyInstanceInput struct { + _ struct{} `locationName:"UpdateTrafficPolicyInstanceRequest" type:"structure" xmlURI:"https://route53.amazonaws.com/doc/2013-04-01/"` + + // The ID of the traffic policy instance that you want to update. + // + // Id is a required field + Id *string `location:"uri" locationName:"Id" min:"1" type:"string" required:"true"` + + // The TTL that you want Amazon Route 53 to assign to all of the updated resource + // record sets. + // + // TTL is a required field + TTL *int64 `type:"long" required:"true"` + + // The ID of the traffic policy that you want Amazon Route 53 to use to update + // resource record sets for the specified traffic policy instance. + // + // TrafficPolicyId is a required field + TrafficPolicyId *string `min:"1" type:"string" required:"true"` + + // The version of the traffic policy that you want Amazon Route 53 to use to + // update resource record sets for the specified traffic policy instance. + // + // TrafficPolicyVersion is a required field + TrafficPolicyVersion *int64 `min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s UpdateTrafficPolicyInstanceInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateTrafficPolicyInstanceInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateTrafficPolicyInstanceInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateTrafficPolicyInstanceInput"} + if s.Id == nil { + invalidParams.Add(request.NewErrParamRequired("Id")) + } + if s.Id != nil && len(*s.Id) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Id", 1)) + } + if s.TTL == nil { + invalidParams.Add(request.NewErrParamRequired("TTL")) + } + if s.TrafficPolicyId == nil { + invalidParams.Add(request.NewErrParamRequired("TrafficPolicyId")) + } + if s.TrafficPolicyId != nil && len(*s.TrafficPolicyId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("TrafficPolicyId", 1)) + } + if s.TrafficPolicyVersion == nil { + invalidParams.Add(request.NewErrParamRequired("TrafficPolicyVersion")) + } + if s.TrafficPolicyVersion != nil && *s.TrafficPolicyVersion < 1 { + invalidParams.Add(request.NewErrParamMinValue("TrafficPolicyVersion", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetId sets the Id field's value. +func (s *UpdateTrafficPolicyInstanceInput) SetId(v string) *UpdateTrafficPolicyInstanceInput { + s.Id = &v + return s +} + +// SetTTL sets the TTL field's value. +func (s *UpdateTrafficPolicyInstanceInput) SetTTL(v int64) *UpdateTrafficPolicyInstanceInput { + s.TTL = &v + return s +} + +// SetTrafficPolicyId sets the TrafficPolicyId field's value. +func (s *UpdateTrafficPolicyInstanceInput) SetTrafficPolicyId(v string) *UpdateTrafficPolicyInstanceInput { + s.TrafficPolicyId = &v + return s +} + +// SetTrafficPolicyVersion sets the TrafficPolicyVersion field's value. +func (s *UpdateTrafficPolicyInstanceInput) SetTrafficPolicyVersion(v int64) *UpdateTrafficPolicyInstanceInput { + s.TrafficPolicyVersion = &v + return s +} + +// A complex type that contains information about the resource record sets that +// Amazon Route 53 created based on a specified traffic policy. +type UpdateTrafficPolicyInstanceOutput struct { + _ struct{} `type:"structure"` + + // A complex type that contains settings for the updated traffic policy instance. + // + // TrafficPolicyInstance is a required field + TrafficPolicyInstance *TrafficPolicyInstance `type:"structure" required:"true"` +} + +// String returns the string representation +func (s UpdateTrafficPolicyInstanceOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateTrafficPolicyInstanceOutput) GoString() string { + return s.String() +} + +// SetTrafficPolicyInstance sets the TrafficPolicyInstance field's value. +func (s *UpdateTrafficPolicyInstanceOutput) SetTrafficPolicyInstance(v *TrafficPolicyInstance) *UpdateTrafficPolicyInstanceOutput { + s.TrafficPolicyInstance = v + return s +} + +// (Private hosted zones only) A complex type that contains information about +// an Amazon VPC. +type VPC struct { + _ struct{} `type:"structure"` + + // (Private hosted zones only) The ID of an Amazon VPC. + VPCId *string `type:"string"` + + // (Private hosted zones only) The region that an Amazon VPC was created in. + VPCRegion *string `min:"1" type:"string" enum:"VPCRegion"` +} + +// String returns the string representation +func (s VPC) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s VPC) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *VPC) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "VPC"} + if s.VPCRegion != nil && len(*s.VPCRegion) < 1 { + invalidParams.Add(request.NewErrParamMinLen("VPCRegion", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetVPCId sets the VPCId field's value. +func (s *VPC) SetVPCId(v string) *VPC { + s.VPCId = &v + return s +} + +// SetVPCRegion sets the VPCRegion field's value. +func (s *VPC) SetVPCRegion(v string) *VPC { + s.VPCRegion = &v + return s +} + +const ( + // AccountLimitTypeMaxHealthChecksByOwner is a AccountLimitType enum value + AccountLimitTypeMaxHealthChecksByOwner = "MAX_HEALTH_CHECKS_BY_OWNER" + + // AccountLimitTypeMaxHostedZonesByOwner is a AccountLimitType enum value + AccountLimitTypeMaxHostedZonesByOwner = "MAX_HOSTED_ZONES_BY_OWNER" + + // AccountLimitTypeMaxTrafficPolicyInstancesByOwner is a AccountLimitType enum value + AccountLimitTypeMaxTrafficPolicyInstancesByOwner = "MAX_TRAFFIC_POLICY_INSTANCES_BY_OWNER" + + // AccountLimitTypeMaxReusableDelegationSetsByOwner is a AccountLimitType enum value + AccountLimitTypeMaxReusableDelegationSetsByOwner = "MAX_REUSABLE_DELEGATION_SETS_BY_OWNER" + + // AccountLimitTypeMaxTrafficPoliciesByOwner is a AccountLimitType enum value + AccountLimitTypeMaxTrafficPoliciesByOwner = "MAX_TRAFFIC_POLICIES_BY_OWNER" +) + +const ( + // ChangeActionCreate is a ChangeAction enum value + ChangeActionCreate = "CREATE" + + // ChangeActionDelete is a ChangeAction enum value + ChangeActionDelete = "DELETE" + + // ChangeActionUpsert is a ChangeAction enum value + ChangeActionUpsert = "UPSERT" +) + +const ( + // ChangeStatusPending is a ChangeStatus enum value + ChangeStatusPending = "PENDING" + + // ChangeStatusInsync is a ChangeStatus enum value + ChangeStatusInsync = "INSYNC" +) + +const ( + // CloudWatchRegionUsEast1 is a CloudWatchRegion enum value + CloudWatchRegionUsEast1 = "us-east-1" + + // CloudWatchRegionUsEast2 is a CloudWatchRegion enum value + CloudWatchRegionUsEast2 = "us-east-2" + + // CloudWatchRegionUsWest1 is a CloudWatchRegion enum value + CloudWatchRegionUsWest1 = "us-west-1" + + // CloudWatchRegionUsWest2 is a CloudWatchRegion enum value + CloudWatchRegionUsWest2 = "us-west-2" + + // CloudWatchRegionCaCentral1 is a CloudWatchRegion enum value + CloudWatchRegionCaCentral1 = "ca-central-1" + + // CloudWatchRegionEuCentral1 is a CloudWatchRegion enum value + CloudWatchRegionEuCentral1 = "eu-central-1" + + // CloudWatchRegionEuWest1 is a CloudWatchRegion enum value + CloudWatchRegionEuWest1 = "eu-west-1" + + // CloudWatchRegionEuWest2 is a CloudWatchRegion enum value + CloudWatchRegionEuWest2 = "eu-west-2" + + // CloudWatchRegionEuWest3 is a CloudWatchRegion enum value + CloudWatchRegionEuWest3 = "eu-west-3" + + // CloudWatchRegionApEast1 is a CloudWatchRegion enum value + CloudWatchRegionApEast1 = "ap-east-1" + + // CloudWatchRegionMeSouth1 is a CloudWatchRegion enum value + CloudWatchRegionMeSouth1 = "me-south-1" + + // CloudWatchRegionApSouth1 is a CloudWatchRegion enum value + CloudWatchRegionApSouth1 = "ap-south-1" + + // CloudWatchRegionApSoutheast1 is a CloudWatchRegion enum value + CloudWatchRegionApSoutheast1 = "ap-southeast-1" + + // CloudWatchRegionApSoutheast2 is a CloudWatchRegion enum value + CloudWatchRegionApSoutheast2 = "ap-southeast-2" + + // CloudWatchRegionApNortheast1 is a CloudWatchRegion enum value + CloudWatchRegionApNortheast1 = "ap-northeast-1" + + // CloudWatchRegionApNortheast2 is a CloudWatchRegion enum value + CloudWatchRegionApNortheast2 = "ap-northeast-2" + + // CloudWatchRegionApNortheast3 is a CloudWatchRegion enum value + CloudWatchRegionApNortheast3 = "ap-northeast-3" + + // CloudWatchRegionEuNorth1 is a CloudWatchRegion enum value + CloudWatchRegionEuNorth1 = "eu-north-1" + + // CloudWatchRegionSaEast1 is a CloudWatchRegion enum value + CloudWatchRegionSaEast1 = "sa-east-1" + + // CloudWatchRegionCnNorthwest1 is a CloudWatchRegion enum value + CloudWatchRegionCnNorthwest1 = "cn-northwest-1" + + // CloudWatchRegionCnNorth1 is a CloudWatchRegion enum value + CloudWatchRegionCnNorth1 = "cn-north-1" +) + +const ( + // ComparisonOperatorGreaterThanOrEqualToThreshold is a ComparisonOperator enum value + ComparisonOperatorGreaterThanOrEqualToThreshold = "GreaterThanOrEqualToThreshold" + + // ComparisonOperatorGreaterThanThreshold is a ComparisonOperator enum value + ComparisonOperatorGreaterThanThreshold = "GreaterThanThreshold" + + // ComparisonOperatorLessThanThreshold is a ComparisonOperator enum value + ComparisonOperatorLessThanThreshold = "LessThanThreshold" + + // ComparisonOperatorLessThanOrEqualToThreshold is a ComparisonOperator enum value + ComparisonOperatorLessThanOrEqualToThreshold = "LessThanOrEqualToThreshold" +) + +const ( + // HealthCheckRegionUsEast1 is a HealthCheckRegion enum value + HealthCheckRegionUsEast1 = "us-east-1" + + // HealthCheckRegionUsWest1 is a HealthCheckRegion enum value + HealthCheckRegionUsWest1 = "us-west-1" + + // HealthCheckRegionUsWest2 is a HealthCheckRegion enum value + HealthCheckRegionUsWest2 = "us-west-2" + + // HealthCheckRegionEuWest1 is a HealthCheckRegion enum value + HealthCheckRegionEuWest1 = "eu-west-1" + + // HealthCheckRegionApSoutheast1 is a HealthCheckRegion enum value + HealthCheckRegionApSoutheast1 = "ap-southeast-1" + + // HealthCheckRegionApSoutheast2 is a HealthCheckRegion enum value + HealthCheckRegionApSoutheast2 = "ap-southeast-2" + + // HealthCheckRegionApNortheast1 is a HealthCheckRegion enum value + HealthCheckRegionApNortheast1 = "ap-northeast-1" + + // HealthCheckRegionSaEast1 is a HealthCheckRegion enum value + HealthCheckRegionSaEast1 = "sa-east-1" +) + +const ( + // HealthCheckTypeHttp is a HealthCheckType enum value + HealthCheckTypeHttp = "HTTP" + + // HealthCheckTypeHttps is a HealthCheckType enum value + HealthCheckTypeHttps = "HTTPS" + + // HealthCheckTypeHttpStrMatch is a HealthCheckType enum value + HealthCheckTypeHttpStrMatch = "HTTP_STR_MATCH" + + // HealthCheckTypeHttpsStrMatch is a HealthCheckType enum value + HealthCheckTypeHttpsStrMatch = "HTTPS_STR_MATCH" + + // HealthCheckTypeTcp is a HealthCheckType enum value + HealthCheckTypeTcp = "TCP" + + // HealthCheckTypeCalculated is a HealthCheckType enum value + HealthCheckTypeCalculated = "CALCULATED" + + // HealthCheckTypeCloudwatchMetric is a HealthCheckType enum value + HealthCheckTypeCloudwatchMetric = "CLOUDWATCH_METRIC" +) + +const ( + // HostedZoneLimitTypeMaxRrsetsByZone is a HostedZoneLimitType enum value + HostedZoneLimitTypeMaxRrsetsByZone = "MAX_RRSETS_BY_ZONE" + + // HostedZoneLimitTypeMaxVpcsAssociatedByZone is a HostedZoneLimitType enum value + HostedZoneLimitTypeMaxVpcsAssociatedByZone = "MAX_VPCS_ASSOCIATED_BY_ZONE" +) + +const ( + // InsufficientDataHealthStatusHealthy is a InsufficientDataHealthStatus enum value + InsufficientDataHealthStatusHealthy = "Healthy" + + // InsufficientDataHealthStatusUnhealthy is a InsufficientDataHealthStatus enum value + InsufficientDataHealthStatusUnhealthy = "Unhealthy" + + // InsufficientDataHealthStatusLastKnownStatus is a InsufficientDataHealthStatus enum value + InsufficientDataHealthStatusLastKnownStatus = "LastKnownStatus" +) + +const ( + // RRTypeSoa is a RRType enum value + RRTypeSoa = "SOA" + + // RRTypeA is a RRType enum value + RRTypeA = "A" + + // RRTypeTxt is a RRType enum value + RRTypeTxt = "TXT" + + // RRTypeNs is a RRType enum value + RRTypeNs = "NS" + + // RRTypeCname is a RRType enum value + RRTypeCname = "CNAME" + + // RRTypeMx is a RRType enum value + RRTypeMx = "MX" + + // RRTypeNaptr is a RRType enum value + RRTypeNaptr = "NAPTR" + + // RRTypePtr is a RRType enum value + RRTypePtr = "PTR" + + // RRTypeSrv is a RRType enum value + RRTypeSrv = "SRV" + + // RRTypeSpf is a RRType enum value + RRTypeSpf = "SPF" + + // RRTypeAaaa is a RRType enum value + RRTypeAaaa = "AAAA" + + // RRTypeCaa is a RRType enum value + RRTypeCaa = "CAA" +) + +const ( + // ResettableElementNameFullyQualifiedDomainName is a ResettableElementName enum value + ResettableElementNameFullyQualifiedDomainName = "FullyQualifiedDomainName" + + // ResettableElementNameRegions is a ResettableElementName enum value + ResettableElementNameRegions = "Regions" + + // ResettableElementNameResourcePath is a ResettableElementName enum value + ResettableElementNameResourcePath = "ResourcePath" + + // ResettableElementNameChildHealthChecks is a ResettableElementName enum value + ResettableElementNameChildHealthChecks = "ChildHealthChecks" +) + +const ( + // ResourceRecordSetFailoverPrimary is a ResourceRecordSetFailover enum value + ResourceRecordSetFailoverPrimary = "PRIMARY" + + // ResourceRecordSetFailoverSecondary is a ResourceRecordSetFailover enum value + ResourceRecordSetFailoverSecondary = "SECONDARY" +) + +const ( + // ResourceRecordSetRegionUsEast1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionUsEast1 = "us-east-1" + + // ResourceRecordSetRegionUsEast2 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionUsEast2 = "us-east-2" + + // ResourceRecordSetRegionUsWest1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionUsWest1 = "us-west-1" + + // ResourceRecordSetRegionUsWest2 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionUsWest2 = "us-west-2" + + // ResourceRecordSetRegionCaCentral1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionCaCentral1 = "ca-central-1" + + // ResourceRecordSetRegionEuWest1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionEuWest1 = "eu-west-1" + + // ResourceRecordSetRegionEuWest2 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionEuWest2 = "eu-west-2" + + // ResourceRecordSetRegionEuWest3 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionEuWest3 = "eu-west-3" + + // ResourceRecordSetRegionEuCentral1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionEuCentral1 = "eu-central-1" + + // ResourceRecordSetRegionApSoutheast1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionApSoutheast1 = "ap-southeast-1" + + // ResourceRecordSetRegionApSoutheast2 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionApSoutheast2 = "ap-southeast-2" + + // ResourceRecordSetRegionApNortheast1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionApNortheast1 = "ap-northeast-1" + + // ResourceRecordSetRegionApNortheast2 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionApNortheast2 = "ap-northeast-2" + + // ResourceRecordSetRegionApNortheast3 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionApNortheast3 = "ap-northeast-3" + + // ResourceRecordSetRegionEuNorth1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionEuNorth1 = "eu-north-1" + + // ResourceRecordSetRegionSaEast1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionSaEast1 = "sa-east-1" + + // ResourceRecordSetRegionCnNorth1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionCnNorth1 = "cn-north-1" + + // ResourceRecordSetRegionCnNorthwest1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionCnNorthwest1 = "cn-northwest-1" + + // ResourceRecordSetRegionApEast1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionApEast1 = "ap-east-1" + + // ResourceRecordSetRegionMeSouth1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionMeSouth1 = "me-south-1" + + // ResourceRecordSetRegionApSouth1 is a ResourceRecordSetRegion enum value + ResourceRecordSetRegionApSouth1 = "ap-south-1" +) + +const ( + // ReusableDelegationSetLimitTypeMaxZonesByReusableDelegationSet is a ReusableDelegationSetLimitType enum value + ReusableDelegationSetLimitTypeMaxZonesByReusableDelegationSet = "MAX_ZONES_BY_REUSABLE_DELEGATION_SET" +) + +const ( + // StatisticAverage is a Statistic enum value + StatisticAverage = "Average" + + // StatisticSum is a Statistic enum value + StatisticSum = "Sum" + + // StatisticSampleCount is a Statistic enum value + StatisticSampleCount = "SampleCount" + + // StatisticMaximum is a Statistic enum value + StatisticMaximum = "Maximum" + + // StatisticMinimum is a Statistic enum value + StatisticMinimum = "Minimum" +) + +const ( + // TagResourceTypeHealthcheck is a TagResourceType enum value + TagResourceTypeHealthcheck = "healthcheck" + + // TagResourceTypeHostedzone is a TagResourceType enum value + TagResourceTypeHostedzone = "hostedzone" +) + +const ( + // VPCRegionUsEast1 is a VPCRegion enum value + VPCRegionUsEast1 = "us-east-1" + + // VPCRegionUsEast2 is a VPCRegion enum value + VPCRegionUsEast2 = "us-east-2" + + // VPCRegionUsWest1 is a VPCRegion enum value + VPCRegionUsWest1 = "us-west-1" + + // VPCRegionUsWest2 is a VPCRegion enum value + VPCRegionUsWest2 = "us-west-2" + + // VPCRegionEuWest1 is a VPCRegion enum value + VPCRegionEuWest1 = "eu-west-1" + + // VPCRegionEuWest2 is a VPCRegion enum value + VPCRegionEuWest2 = "eu-west-2" + + // VPCRegionEuWest3 is a VPCRegion enum value + VPCRegionEuWest3 = "eu-west-3" + + // VPCRegionEuCentral1 is a VPCRegion enum value + VPCRegionEuCentral1 = "eu-central-1" + + // VPCRegionApEast1 is a VPCRegion enum value + VPCRegionApEast1 = "ap-east-1" + + // VPCRegionMeSouth1 is a VPCRegion enum value + VPCRegionMeSouth1 = "me-south-1" + + // VPCRegionApSoutheast1 is a VPCRegion enum value + VPCRegionApSoutheast1 = "ap-southeast-1" + + // VPCRegionApSoutheast2 is a VPCRegion enum value + VPCRegionApSoutheast2 = "ap-southeast-2" + + // VPCRegionApSouth1 is a VPCRegion enum value + VPCRegionApSouth1 = "ap-south-1" + + // VPCRegionApNortheast1 is a VPCRegion enum value + VPCRegionApNortheast1 = "ap-northeast-1" + + // VPCRegionApNortheast2 is a VPCRegion enum value + VPCRegionApNortheast2 = "ap-northeast-2" + + // VPCRegionApNortheast3 is a VPCRegion enum value + VPCRegionApNortheast3 = "ap-northeast-3" + + // VPCRegionEuNorth1 is a VPCRegion enum value + VPCRegionEuNorth1 = "eu-north-1" + + // VPCRegionSaEast1 is a VPCRegion enum value + VPCRegionSaEast1 = "sa-east-1" + + // VPCRegionCaCentral1 is a VPCRegion enum value + VPCRegionCaCentral1 = "ca-central-1" + + // VPCRegionCnNorth1 is a VPCRegion enum value + VPCRegionCnNorth1 = "cn-north-1" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/customizations.go b/vendor/github.com/aws/aws-sdk-go/service/route53/customizations.go new file mode 100644 index 000000000..7aca8722e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/customizations.go @@ -0,0 +1,42 @@ +package route53 + +import ( + "net/url" + "regexp" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/restxml" +) + +func init() { + initClient = func(c *client.Client) { + c.Handlers.Build.PushBack(sanitizeURL) + } + + initRequest = func(r *request.Request) { + switch r.Operation.Name { + case opChangeResourceRecordSets: + r.Handlers.UnmarshalError.Remove(restxml.UnmarshalErrorHandler) + r.Handlers.UnmarshalError.PushBack(unmarshalChangeResourceRecordSetsError) + } + } +} + +var reSanitizeURL = regexp.MustCompile(`\/%2F\w+%2F`) + +func sanitizeURL(r *request.Request) { + r.HTTPRequest.URL.RawPath = + reSanitizeURL.ReplaceAllString(r.HTTPRequest.URL.RawPath, "/") + + // Update Path so that it reflects the cleaned RawPath + updated, err := url.Parse(r.HTTPRequest.URL.RawPath) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to clean Route53 URL", err) + return + } + + // Take the updated path so the requests's URL Path has parity with RawPath. + r.HTTPRequest.URL.Path = updated.Path +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/doc.go b/vendor/github.com/aws/aws-sdk-go/service/route53/doc.go new file mode 100644 index 000000000..386f616db --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/doc.go @@ -0,0 +1,29 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package route53 provides the client and types for making API +// requests to Amazon Route 53. +// +// Amazon Route 53 is a highly available and scalable Domain Name System (DNS) +// web service. +// +// See https://docs.aws.amazon.com/goto/WebAPI/route53-2013-04-01 for more information on this service. +// +// See route53 package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/route53/ +// +// Using the Client +// +// To contact Amazon Route 53 with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the Amazon Route 53 client Route53 for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/route53/#New +package route53 diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/errors.go b/vendor/github.com/aws/aws-sdk-go/service/route53/errors.go new file mode 100644 index 000000000..ce86bd613 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/errors.go @@ -0,0 +1,438 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package route53 + +const ( + + // ErrCodeConcurrentModification for service response error code + // "ConcurrentModification". + // + // Another user submitted a request to create, update, or delete the object + // at the same time that you did. Retry the request. + ErrCodeConcurrentModification = "ConcurrentModification" + + // ErrCodeConflictingDomainExists for service response error code + // "ConflictingDomainExists". + // + // The cause of this error depends on whether you're trying to create a public + // or a private hosted zone: + // + // * Public hosted zone: Two hosted zones that have the same name or that + // have a parent/child relationship (example.com and test.example.com) can't + // have any common name servers. You tried to create a hosted zone that has + // the same name as an existing hosted zone or that's the parent or child + // of an existing hosted zone, and you specified a delegation set that shares + // one or more name servers with the existing hosted zone. For more information, + // see CreateReusableDelegationSet (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateReusableDelegationSet.html). + // + // * Private hosted zone: You specified an Amazon VPC that you're already + // using for another hosted zone, and the domain that you specified for one + // of the hosted zones is a subdomain of the domain that you specified for + // the other hosted zone. For example, you can't use the same Amazon VPC + // for the hosted zones for example.com and test.example.com. + ErrCodeConflictingDomainExists = "ConflictingDomainExists" + + // ErrCodeConflictingTypes for service response error code + // "ConflictingTypes". + // + // You tried to update a traffic policy instance by using a traffic policy version + // that has a different DNS type than the current type for the instance. You + // specified the type in the JSON document in the CreateTrafficPolicy or CreateTrafficPolicyVersionrequest. + ErrCodeConflictingTypes = "ConflictingTypes" + + // ErrCodeDelegationSetAlreadyCreated for service response error code + // "DelegationSetAlreadyCreated". + // + // A delegation set with the same owner and caller reference combination has + // already been created. + ErrCodeDelegationSetAlreadyCreated = "DelegationSetAlreadyCreated" + + // ErrCodeDelegationSetAlreadyReusable for service response error code + // "DelegationSetAlreadyReusable". + // + // The specified delegation set has already been marked as reusable. + ErrCodeDelegationSetAlreadyReusable = "DelegationSetAlreadyReusable" + + // ErrCodeDelegationSetInUse for service response error code + // "DelegationSetInUse". + // + // The specified delegation contains associated hosted zones which must be deleted + // before the reusable delegation set can be deleted. + ErrCodeDelegationSetInUse = "DelegationSetInUse" + + // ErrCodeDelegationSetNotAvailable for service response error code + // "DelegationSetNotAvailable". + // + // You can create a hosted zone that has the same name as an existing hosted + // zone (example.com is common), but there is a limit to the number of hosted + // zones that have the same name. If you get this error, Amazon Route 53 has + // reached that limit. If you own the domain name and Route 53 generates this + // error, contact Customer Support. + ErrCodeDelegationSetNotAvailable = "DelegationSetNotAvailable" + + // ErrCodeDelegationSetNotReusable for service response error code + // "DelegationSetNotReusable". + // + // A reusable delegation set with the specified ID does not exist. + ErrCodeDelegationSetNotReusable = "DelegationSetNotReusable" + + // ErrCodeHealthCheckAlreadyExists for service response error code + // "HealthCheckAlreadyExists". + // + // The health check you're attempting to create already exists. Amazon Route + // 53 returns this error when you submit a request that has the following values: + // + // * The same value for CallerReference as an existing health check, and + // one or more values that differ from the existing health check that has + // the same caller reference. + // + // * The same value for CallerReference as a health check that you created + // and later deleted, regardless of the other settings in the request. + ErrCodeHealthCheckAlreadyExists = "HealthCheckAlreadyExists" + + // ErrCodeHealthCheckInUse for service response error code + // "HealthCheckInUse". + // + // This error code is not in use. + ErrCodeHealthCheckInUse = "HealthCheckInUse" + + // ErrCodeHealthCheckVersionMismatch for service response error code + // "HealthCheckVersionMismatch". + // + // The value of HealthCheckVersion in the request doesn't match the value of + // HealthCheckVersion in the health check. + ErrCodeHealthCheckVersionMismatch = "HealthCheckVersionMismatch" + + // ErrCodeHostedZoneAlreadyExists for service response error code + // "HostedZoneAlreadyExists". + // + // The hosted zone you're trying to create already exists. Amazon Route 53 returns + // this error when a hosted zone has already been created with the specified + // CallerReference. + ErrCodeHostedZoneAlreadyExists = "HostedZoneAlreadyExists" + + // ErrCodeHostedZoneNotEmpty for service response error code + // "HostedZoneNotEmpty". + // + // The hosted zone contains resource records that are not SOA or NS records. + ErrCodeHostedZoneNotEmpty = "HostedZoneNotEmpty" + + // ErrCodeHostedZoneNotFound for service response error code + // "HostedZoneNotFound". + // + // The specified HostedZone can't be found. + ErrCodeHostedZoneNotFound = "HostedZoneNotFound" + + // ErrCodeHostedZoneNotPrivate for service response error code + // "HostedZoneNotPrivate". + // + // The specified hosted zone is a public hosted zone, not a private hosted zone. + ErrCodeHostedZoneNotPrivate = "HostedZoneNotPrivate" + + // ErrCodeIncompatibleVersion for service response error code + // "IncompatibleVersion". + // + // The resource you're trying to access is unsupported on this Amazon Route + // 53 endpoint. + ErrCodeIncompatibleVersion = "IncompatibleVersion" + + // ErrCodeInsufficientCloudWatchLogsResourcePolicy for service response error code + // "InsufficientCloudWatchLogsResourcePolicy". + // + // Amazon Route 53 doesn't have the permissions required to create log streams + // and send query logs to log streams. Possible causes include the following: + // + // * There is no resource policy that specifies the log group ARN in the + // value for Resource. + // + // * The resource policy that includes the log group ARN in the value for + // Resource doesn't have the necessary permissions. + // + // * The resource policy hasn't finished propagating yet. + ErrCodeInsufficientCloudWatchLogsResourcePolicy = "InsufficientCloudWatchLogsResourcePolicy" + + // ErrCodeInvalidArgument for service response error code + // "InvalidArgument". + // + // Parameter name is invalid. + ErrCodeInvalidArgument = "InvalidArgument" + + // ErrCodeInvalidChangeBatch for service response error code + // "InvalidChangeBatch". + // + // This exception contains a list of messages that might contain one or more + // error messages. Each error message indicates one error in the change batch. + ErrCodeInvalidChangeBatch = "InvalidChangeBatch" + + // ErrCodeInvalidDomainName for service response error code + // "InvalidDomainName". + // + // The specified domain name is not valid. + ErrCodeInvalidDomainName = "InvalidDomainName" + + // ErrCodeInvalidInput for service response error code + // "InvalidInput". + // + // The input is not valid. + ErrCodeInvalidInput = "InvalidInput" + + // ErrCodeInvalidPaginationToken for service response error code + // "InvalidPaginationToken". + // + // The value that you specified to get the second or subsequent page of results + // is invalid. + ErrCodeInvalidPaginationToken = "InvalidPaginationToken" + + // ErrCodeInvalidTrafficPolicyDocument for service response error code + // "InvalidTrafficPolicyDocument". + // + // The format of the traffic policy document that you specified in the Document + // element is invalid. + ErrCodeInvalidTrafficPolicyDocument = "InvalidTrafficPolicyDocument" + + // ErrCodeInvalidVPCId for service response error code + // "InvalidVPCId". + // + // The VPC ID that you specified either isn't a valid ID or the current account + // is not authorized to access this VPC. + ErrCodeInvalidVPCId = "InvalidVPCId" + + // ErrCodeLastVPCAssociation for service response error code + // "LastVPCAssociation". + // + // The VPC that you're trying to disassociate from the private hosted zone is + // the last VPC that is associated with the hosted zone. Amazon Route 53 doesn't + // support disassociating the last VPC from a hosted zone. + ErrCodeLastVPCAssociation = "LastVPCAssociation" + + // ErrCodeLimitsExceeded for service response error code + // "LimitsExceeded". + // + // This operation can't be completed either because the current account has + // reached the limit on reusable delegation sets that it can create or because + // you've reached the limit on the number of Amazon VPCs that you can associate + // with a private hosted zone. To get the current limit on the number of reusable + // delegation sets, see GetAccountLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). + // To get the current limit on the number of Amazon VPCs that you can associate + // with a private hosted zone, see GetHostedZoneLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetHostedZoneLimit.html). + // To request a higher limit, create a case (http://aws.amazon.com/route53-request) + // with the AWS Support Center. + ErrCodeLimitsExceeded = "LimitsExceeded" + + // ErrCodeNoSuchChange for service response error code + // "NoSuchChange". + // + // A change with the specified change ID does not exist. + ErrCodeNoSuchChange = "NoSuchChange" + + // ErrCodeNoSuchCloudWatchLogsLogGroup for service response error code + // "NoSuchCloudWatchLogsLogGroup". + // + // There is no CloudWatch Logs log group with the specified ARN. + ErrCodeNoSuchCloudWatchLogsLogGroup = "NoSuchCloudWatchLogsLogGroup" + + // ErrCodeNoSuchDelegationSet for service response error code + // "NoSuchDelegationSet". + // + // A reusable delegation set with the specified ID does not exist. + ErrCodeNoSuchDelegationSet = "NoSuchDelegationSet" + + // ErrCodeNoSuchGeoLocation for service response error code + // "NoSuchGeoLocation". + // + // Amazon Route 53 doesn't support the specified geographic location. + ErrCodeNoSuchGeoLocation = "NoSuchGeoLocation" + + // ErrCodeNoSuchHealthCheck for service response error code + // "NoSuchHealthCheck". + // + // No health check exists with the specified ID. + ErrCodeNoSuchHealthCheck = "NoSuchHealthCheck" + + // ErrCodeNoSuchHostedZone for service response error code + // "NoSuchHostedZone". + // + // No hosted zone exists with the ID that you specified. + ErrCodeNoSuchHostedZone = "NoSuchHostedZone" + + // ErrCodeNoSuchQueryLoggingConfig for service response error code + // "NoSuchQueryLoggingConfig". + // + // There is no DNS query logging configuration with the specified ID. + ErrCodeNoSuchQueryLoggingConfig = "NoSuchQueryLoggingConfig" + + // ErrCodeNoSuchTrafficPolicy for service response error code + // "NoSuchTrafficPolicy". + // + // No traffic policy exists with the specified ID. + ErrCodeNoSuchTrafficPolicy = "NoSuchTrafficPolicy" + + // ErrCodeNoSuchTrafficPolicyInstance for service response error code + // "NoSuchTrafficPolicyInstance". + // + // No traffic policy instance exists with the specified ID. + ErrCodeNoSuchTrafficPolicyInstance = "NoSuchTrafficPolicyInstance" + + // ErrCodeNotAuthorizedException for service response error code + // "NotAuthorizedException". + // + // Associating the specified VPC with the specified hosted zone has not been + // authorized. + ErrCodeNotAuthorizedException = "NotAuthorizedException" + + // ErrCodePriorRequestNotComplete for service response error code + // "PriorRequestNotComplete". + // + // If Amazon Route 53 can't process a request before the next request arrives, + // it will reject subsequent requests for the same hosted zone and return an + // HTTP 400 error (Bad request). If Route 53 returns this error repeatedly for + // the same request, we recommend that you wait, in intervals of increasing + // duration, before you try the request again. + ErrCodePriorRequestNotComplete = "PriorRequestNotComplete" + + // ErrCodePublicZoneVPCAssociation for service response error code + // "PublicZoneVPCAssociation". + // + // You're trying to associate a VPC with a public hosted zone. Amazon Route + // 53 doesn't support associating a VPC with a public hosted zone. + ErrCodePublicZoneVPCAssociation = "PublicZoneVPCAssociation" + + // ErrCodeQueryLoggingConfigAlreadyExists for service response error code + // "QueryLoggingConfigAlreadyExists". + // + // You can create only one query logging configuration for a hosted zone, and + // a query logging configuration already exists for this hosted zone. + ErrCodeQueryLoggingConfigAlreadyExists = "QueryLoggingConfigAlreadyExists" + + // ErrCodeThrottlingException for service response error code + // "ThrottlingException". + // + // The limit on the number of requests per second was exceeded. + ErrCodeThrottlingException = "ThrottlingException" + + // ErrCodeTooManyHealthChecks for service response error code + // "TooManyHealthChecks". + // + // This health check can't be created because the current account has reached + // the limit on the number of active health checks. + // + // For information about default limits, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) + // in the Amazon Route 53 Developer Guide. + // + // For information about how to get the current limit for an account, see GetAccountLimit + // (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). + // To request a higher limit, create a case (http://aws.amazon.com/route53-request) + // with the AWS Support Center. + // + // You have reached the maximum number of active health checks for an AWS account. + // To request a higher limit, create a case (http://aws.amazon.com/route53-request) + // with the AWS Support Center. + ErrCodeTooManyHealthChecks = "TooManyHealthChecks" + + // ErrCodeTooManyHostedZones for service response error code + // "TooManyHostedZones". + // + // This operation can't be completed either because the current account has + // reached the limit on the number of hosted zones or because you've reached + // the limit on the number of hosted zones that can be associated with a reusable + // delegation set. + // + // For information about default limits, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) + // in the Amazon Route 53 Developer Guide. + // + // To get the current limit on hosted zones that can be created by an account, + // see GetAccountLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). + // + // To get the current limit on hosted zones that can be associated with a reusable + // delegation set, see GetReusableDelegationSetLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetReusableDelegationSetLimit.html). + // + // To request a higher limit, create a case (http://aws.amazon.com/route53-request) + // with the AWS Support Center. + ErrCodeTooManyHostedZones = "TooManyHostedZones" + + // ErrCodeTooManyTrafficPolicies for service response error code + // "TooManyTrafficPolicies". + // + // This traffic policy can't be created because the current account has reached + // the limit on the number of traffic policies. + // + // For information about default limits, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) + // in the Amazon Route 53 Developer Guide. + // + // To get the current limit for an account, see GetAccountLimit (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). + // + // To request a higher limit, create a case (http://aws.amazon.com/route53-request) + // with the AWS Support Center. + ErrCodeTooManyTrafficPolicies = "TooManyTrafficPolicies" + + // ErrCodeTooManyTrafficPolicyInstances for service response error code + // "TooManyTrafficPolicyInstances". + // + // This traffic policy instance can't be created because the current account + // has reached the limit on the number of traffic policy instances. + // + // For information about default limits, see Limits (https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html) + // in the Amazon Route 53 Developer Guide. + // + // For information about how to get the current limit for an account, see GetAccountLimit + // (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetAccountLimit.html). + // + // To request a higher limit, create a case (http://aws.amazon.com/route53-request) + // with the AWS Support Center. + ErrCodeTooManyTrafficPolicyInstances = "TooManyTrafficPolicyInstances" + + // ErrCodeTooManyTrafficPolicyVersionsForCurrentPolicy for service response error code + // "TooManyTrafficPolicyVersionsForCurrentPolicy". + // + // This traffic policy version can't be created because you've reached the limit + // of 1000 on the number of versions that you can create for the current traffic + // policy. + // + // To create more traffic policy versions, you can use GetTrafficPolicy (https://docs.aws.amazon.com/Route53/latest/APIReference/API_GetTrafficPolicy.html) + // to get the traffic policy document for a specified traffic policy version, + // and then use CreateTrafficPolicy (https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateTrafficPolicy.html) + // to create a new traffic policy using the traffic policy document. + ErrCodeTooManyTrafficPolicyVersionsForCurrentPolicy = "TooManyTrafficPolicyVersionsForCurrentPolicy" + + // ErrCodeTooManyVPCAssociationAuthorizations for service response error code + // "TooManyVPCAssociationAuthorizations". + // + // You've created the maximum number of authorizations that can be created for + // the specified hosted zone. To authorize another VPC to be associated with + // the hosted zone, submit a DeleteVPCAssociationAuthorization request to remove + // an existing authorization. To get a list of existing authorizations, submit + // a ListVPCAssociationAuthorizations request. + ErrCodeTooManyVPCAssociationAuthorizations = "TooManyVPCAssociationAuthorizations" + + // ErrCodeTrafficPolicyAlreadyExists for service response error code + // "TrafficPolicyAlreadyExists". + // + // A traffic policy that has the same value for Name already exists. + ErrCodeTrafficPolicyAlreadyExists = "TrafficPolicyAlreadyExists" + + // ErrCodeTrafficPolicyInUse for service response error code + // "TrafficPolicyInUse". + // + // One or more traffic policy instances were created by using the specified + // traffic policy. + ErrCodeTrafficPolicyInUse = "TrafficPolicyInUse" + + // ErrCodeTrafficPolicyInstanceAlreadyExists for service response error code + // "TrafficPolicyInstanceAlreadyExists". + // + // There is already a traffic policy instance with the specified ID. + ErrCodeTrafficPolicyInstanceAlreadyExists = "TrafficPolicyInstanceAlreadyExists" + + // ErrCodeVPCAssociationAuthorizationNotFound for service response error code + // "VPCAssociationAuthorizationNotFound". + // + // The VPC that you specified is not authorized to be associated with the hosted + // zone. + ErrCodeVPCAssociationAuthorizationNotFound = "VPCAssociationAuthorizationNotFound" + + // ErrCodeVPCAssociationNotFound for service response error code + // "VPCAssociationNotFound". + // + // The specified VPC and hosted zone are not currently associated. + ErrCodeVPCAssociationNotFound = "VPCAssociationNotFound" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/service.go b/vendor/github.com/aws/aws-sdk-go/service/route53/service.go new file mode 100644 index 000000000..dd22cb2cd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/service.go @@ -0,0 +1,95 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package route53 + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol/restxml" +) + +// Route53 provides the API operation methods for making requests to +// Amazon Route 53. See this package's package overview docs +// for details on the service. +// +// Route53 methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type Route53 struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "route53" // Name of service. + EndpointsID = ServiceName // ID to lookup a service endpoint with. + ServiceID = "Route 53" // ServiceID is a unique identifer of a specific service. +) + +// New creates a new instance of the Route53 client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// // Create a Route53 client from just a session. +// svc := route53.New(mySession) +// +// // Create a Route53 client with additional configuration +// svc := route53.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *Route53 { + c := p.ClientConfig(EndpointsID, cfgs...) + return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *Route53 { + svc := &Route53{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + Endpoint: endpoint, + APIVersion: "2013-04-01", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(restxml.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(restxml.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a Route53 operation and runs any +// custom request initialization. +func (c *Route53) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/service/route53/unmarshal_error.go new file mode 100644 index 000000000..b3b95a126 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/unmarshal_error.go @@ -0,0 +1,106 @@ +package route53 + +import ( + "encoding/xml" + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +const errorRespTag = "ErrorResponse" +const invalidChangeTag = "InvalidChangeBatch" + +type standardXMLErrorResponse struct { + Code string `xml:"Error>Code"` + Message string `xml:"Error>Message"` + RequestID string `xml:"RequestId"` +} + +func (e standardXMLErrorResponse) FillCommon(c *xmlErrorResponse) { + c.Code = e.Code + c.Message = e.Message + c.RequestID = e.RequestID +} + +type invalidChangeBatchXMLErrorResponse struct { + Messages []string `xml:"Messages>Message"` + RequestID string `xml:"RequestId"` +} + +func (e invalidChangeBatchXMLErrorResponse) FillCommon(c *xmlErrorResponse) { + c.Code = invalidChangeTag + c.Message = "ChangeBatch errors occurred" + c.Messages = e.Messages + c.RequestID = e.RequestID +} + +type xmlErrorResponse struct { + Code string + Message string + Messages []string + RequestID string +} + +func (e *xmlErrorResponse) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type commonFiller interface { + FillCommon(*xmlErrorResponse) + } + + var errResp commonFiller + switch start.Name.Local { + case errorRespTag: + errResp = &standardXMLErrorResponse{} + + case invalidChangeTag: + errResp = &invalidChangeBatchXMLErrorResponse{} + + default: + return fmt.Errorf("unknown error message, %v", start.Name.Local) + } + + if err := d.DecodeElement(errResp, &start); err != nil { + return err + } + + errResp.FillCommon(e) + return nil +} + +func unmarshalChangeResourceRecordSetsError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + var errResp xmlErrorResponse + err := xmlutil.UnmarshalXMLError(&errResp, r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to unmarshal error message", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + + var baseErr awserr.Error + if len(errResp.Messages) != 0 { + var errs []error + for _, msg := range errResp.Messages { + errs = append(errs, awserr.New(invalidChangeTag, msg, nil)) + } + baseErr = awserr.NewBatchError(errResp.Code, errResp.Message, errs) + } else { + baseErr = awserr.New(errResp.Code, errResp.Message, nil) + } + + reqID := errResp.RequestID + if len(reqID) == 0 { + reqID = r.RequestID + } + r.Error = awserr.NewRequestFailure( + baseErr, + r.HTTPResponse.StatusCode, + reqID, + ) +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/route53/waiters.go b/vendor/github.com/aws/aws-sdk-go/service/route53/waiters.go new file mode 100644 index 000000000..9bd7a9a71 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/route53/waiters.go @@ -0,0 +1,56 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package route53 + +import ( + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +// WaitUntilResourceRecordSetsChanged uses the Route 53 API operation +// GetChange to wait for a condition to be met before returning. +// If the condition is not met within the max attempt window, an error will +// be returned. +func (c *Route53) WaitUntilResourceRecordSetsChanged(input *GetChangeInput) error { + return c.WaitUntilResourceRecordSetsChangedWithContext(aws.BackgroundContext(), input) +} + +// WaitUntilResourceRecordSetsChangedWithContext is an extended version of WaitUntilResourceRecordSetsChanged. +// With the support for passing in a context and options to configure the +// Waiter and the underlying request options. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *Route53) WaitUntilResourceRecordSetsChangedWithContext(ctx aws.Context, input *GetChangeInput, opts ...request.WaiterOption) error { + w := request.Waiter{ + Name: "WaitUntilResourceRecordSetsChanged", + MaxAttempts: 60, + Delay: request.ConstantWaiterDelay(30 * time.Second), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathWaiterMatch, Argument: "ChangeInfo.Status", + Expected: "INSYNC", + }, + }, + Logger: c.Config.Logger, + NewRequest: func(opts []request.Option) (*request.Request, error) { + var inCpy *GetChangeInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetChangeRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + w.ApplyOptions(opts...) + + return w.WaitWithContext(ctx) +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go new file mode 100644 index 000000000..eb0a6a417 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -0,0 +1,2750 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" +) + +const opAssumeRole = "AssumeRole" + +// AssumeRoleRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRole operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssumeRole for more information on using the AssumeRole +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssumeRoleRequest method. +// req, resp := client.AssumeRoleRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole +func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) { + op := &request.Operation{ + Name: opAssumeRole, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleInput{} + } + + output = &AssumeRoleOutput{} + req = c.newRequest(op, input, output) + return +} + +// AssumeRole API operation for AWS Security Token Service. +// +// Returns a set of temporary security credentials that you can use to access +// AWS resources that you might not normally have access to. These temporary +// credentials consist of an access key ID, a secret access key, and a security +// token. Typically, you use AssumeRole within your account or for cross-account +// access. For a comparison of AssumeRole with other API operations that produce +// temporary credentials, see Requesting Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// You cannot use AWS account root user credentials to call AssumeRole. You +// must use credentials for an IAM user or an IAM role to call AssumeRole. +// +// For cross-account access, imagine that you own multiple accounts and need +// to access resources in each account. You could create long-term credentials +// in each account to access those resources. However, managing all those credentials +// and remembering which one can access which account can be time consuming. +// Instead, you can create one set of long-term credentials in one account. +// Then use temporary security credentials to access all the other accounts +// by assuming roles in those accounts. For more information about roles, see +// IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) +// in the IAM User Guide. +// +// By default, the temporary security credentials created by AssumeRole last +// for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. You can provide a value from 900 +// seconds (15 minutes) up to the maximum session duration setting for the role. +// This setting can have a value from 1 hour to 12 hours. To learn how to view +// the maximum value for your role, see View the Maximum Session Duration Setting +// for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI commands. However +// the limit does not apply when you use those operations to create a console +// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRole can be used to make +// API calls to any AWS service with the following exception: You cannot call +// the AWS STS GetFederationToken or GetSessionToken API operations. +// +// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// to this operation. You can pass a single JSON policy document to use as an +// inline session policy. You can also specify up to 10 managed policies to +// use as managed session policies. The plain text that you use for both inline +// and managed session policies shouldn't exceed 2048 characters. Passing policies +// to this operation returns new temporary credentials. The resulting session's +// permissions are the intersection of the role's identity-based policy and +// the session policies. You can use the role's temporary credentials in subsequent +// AWS API calls to access resources in the account that owns the role. You +// cannot use session policies to grant more permissions than those allowed +// by the identity-based policy of the role that is being assumed. For more +// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// in the IAM User Guide. +// +// To assume a role from a different account, your AWS account must be trusted +// by the role. The trust relationship is defined in the role's trust policy +// when the role is created. That trust policy states which accounts are allowed +// to delegate that access to users in the account. +// +// A user who wants to access a role in a different account must also have permissions +// that are delegated from the user account administrator. The administrator +// must attach a policy that allows the user to call AssumeRole for the ARN +// of the role in the other account. If the user is in the same account as the +// role, then you can do either of the following: +// +// * Attach a policy to the user (identical to the previous user in a different +// account). +// +// * Add the user as a principal directly in the role's trust policy. +// +// In this case, the trust policy acts as an IAM resource-based policy. Users +// in the same account as the role do not need explicit permission to assume +// the role. For more information about trust policies and resource-based policies, +// see IAM Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) +// in the IAM User Guide. +// +// Using MFA with AssumeRole +// +// (Optional) You can include multi-factor authentication (MFA) information +// when you call AssumeRole. This is useful for cross-account scenarios to ensure +// that the user that assumes the role has been authenticated with an AWS MFA +// device. In that scenario, the trust policy of the role being assumed includes +// a condition that tests for MFA authentication. If the caller does not include +// valid MFA information, the request to assume the role is denied. The condition +// in a trust policy that tests for MFA authentication might look like the following +// example. +// +// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}} +// +// For more information, see Configuring MFA-Protected API Access (https://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html) +// in the IAM User Guide guide. +// +// To use MFA with AssumeRole, you pass values for the SerialNumber and TokenCode +// parameters. The SerialNumber value identifies the user's hardware or virtual +// MFA device. The TokenCode is the time-based one-time password (TOTP) that +// the MFA device produces. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation AssumeRole for usage and error information. +// +// Returned Error Codes: +// * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument" +// The request was rejected because the policy document was malformed. The error +// message describes the specific error. +// +// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" +// The request was rejected because the policy document was too large. The error +// message describes how big the policy document is, in packed form, as a percentage +// of what the API allows. +// +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole +func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) { + req, out := c.AssumeRoleRequest(input) + return out, req.Send() +} + +// AssumeRoleWithContext is the same as AssumeRole with the addition of +// the ability to pass a context and additional request options. +// +// See AssumeRole for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) AssumeRoleWithContext(ctx aws.Context, input *AssumeRoleInput, opts ...request.Option) (*AssumeRoleOutput, error) { + req, out := c.AssumeRoleRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAssumeRoleWithSAML = "AssumeRoleWithSAML" + +// AssumeRoleWithSAMLRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRoleWithSAML operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssumeRoleWithSAML for more information on using the AssumeRoleWithSAML +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssumeRoleWithSAMLRequest method. +// req, resp := client.AssumeRoleWithSAMLRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML +func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) { + op := &request.Operation{ + Name: opAssumeRoleWithSAML, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleWithSAMLInput{} + } + + output = &AssumeRoleWithSAMLOutput{} + req = c.newRequest(op, input, output) + req.Config.Credentials = credentials.AnonymousCredentials + return +} + +// AssumeRoleWithSAML API operation for AWS Security Token Service. +// +// Returns a set of temporary security credentials for users who have been authenticated +// via a SAML authentication response. This operation provides a mechanism for +// tying an enterprise identity store or directory to role-based AWS access +// without user-specific credentials or configuration. For a comparison of AssumeRoleWithSAML +// with the other API operations that produce temporary credentials, see Requesting +// Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The temporary security credentials returned by this operation consist of +// an access key ID, a secret access key, and a security token. Applications +// can use these temporary security credentials to sign calls to AWS services. +// +// By default, the temporary security credentials created by AssumeRoleWithSAML +// last for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. Your role session lasts for the +// duration that you specify, or until the time specified in the SAML authentication +// response's SessionNotOnOrAfter value, whichever is shorter. You can provide +// a DurationSeconds value from 900 seconds (15 minutes) up to the maximum session +// duration setting for the role. This setting can have a value from 1 hour +// to 12 hours. To learn how to view the maximum value for your role, see View +// the Maximum Session Duration Setting for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI commands. However +// the limit does not apply when you use those operations to create a console +// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRoleWithSAML can be used +// to make API calls to any AWS service with the following exception: you cannot +// call the STS GetFederationToken or GetSessionToken API operations. +// +// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// to this operation. You can pass a single JSON policy document to use as an +// inline session policy. You can also specify up to 10 managed policies to +// use as managed session policies. The plain text that you use for both inline +// and managed session policies shouldn't exceed 2048 characters. Passing policies +// to this operation returns new temporary credentials. The resulting session's +// permissions are the intersection of the role's identity-based policy and +// the session policies. You can use the role's temporary credentials in subsequent +// AWS API calls to access resources in the account that owns the role. You +// cannot use session policies to grant more permissions than those allowed +// by the identity-based policy of the role that is being assumed. For more +// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// in the IAM User Guide. +// +// Before your application can call AssumeRoleWithSAML, you must configure your +// SAML identity provider (IdP) to issue the claims required by AWS. Additionally, +// you must use AWS Identity and Access Management (IAM) to create a SAML provider +// entity in your AWS account that represents your identity provider. You must +// also create an IAM role that specifies this SAML provider in its trust policy. +// +// Calling AssumeRoleWithSAML does not require the use of AWS security credentials. +// The identity of the caller is validated by using keys in the metadata document +// that is uploaded for the SAML provider entity for your identity provider. +// +// Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail +// logs. The entry includes the value in the NameID element of the SAML assertion. +// We recommend that you use a NameIDType that is not associated with any personally +// identifiable information (PII). For example, you could instead use the Persistent +// Identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent). +// +// For more information, see the following resources: +// +// * About SAML 2.0-based Federation (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html) +// in the IAM User Guide. +// +// * Creating SAML Identity Providers (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html) +// in the IAM User Guide. +// +// * Configuring a Relying Party and Claims (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html) +// in the IAM User Guide. +// +// * Creating a Role for SAML 2.0 Federation (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html) +// in the IAM User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation AssumeRoleWithSAML for usage and error information. +// +// Returned Error Codes: +// * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument" +// The request was rejected because the policy document was malformed. The error +// message describes the specific error. +// +// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" +// The request was rejected because the policy document was too large. The error +// message describes how big the policy document is, in packed form, as a percentage +// of what the API allows. +// +// * ErrCodeIDPRejectedClaimException "IDPRejectedClaim" +// The identity provider (IdP) reported that authentication failed. This might +// be because the claim is invalid. +// +// If this error is returned for the AssumeRoleWithWebIdentity operation, it +// can also mean that the claim has expired or has been explicitly revoked. +// +// * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken" +// The web identity token that was passed could not be validated by AWS. Get +// a new identity token from the identity provider and then retry the request. +// +// * ErrCodeExpiredTokenException "ExpiredTokenException" +// The web identity token that was passed is expired or is not valid. Get a +// new identity token from the identity provider and then retry the request. +// +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML +func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) { + req, out := c.AssumeRoleWithSAMLRequest(input) + return out, req.Send() +} + +// AssumeRoleWithSAMLWithContext is the same as AssumeRoleWithSAML with the addition of +// the ability to pass a context and additional request options. +// +// See AssumeRoleWithSAML for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) AssumeRoleWithSAMLWithContext(ctx aws.Context, input *AssumeRoleWithSAMLInput, opts ...request.Option) (*AssumeRoleWithSAMLOutput, error) { + req, out := c.AssumeRoleWithSAMLRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity" + +// AssumeRoleWithWebIdentityRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRoleWithWebIdentity operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssumeRoleWithWebIdentity for more information on using the AssumeRoleWithWebIdentity +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssumeRoleWithWebIdentityRequest method. +// req, resp := client.AssumeRoleWithWebIdentityRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity +func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) { + op := &request.Operation{ + Name: opAssumeRoleWithWebIdentity, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleWithWebIdentityInput{} + } + + output = &AssumeRoleWithWebIdentityOutput{} + req = c.newRequest(op, input, output) + req.Config.Credentials = credentials.AnonymousCredentials + return +} + +// AssumeRoleWithWebIdentity API operation for AWS Security Token Service. +// +// Returns a set of temporary security credentials for users who have been authenticated +// in a mobile or web application with a web identity provider. Example providers +// include Amazon Cognito, Login with Amazon, Facebook, Google, or any OpenID +// Connect-compatible identity provider. +// +// For mobile applications, we recommend that you use Amazon Cognito. You can +// use Amazon Cognito with the AWS SDK for iOS Developer Guide (http://aws.amazon.com/sdkforios/) +// and the AWS SDK for Android Developer Guide (http://aws.amazon.com/sdkforandroid/) +// to uniquely identify a user. You can also supply the user with a consistent +// identity throughout the lifetime of an application. +// +// To learn more about Amazon Cognito, see Amazon Cognito Overview (https://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html#d0e840) +// in AWS SDK for Android Developer Guide and Amazon Cognito Overview (https://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#d0e664) +// in the AWS SDK for iOS Developer Guide. +// +// Calling AssumeRoleWithWebIdentity does not require the use of AWS security +// credentials. Therefore, you can distribute an application (for example, on +// mobile devices) that requests temporary security credentials without including +// long-term AWS credentials in the application. You also don't need to deploy +// server-based proxy services that use long-term AWS credentials. Instead, +// the identity of the caller is validated by using a token from the web identity +// provider. For a comparison of AssumeRoleWithWebIdentity with the other API +// operations that produce temporary credentials, see Requesting Temporary Security +// Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The temporary security credentials returned by this API consist of an access +// key ID, a secret access key, and a security token. Applications can use these +// temporary security credentials to sign calls to AWS service API operations. +// +// By default, the temporary security credentials created by AssumeRoleWithWebIdentity +// last for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. You can provide a value from 900 +// seconds (15 minutes) up to the maximum session duration setting for the role. +// This setting can have a value from 1 hour to 12 hours. To learn how to view +// the maximum value for your role, see View the Maximum Session Duration Setting +// for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI commands. However +// the limit does not apply when you use those operations to create a console +// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRoleWithWebIdentity can +// be used to make API calls to any AWS service with the following exception: +// you cannot call the STS GetFederationToken or GetSessionToken API operations. +// +// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// to this operation. You can pass a single JSON policy document to use as an +// inline session policy. You can also specify up to 10 managed policies to +// use as managed session policies. The plain text that you use for both inline +// and managed session policies shouldn't exceed 2048 characters. Passing policies +// to this operation returns new temporary credentials. The resulting session's +// permissions are the intersection of the role's identity-based policy and +// the session policies. You can use the role's temporary credentials in subsequent +// AWS API calls to access resources in the account that owns the role. You +// cannot use session policies to grant more permissions than those allowed +// by the identity-based policy of the role that is being assumed. For more +// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// in the IAM User Guide. +// +// Before your application can call AssumeRoleWithWebIdentity, you must have +// an identity token from a supported identity provider and create a role that +// the application can assume. The role that your application assumes must trust +// the identity provider that is associated with the identity token. In other +// words, the identity provider must be specified in the role's trust policy. +// +// Calling AssumeRoleWithWebIdentity can result in an entry in your AWS CloudTrail +// logs. The entry includes the Subject (http://openid.net/specs/openid-connect-core-1_0.html#Claims) +// of the provided Web Identity Token. We recommend that you avoid using any +// personally identifiable information (PII) in this field. For example, you +// could instead use a GUID or a pairwise identifier, as suggested in the OIDC +// specification (http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes). +// +// For more information about how to use web identity federation and the AssumeRoleWithWebIdentity +// API, see the following resources: +// +// * Using Web Identity Federation API Operations for Mobile Apps (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html) +// and Federation Through a Web-based Identity Provider (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). +// +// * Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html). +// Walk through the process of authenticating through Login with Amazon, +// Facebook, or Google, getting temporary security credentials, and then +// using those credentials to make a request to AWS. +// +// * AWS SDK for iOS Developer Guide (http://aws.amazon.com/sdkforios/) and +// AWS SDK for Android Developer Guide (http://aws.amazon.com/sdkforandroid/). +// These toolkits contain sample apps that show how to invoke the identity +// providers, and then how to use the information from these providers to +// get and use temporary security credentials. +// +// * Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications). +// This article discusses web identity federation and shows an example of +// how to use web identity federation to get access to content in Amazon +// S3. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation AssumeRoleWithWebIdentity for usage and error information. +// +// Returned Error Codes: +// * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument" +// The request was rejected because the policy document was malformed. The error +// message describes the specific error. +// +// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" +// The request was rejected because the policy document was too large. The error +// message describes how big the policy document is, in packed form, as a percentage +// of what the API allows. +// +// * ErrCodeIDPRejectedClaimException "IDPRejectedClaim" +// The identity provider (IdP) reported that authentication failed. This might +// be because the claim is invalid. +// +// If this error is returned for the AssumeRoleWithWebIdentity operation, it +// can also mean that the claim has expired or has been explicitly revoked. +// +// * ErrCodeIDPCommunicationErrorException "IDPCommunicationError" +// The request could not be fulfilled because the non-AWS identity provider +// (IDP) that was asked to verify the incoming identity token could not be reached. +// This is often a transient error caused by network conditions. Retry the request +// a limited number of times so that you don't exceed the request rate. If the +// error persists, the non-AWS identity provider might be down or not responding. +// +// * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken" +// The web identity token that was passed could not be validated by AWS. Get +// a new identity token from the identity provider and then retry the request. +// +// * ErrCodeExpiredTokenException "ExpiredTokenException" +// The web identity token that was passed is expired or is not valid. Get a +// new identity token from the identity provider and then retry the request. +// +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity +func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) { + req, out := c.AssumeRoleWithWebIdentityRequest(input) + return out, req.Send() +} + +// AssumeRoleWithWebIdentityWithContext is the same as AssumeRoleWithWebIdentity with the addition of +// the ability to pass a context and additional request options. +// +// See AssumeRoleWithWebIdentity for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) AssumeRoleWithWebIdentityWithContext(ctx aws.Context, input *AssumeRoleWithWebIdentityInput, opts ...request.Option) (*AssumeRoleWithWebIdentityOutput, error) { + req, out := c.AssumeRoleWithWebIdentityRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage" + +// DecodeAuthorizationMessageRequest generates a "aws/request.Request" representing the +// client's request for the DecodeAuthorizationMessage operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DecodeAuthorizationMessage for more information on using the DecodeAuthorizationMessage +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DecodeAuthorizationMessageRequest method. +// req, resp := client.DecodeAuthorizationMessageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage +func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) { + op := &request.Operation{ + Name: opDecodeAuthorizationMessage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DecodeAuthorizationMessageInput{} + } + + output = &DecodeAuthorizationMessageOutput{} + req = c.newRequest(op, input, output) + return +} + +// DecodeAuthorizationMessage API operation for AWS Security Token Service. +// +// Decodes additional information about the authorization status of a request +// from an encoded message returned in response to an AWS request. +// +// For example, if a user is not authorized to perform an operation that he +// or she has requested, the request returns a Client.UnauthorizedOperation +// response (an HTTP 403 response). Some AWS operations additionally return +// an encoded message that can provide details about this authorization failure. +// +// Only certain AWS operations return an encoded authorization message. The +// documentation for an individual operation indicates whether that operation +// returns an encoded message in addition to returning an HTTP code. +// +// The message is encoded because the details of the authorization status can +// constitute privileged information that the user who requested the operation +// should not see. To decode an authorization status message, a user must be +// granted permissions via an IAM policy to request the DecodeAuthorizationMessage +// (sts:DecodeAuthorizationMessage) action. +// +// The decoded message includes the following type of information: +// +// * Whether the request was denied due to an explicit deny or due to the +// absence of an explicit allow. For more information, see Determining Whether +// a Request is Allowed or Denied (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow) +// in the IAM User Guide. +// +// * The principal who made the request. +// +// * The requested action. +// +// * The requested resource. +// +// * The values of condition keys in the context of the user's request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation DecodeAuthorizationMessage for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidAuthorizationMessageException "InvalidAuthorizationMessageException" +// The error returned if the message passed to DecodeAuthorizationMessage was +// invalid. This can happen if the token contains invalid characters, such as +// linebreaks. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage +func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) { + req, out := c.DecodeAuthorizationMessageRequest(input) + return out, req.Send() +} + +// DecodeAuthorizationMessageWithContext is the same as DecodeAuthorizationMessage with the addition of +// the ability to pass a context and additional request options. +// +// See DecodeAuthorizationMessage for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) DecodeAuthorizationMessageWithContext(ctx aws.Context, input *DecodeAuthorizationMessageInput, opts ...request.Option) (*DecodeAuthorizationMessageOutput, error) { + req, out := c.DecodeAuthorizationMessageRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetAccessKeyInfo = "GetAccessKeyInfo" + +// GetAccessKeyInfoRequest generates a "aws/request.Request" representing the +// client's request for the GetAccessKeyInfo operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetAccessKeyInfo for more information on using the GetAccessKeyInfo +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetAccessKeyInfoRequest method. +// req, resp := client.GetAccessKeyInfoRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetAccessKeyInfo +func (c *STS) GetAccessKeyInfoRequest(input *GetAccessKeyInfoInput) (req *request.Request, output *GetAccessKeyInfoOutput) { + op := &request.Operation{ + Name: opGetAccessKeyInfo, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetAccessKeyInfoInput{} + } + + output = &GetAccessKeyInfoOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetAccessKeyInfo API operation for AWS Security Token Service. +// +// Returns the account identifier for the specified access key ID. +// +// Access keys consist of two parts: an access key ID (for example, AKIAIOSFODNN7EXAMPLE) +// and a secret access key (for example, wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY). +// For more information about access keys, see Managing Access Keys for IAM +// Users (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) +// in the IAM User Guide. +// +// When you pass an access key ID to this operation, it returns the ID of the +// AWS account to which the keys belong. Access key IDs beginning with AKIA +// are long-term credentials for an IAM user or the AWS account root user. Access +// key IDs beginning with ASIA are temporary credentials that are created using +// STS operations. If the account in the response belongs to you, you can sign +// in as the root user and review your root user access keys. Then, you can +// pull a credentials report (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html) +// to learn which IAM user owns the keys. To learn who requested the temporary +// credentials for an ASIA access key, view the STS events in your CloudTrail +// logs (https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html). +// +// This operation does not indicate the state of the access key. The key might +// be active, inactive, or deleted. Active keys might not have permissions to +// perform an operation. Providing a deleted access key might return an error +// that the key doesn't exist. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation GetAccessKeyInfo for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetAccessKeyInfo +func (c *STS) GetAccessKeyInfo(input *GetAccessKeyInfoInput) (*GetAccessKeyInfoOutput, error) { + req, out := c.GetAccessKeyInfoRequest(input) + return out, req.Send() +} + +// GetAccessKeyInfoWithContext is the same as GetAccessKeyInfo with the addition of +// the ability to pass a context and additional request options. +// +// See GetAccessKeyInfo for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) GetAccessKeyInfoWithContext(ctx aws.Context, input *GetAccessKeyInfoInput, opts ...request.Option) (*GetAccessKeyInfoOutput, error) { + req, out := c.GetAccessKeyInfoRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetCallerIdentity = "GetCallerIdentity" + +// GetCallerIdentityRequest generates a "aws/request.Request" representing the +// client's request for the GetCallerIdentity operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetCallerIdentity for more information on using the GetCallerIdentity +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetCallerIdentityRequest method. +// req, resp := client.GetCallerIdentityRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity +func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *request.Request, output *GetCallerIdentityOutput) { + op := &request.Operation{ + Name: opGetCallerIdentity, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetCallerIdentityInput{} + } + + output = &GetCallerIdentityOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetCallerIdentity API operation for AWS Security Token Service. +// +// Returns details about the IAM user or role whose credentials are used to +// call the operation. +// +// No permissions are required to perform this operation. If an administrator +// adds a policy to your IAM user or role that explicitly denies access to the +// sts:GetCallerIdentity action, you can still perform this operation. Permissions +// are not required because the same information is returned when an IAM user +// or role is denied access. To view an example response, see I Am Not Authorized +// to Perform: iam:DeleteVirtualMFADevice (https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_access-denied-delete-mfa). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation GetCallerIdentity for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity +func (c *STS) GetCallerIdentity(input *GetCallerIdentityInput) (*GetCallerIdentityOutput, error) { + req, out := c.GetCallerIdentityRequest(input) + return out, req.Send() +} + +// GetCallerIdentityWithContext is the same as GetCallerIdentity with the addition of +// the ability to pass a context and additional request options. +// +// See GetCallerIdentity for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) GetCallerIdentityWithContext(ctx aws.Context, input *GetCallerIdentityInput, opts ...request.Option) (*GetCallerIdentityOutput, error) { + req, out := c.GetCallerIdentityRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetFederationToken = "GetFederationToken" + +// GetFederationTokenRequest generates a "aws/request.Request" representing the +// client's request for the GetFederationToken operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetFederationToken for more information on using the GetFederationToken +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetFederationTokenRequest method. +// req, resp := client.GetFederationTokenRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken +func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) { + op := &request.Operation{ + Name: opGetFederationToken, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetFederationTokenInput{} + } + + output = &GetFederationTokenOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetFederationToken API operation for AWS Security Token Service. +// +// Returns a set of temporary security credentials (consisting of an access +// key ID, a secret access key, and a security token) for a federated user. +// A typical use is in a proxy application that gets temporary security credentials +// on behalf of distributed applications inside a corporate network. You must +// call the GetFederationToken operation using the long-term security credentials +// of an IAM user. As a result, this call is appropriate in contexts where those +// credentials can be safely stored, usually in a server-based application. +// For a comparison of GetFederationToken with the other API operations that +// produce temporary credentials, see Requesting Temporary Security Credentials +// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// You can create a mobile-based or browser-based app that can authenticate +// users using a web identity provider like Login with Amazon, Facebook, Google, +// or an OpenID Connect-compatible identity provider. In this case, we recommend +// that you use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity. +// For more information, see Federation Through a Web-based Identity Provider +// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). +// +// You can also call GetFederationToken using the security credentials of an +// AWS account root user, but we do not recommend it. Instead, we recommend +// that you create an IAM user for the purpose of the proxy application. Then +// attach a policy to the IAM user that limits federated users to only the actions +// and resources that they need to access. For more information, see IAM Best +// Practices (https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) +// in the IAM User Guide. +// +// The temporary credentials are valid for the specified duration, from 900 +// seconds (15 minutes) up to a maximum of 129,600 seconds (36 hours). The default +// is 43,200 seconds (12 hours). Temporary credentials that are obtained by +// using AWS account root user credentials have a maximum duration of 3,600 +// seconds (1 hour). +// +// The temporary security credentials created by GetFederationToken can be used +// to make API calls to any AWS service with the following exceptions: +// +// * You cannot use these credentials to call any IAM API operations. +// +// * You cannot call any STS API operations except GetCallerIdentity. +// +// Permissions +// +// You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// to this operation. You can pass a single JSON policy document to use as an +// inline session policy. You can also specify up to 10 managed policies to +// use as managed session policies. The plain text that you use for both inline +// and managed session policies shouldn't exceed 2048 characters. +// +// Though the session policy parameters are optional, if you do not pass a policy, +// then the resulting federated user session has no permissions. The only exception +// is when the credentials are used to access a resource that has a resource-based +// policy that specifically references the federated user session in the Principal +// element of the policy. When you pass session policies, the session permissions +// are the intersection of the IAM user policies and the session policies that +// you pass. This gives you a way to further restrict the permissions for a +// federated user. You cannot use session policies to grant more permissions +// than those that are defined in the permissions policy of the IAM user. For +// more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// in the IAM User Guide. For information about using GetFederationToken to +// create temporary security credentials, see GetFederationToken—Federation +// Through a Custom Identity Broker (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation GetFederationToken for usage and error information. +// +// Returned Error Codes: +// * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument" +// The request was rejected because the policy document was malformed. The error +// message describes the specific error. +// +// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" +// The request was rejected because the policy document was too large. The error +// message describes how big the policy document is, in packed form, as a percentage +// of what the API allows. +// +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken +func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) { + req, out := c.GetFederationTokenRequest(input) + return out, req.Send() +} + +// GetFederationTokenWithContext is the same as GetFederationToken with the addition of +// the ability to pass a context and additional request options. +// +// See GetFederationToken for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) GetFederationTokenWithContext(ctx aws.Context, input *GetFederationTokenInput, opts ...request.Option) (*GetFederationTokenOutput, error) { + req, out := c.GetFederationTokenRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetSessionToken = "GetSessionToken" + +// GetSessionTokenRequest generates a "aws/request.Request" representing the +// client's request for the GetSessionToken operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetSessionToken for more information on using the GetSessionToken +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetSessionTokenRequest method. +// req, resp := client.GetSessionTokenRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken +func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) { + op := &request.Operation{ + Name: opGetSessionToken, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetSessionTokenInput{} + } + + output = &GetSessionTokenOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetSessionToken API operation for AWS Security Token Service. +// +// Returns a set of temporary credentials for an AWS account or IAM user. The +// credentials consist of an access key ID, a secret access key, and a security +// token. Typically, you use GetSessionToken if you want to use MFA to protect +// programmatic calls to specific AWS API operations like Amazon EC2 StopInstances. +// MFA-enabled IAM users would need to call GetSessionToken and submit an MFA +// code that is associated with their MFA device. Using the temporary security +// credentials that are returned from the call, IAM users can then make programmatic +// calls to API operations that require MFA authentication. If you do not supply +// a correct MFA code, then the API returns an access denied error. For a comparison +// of GetSessionToken with the other API operations that produce temporary credentials, +// see Requesting Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The GetSessionToken operation must be called by using the long-term AWS security +// credentials of the AWS account root user or an IAM user. Credentials that +// are created by IAM users are valid for the duration that you specify. This +// duration can range from 900 seconds (15 minutes) up to a maximum of 129,600 +// seconds (36 hours), with a default of 43,200 seconds (12 hours). Credentials +// based on account credentials can range from 900 seconds (15 minutes) up to +// 3,600 seconds (1 hour), with a default of 1 hour. +// +// The temporary security credentials created by GetSessionToken can be used +// to make API calls to any AWS service with the following exceptions: +// +// * You cannot call any IAM API operations unless MFA authentication information +// is included in the request. +// +// * You cannot call any STS API except AssumeRole or GetCallerIdentity. +// +// We recommend that you do not call GetSessionToken with AWS account root user +// credentials. Instead, follow our best practices (https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users) +// by creating one or more IAM users, giving them the necessary permissions, +// and using IAM users for everyday interaction with AWS. +// +// The credentials that are returned by GetSessionToken are based on permissions +// associated with the user whose credentials were used to call the operation. +// If GetSessionToken is called using AWS account root user credentials, the +// temporary credentials have root user permissions. Similarly, if GetSessionToken +// is called using the credentials of an IAM user, the temporary credentials +// have the same permissions as the IAM user. +// +// For more information about using GetSessionToken to create temporary credentials, +// go to Temporary Credentials for Users in Untrusted Environments (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken) +// in the IAM User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation GetSessionToken for usage and error information. +// +// Returned Error Codes: +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken +func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) { + req, out := c.GetSessionTokenRequest(input) + return out, req.Send() +} + +// GetSessionTokenWithContext is the same as GetSessionToken with the addition of +// the ability to pass a context and additional request options. +// +// See GetSessionToken for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) GetSessionTokenWithContext(ctx aws.Context, input *GetSessionTokenInput, opts ...request.Option) (*GetSessionTokenOutput, error) { + req, out := c.GetSessionTokenRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +type AssumeRoleInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) up to the maximum session duration setting for the role. + // This setting can have a value from 1 hour to 12 hours. If you specify a value + // higher than this setting, the operation fails. For example, if you specify + // a session duration of 12 hours, but your administrator set the maximum session + // duration to 6 hours, your operation fails. To learn how to view the maximum + // value for your role, see View the Maximum Session Duration Setting for a + // Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter is separate from the duration of a console + // session that you might request using the returned credentials. The request + // to the federation endpoint for a console sign-in token takes a SessionDuration + // parameter that specifies the maximum length of the console session. For more + // information, see Creating a URL that Enables Federated Users to Access the + // AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // A unique identifier that might be required when you assume a role in another + // account. If the administrator of the account to which the role belongs provided + // you with an external ID, then provide that value in the ExternalId parameter. + // This value can be any string, such as a passphrase or account number. A cross-account + // role is usually set up to trust everyone in an account. Therefore, the administrator + // of the trusting account might send an external ID to the administrator of + // the trusted account. That way, only someone with the ID can assume the role, + // rather than everyone in the account. For more information about the external + // ID, see How to Use an External ID When Granting Access to Your AWS Resources + // to a Third Party (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) + // in the IAM User Guide. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@:/- + ExternalId *string `min:"2" type:"string"` + + // An IAM policy in JSON format that you want to use as an inline session policy. + // + // This parameter is optional. Passing policies to this operation returns new + // temporary credentials. The resulting session's permissions are the intersection + // of the role's identity-based policy and the session policies. You can use + // the role's temporary credentials in subsequent AWS API calls to access resources + // in the account that owns the role. You cannot use session policies to grant + // more permissions than those allowed by the identity-based policy of the role + // that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The plain text that you use for both inline and managed session policies + // shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII + // character from the space character to the end of the valid character list + // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Names (ARNs) of the IAM managed policies that you want + // to use as managed session policies. The policies must exist in the same account + // as the role. + // + // This parameter is optional. You can provide up to 10 managed policy ARNs. + // However, the plain text that you use for both inline and managed session + // policies shouldn't exceed 2048 characters. For more information about ARNs, + // see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + // + // Passing policies to this operation returns new temporary credentials. The + // resulting session's permissions are the intersection of the role's identity-based + // policy and the session policies. You can use the role's temporary credentials + // in subsequent AWS API calls to access resources in the account that owns + // the role. You cannot use session policies to grant more permissions than + // those allowed by the identity-based policy of the role that is being assumed. + // For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + PolicyArns []*PolicyDescriptorType `type:"list"` + + // The Amazon Resource Name (ARN) of the role to assume. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // An identifier for the assumed role session. + // + // Use the role session name to uniquely identify a session when the same role + // is assumed by different principals or for different reasons. In cross-account + // scenarios, the role session name is visible to, and can be logged by the + // account that owns the role. The role session name is also used in the ARN + // of the assumed role principal. This means that subsequent cross-account API + // requests that use the temporary security credentials will expose the role + // session name to the external account in their AWS CloudTrail logs. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // RoleSessionName is a required field + RoleSessionName *string `min:"2" type:"string" required:"true"` + + // The identification number of the MFA device that is associated with the user + // who is making the AssumeRole call. Specify this value if the trust policy + // of the role being assumed includes a condition that requires MFA authentication. + // The value is either the serial number for a hardware device (such as GAHT12345678) + // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + SerialNumber *string `min:"9" type:"string"` + + // The value provided by the MFA device, if the trust policy of the role being + // assumed requires MFA (that is, if the policy includes a condition that tests + // for MFA). If the role being assumed requires MFA and if the TokenCode value + // is missing or expired, the AssumeRole call returns an "access denied" error. + // + // The format for this parameter, as described by its regex pattern, is a sequence + // of six numeric digits. + TokenCode *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s AssumeRoleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.ExternalId != nil && len(*s.ExternalId) < 2 { + invalidParams.Add(request.NewErrParamMinLen("ExternalId", 2)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.RoleSessionName == nil { + invalidParams.Add(request.NewErrParamRequired("RoleSessionName")) + } + if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2)) + } + if s.SerialNumber != nil && len(*s.SerialNumber) < 9 { + invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9)) + } + if s.TokenCode != nil && len(*s.TokenCode) < 6 { + invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6)) + } + if s.PolicyArns != nil { + for i, v := range s.PolicyArns { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *AssumeRoleInput) SetDurationSeconds(v int64) *AssumeRoleInput { + s.DurationSeconds = &v + return s +} + +// SetExternalId sets the ExternalId field's value. +func (s *AssumeRoleInput) SetExternalId(v string) *AssumeRoleInput { + s.ExternalId = &v + return s +} + +// SetPolicy sets the Policy field's value. +func (s *AssumeRoleInput) SetPolicy(v string) *AssumeRoleInput { + s.Policy = &v + return s +} + +// SetPolicyArns sets the PolicyArns field's value. +func (s *AssumeRoleInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleInput { + s.PolicyArns = v + return s +} + +// SetRoleArn sets the RoleArn field's value. +func (s *AssumeRoleInput) SetRoleArn(v string) *AssumeRoleInput { + s.RoleArn = &v + return s +} + +// SetRoleSessionName sets the RoleSessionName field's value. +func (s *AssumeRoleInput) SetRoleSessionName(v string) *AssumeRoleInput { + s.RoleSessionName = &v + return s +} + +// SetSerialNumber sets the SerialNumber field's value. +func (s *AssumeRoleInput) SetSerialNumber(v string) *AssumeRoleInput { + s.SerialNumber = &v + return s +} + +// SetTokenCode sets the TokenCode field's value. +func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput { + s.TokenCode = &v + return s +} + +// Contains the response to a successful AssumeRole request, including temporary +// AWS credentials that can be used to make AWS requests. +type AssumeRoleOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers + // that you can use to refer to the resulting temporary security credentials. + // For example, you can reference these credentials as a principal in a resource-based + // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName + // that you specified when you called AssumeRole. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` +} + +// String returns the string representation +func (s AssumeRoleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleOutput) GoString() string { + return s.String() +} + +// SetAssumedRoleUser sets the AssumedRoleUser field's value. +func (s *AssumeRoleOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleOutput { + s.AssumedRoleUser = v + return s +} + +// SetCredentials sets the Credentials field's value. +func (s *AssumeRoleOutput) SetCredentials(v *Credentials) *AssumeRoleOutput { + s.Credentials = v + return s +} + +// SetPackedPolicySize sets the PackedPolicySize field's value. +func (s *AssumeRoleOutput) SetPackedPolicySize(v int64) *AssumeRoleOutput { + s.PackedPolicySize = &v + return s +} + +type AssumeRoleWithSAMLInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. Your role session lasts for + // the duration that you specify for the DurationSeconds parameter, or until + // the time specified in the SAML authentication response's SessionNotOnOrAfter + // value, whichever is shorter. You can provide a DurationSeconds value from + // 900 seconds (15 minutes) up to the maximum session duration setting for the + // role. This setting can have a value from 1 hour to 12 hours. If you specify + // a value higher than this setting, the operation fails. For example, if you + // specify a session duration of 12 hours, but your administrator set the maximum + // session duration to 6 hours, your operation fails. To learn how to view the + // maximum value for your role, see View the Maximum Session Duration Setting + // for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter is separate from the duration of a console + // session that you might request using the returned credentials. The request + // to the federation endpoint for a console sign-in token takes a SessionDuration + // parameter that specifies the maximum length of the console session. For more + // information, see Creating a URL that Enables Federated Users to Access the + // AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // An IAM policy in JSON format that you want to use as an inline session policy. + // + // This parameter is optional. Passing policies to this operation returns new + // temporary credentials. The resulting session's permissions are the intersection + // of the role's identity-based policy and the session policies. You can use + // the role's temporary credentials in subsequent AWS API calls to access resources + // in the account that owns the role. You cannot use session policies to grant + // more permissions than those allowed by the identity-based policy of the role + // that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The plain text that you use for both inline and managed session policies + // shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII + // character from the space character to the end of the valid character list + // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Names (ARNs) of the IAM managed policies that you want + // to use as managed session policies. The policies must exist in the same account + // as the role. + // + // This parameter is optional. You can provide up to 10 managed policy ARNs. + // However, the plain text that you use for both inline and managed session + // policies shouldn't exceed 2048 characters. For more information about ARNs, + // see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + // + // Passing policies to this operation returns new temporary credentials. The + // resulting session's permissions are the intersection of the role's identity-based + // policy and the session policies. You can use the role's temporary credentials + // in subsequent AWS API calls to access resources in the account that owns + // the role. You cannot use session policies to grant more permissions than + // those allowed by the identity-based policy of the role that is being assumed. + // For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + PolicyArns []*PolicyDescriptorType `type:"list"` + + // The Amazon Resource Name (ARN) of the SAML provider in IAM that describes + // the IdP. + // + // PrincipalArn is a required field + PrincipalArn *string `min:"20" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the role that the caller is assuming. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // The base-64 encoded SAML authentication response provided by the IdP. + // + // For more information, see Configuring a Relying Party and Adding Claims (https://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html) + // in the IAM User Guide. + // + // SAMLAssertion is a required field + SAMLAssertion *string `min:"4" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumeRoleWithSAMLInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithSAMLInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleWithSAMLInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithSAMLInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.PrincipalArn == nil { + invalidParams.Add(request.NewErrParamRequired("PrincipalArn")) + } + if s.PrincipalArn != nil && len(*s.PrincipalArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("PrincipalArn", 20)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.SAMLAssertion == nil { + invalidParams.Add(request.NewErrParamRequired("SAMLAssertion")) + } + if s.SAMLAssertion != nil && len(*s.SAMLAssertion) < 4 { + invalidParams.Add(request.NewErrParamMinLen("SAMLAssertion", 4)) + } + if s.PolicyArns != nil { + for i, v := range s.PolicyArns { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *AssumeRoleWithSAMLInput) SetDurationSeconds(v int64) *AssumeRoleWithSAMLInput { + s.DurationSeconds = &v + return s +} + +// SetPolicy sets the Policy field's value. +func (s *AssumeRoleWithSAMLInput) SetPolicy(v string) *AssumeRoleWithSAMLInput { + s.Policy = &v + return s +} + +// SetPolicyArns sets the PolicyArns field's value. +func (s *AssumeRoleWithSAMLInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleWithSAMLInput { + s.PolicyArns = v + return s +} + +// SetPrincipalArn sets the PrincipalArn field's value. +func (s *AssumeRoleWithSAMLInput) SetPrincipalArn(v string) *AssumeRoleWithSAMLInput { + s.PrincipalArn = &v + return s +} + +// SetRoleArn sets the RoleArn field's value. +func (s *AssumeRoleWithSAMLInput) SetRoleArn(v string) *AssumeRoleWithSAMLInput { + s.RoleArn = &v + return s +} + +// SetSAMLAssertion sets the SAMLAssertion field's value. +func (s *AssumeRoleWithSAMLInput) SetSAMLAssertion(v string) *AssumeRoleWithSAMLInput { + s.SAMLAssertion = &v + return s +} + +// Contains the response to a successful AssumeRoleWithSAML request, including +// temporary AWS credentials that can be used to make AWS requests. +type AssumeRoleWithSAMLOutput struct { + _ struct{} `type:"structure"` + + // The identifiers for the temporary security credentials that the operation + // returns. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The value of the Recipient attribute of the SubjectConfirmationData element + // of the SAML assertion. + Audience *string `type:"string"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` + + // The value of the Issuer element of the SAML assertion. + Issuer *string `type:"string"` + + // A hash value based on the concatenation of the Issuer response value, the + // AWS account ID, and the friendly name (the last part of the ARN) of the SAML + // provider in IAM. The combination of NameQualifier and Subject can be used + // to uniquely identify a federated user. + // + // The following pseudocode shows how the hash value is calculated: + // + // BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP" + // ) ) + NameQualifier *string `type:"string"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` + + // The value of the NameID element in the Subject element of the SAML assertion. + Subject *string `type:"string"` + + // The format of the name ID, as defined by the Format attribute in the NameID + // element of the SAML assertion. Typical examples of the format are transient + // or persistent. + // + // If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format, + // that prefix is removed. For example, urn:oasis:names:tc:SAML:2.0:nameid-format:transient + // is returned as transient. If the format includes any other prefix, the format + // is returned with no modifications. + SubjectType *string `type:"string"` +} + +// String returns the string representation +func (s AssumeRoleWithSAMLOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithSAMLOutput) GoString() string { + return s.String() +} + +// SetAssumedRoleUser sets the AssumedRoleUser field's value. +func (s *AssumeRoleWithSAMLOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleWithSAMLOutput { + s.AssumedRoleUser = v + return s +} + +// SetAudience sets the Audience field's value. +func (s *AssumeRoleWithSAMLOutput) SetAudience(v string) *AssumeRoleWithSAMLOutput { + s.Audience = &v + return s +} + +// SetCredentials sets the Credentials field's value. +func (s *AssumeRoleWithSAMLOutput) SetCredentials(v *Credentials) *AssumeRoleWithSAMLOutput { + s.Credentials = v + return s +} + +// SetIssuer sets the Issuer field's value. +func (s *AssumeRoleWithSAMLOutput) SetIssuer(v string) *AssumeRoleWithSAMLOutput { + s.Issuer = &v + return s +} + +// SetNameQualifier sets the NameQualifier field's value. +func (s *AssumeRoleWithSAMLOutput) SetNameQualifier(v string) *AssumeRoleWithSAMLOutput { + s.NameQualifier = &v + return s +} + +// SetPackedPolicySize sets the PackedPolicySize field's value. +func (s *AssumeRoleWithSAMLOutput) SetPackedPolicySize(v int64) *AssumeRoleWithSAMLOutput { + s.PackedPolicySize = &v + return s +} + +// SetSubject sets the Subject field's value. +func (s *AssumeRoleWithSAMLOutput) SetSubject(v string) *AssumeRoleWithSAMLOutput { + s.Subject = &v + return s +} + +// SetSubjectType sets the SubjectType field's value. +func (s *AssumeRoleWithSAMLOutput) SetSubjectType(v string) *AssumeRoleWithSAMLOutput { + s.SubjectType = &v + return s +} + +type AssumeRoleWithWebIdentityInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) up to the maximum session duration setting for the role. + // This setting can have a value from 1 hour to 12 hours. If you specify a value + // higher than this setting, the operation fails. For example, if you specify + // a session duration of 12 hours, but your administrator set the maximum session + // duration to 6 hours, your operation fails. To learn how to view the maximum + // value for your role, see View the Maximum Session Duration Setting for a + // Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter is separate from the duration of a console + // session that you might request using the returned credentials. The request + // to the federation endpoint for a console sign-in token takes a SessionDuration + // parameter that specifies the maximum length of the console session. For more + // information, see Creating a URL that Enables Federated Users to Access the + // AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // An IAM policy in JSON format that you want to use as an inline session policy. + // + // This parameter is optional. Passing policies to this operation returns new + // temporary credentials. The resulting session's permissions are the intersection + // of the role's identity-based policy and the session policies. You can use + // the role's temporary credentials in subsequent AWS API calls to access resources + // in the account that owns the role. You cannot use session policies to grant + // more permissions than those allowed by the identity-based policy of the role + // that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The plain text that you use for both inline and managed session policies + // shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII + // character from the space character to the end of the valid character list + // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Names (ARNs) of the IAM managed policies that you want + // to use as managed session policies. The policies must exist in the same account + // as the role. + // + // This parameter is optional. You can provide up to 10 managed policy ARNs. + // However, the plain text that you use for both inline and managed session + // policies shouldn't exceed 2048 characters. For more information about ARNs, + // see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + // + // Passing policies to this operation returns new temporary credentials. The + // resulting session's permissions are the intersection of the role's identity-based + // policy and the session policies. You can use the role's temporary credentials + // in subsequent AWS API calls to access resources in the account that owns + // the role. You cannot use session policies to grant more permissions than + // those allowed by the identity-based policy of the role that is being assumed. + // For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + PolicyArns []*PolicyDescriptorType `type:"list"` + + // The fully qualified host component of the domain name of the identity provider. + // + // Specify this value only for OAuth 2.0 access tokens. Currently www.amazon.com + // and graph.facebook.com are the only supported identity providers for OAuth + // 2.0 access tokens. Do not include URL schemes and port numbers. + // + // Do not specify this value for OpenID Connect ID tokens. + ProviderId *string `min:"4" type:"string"` + + // The Amazon Resource Name (ARN) of the role that the caller is assuming. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // An identifier for the assumed role session. Typically, you pass the name + // or identifier that is associated with the user who is using your application. + // That way, the temporary security credentials that your application will use + // are associated with that user. This session name is included as part of the + // ARN and assumed role ID in the AssumedRoleUser response element. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // RoleSessionName is a required field + RoleSessionName *string `min:"2" type:"string" required:"true"` + + // The OAuth 2.0 access token or OpenID Connect ID token that is provided by + // the identity provider. Your application must get this token by authenticating + // the user who is using your application with a web identity provider before + // the application makes an AssumeRoleWithWebIdentity call. + // + // WebIdentityToken is a required field + WebIdentityToken *string `min:"4" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumeRoleWithWebIdentityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithWebIdentityInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleWithWebIdentityInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithWebIdentityInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.ProviderId != nil && len(*s.ProviderId) < 4 { + invalidParams.Add(request.NewErrParamMinLen("ProviderId", 4)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.RoleSessionName == nil { + invalidParams.Add(request.NewErrParamRequired("RoleSessionName")) + } + if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2)) + } + if s.WebIdentityToken == nil { + invalidParams.Add(request.NewErrParamRequired("WebIdentityToken")) + } + if s.WebIdentityToken != nil && len(*s.WebIdentityToken) < 4 { + invalidParams.Add(request.NewErrParamMinLen("WebIdentityToken", 4)) + } + if s.PolicyArns != nil { + for i, v := range s.PolicyArns { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *AssumeRoleWithWebIdentityInput) SetDurationSeconds(v int64) *AssumeRoleWithWebIdentityInput { + s.DurationSeconds = &v + return s +} + +// SetPolicy sets the Policy field's value. +func (s *AssumeRoleWithWebIdentityInput) SetPolicy(v string) *AssumeRoleWithWebIdentityInput { + s.Policy = &v + return s +} + +// SetPolicyArns sets the PolicyArns field's value. +func (s *AssumeRoleWithWebIdentityInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleWithWebIdentityInput { + s.PolicyArns = v + return s +} + +// SetProviderId sets the ProviderId field's value. +func (s *AssumeRoleWithWebIdentityInput) SetProviderId(v string) *AssumeRoleWithWebIdentityInput { + s.ProviderId = &v + return s +} + +// SetRoleArn sets the RoleArn field's value. +func (s *AssumeRoleWithWebIdentityInput) SetRoleArn(v string) *AssumeRoleWithWebIdentityInput { + s.RoleArn = &v + return s +} + +// SetRoleSessionName sets the RoleSessionName field's value. +func (s *AssumeRoleWithWebIdentityInput) SetRoleSessionName(v string) *AssumeRoleWithWebIdentityInput { + s.RoleSessionName = &v + return s +} + +// SetWebIdentityToken sets the WebIdentityToken field's value. +func (s *AssumeRoleWithWebIdentityInput) SetWebIdentityToken(v string) *AssumeRoleWithWebIdentityInput { + s.WebIdentityToken = &v + return s +} + +// Contains the response to a successful AssumeRoleWithWebIdentity request, +// including temporary AWS credentials that can be used to make AWS requests. +type AssumeRoleWithWebIdentityOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers + // that you can use to refer to the resulting temporary security credentials. + // For example, you can reference these credentials as a principal in a resource-based + // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName + // that you specified when you called AssumeRole. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The intended audience (also known as client ID) of the web identity token. + // This is traditionally the client identifier issued to the application that + // requested the web identity token. + Audience *string `type:"string"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` + + // The issuing authority of the web identity token presented. For OpenID Connect + // ID tokens, this contains the value of the iss field. For OAuth 2.0 access + // tokens, this contains the value of the ProviderId parameter that was passed + // in the AssumeRoleWithWebIdentity request. + Provider *string `type:"string"` + + // The unique user identifier that is returned by the identity provider. This + // identifier is associated with the WebIdentityToken that was submitted with + // the AssumeRoleWithWebIdentity call. The identifier is typically unique to + // the user and the application that acquired the WebIdentityToken (pairwise + // identifier). For OpenID Connect ID tokens, this field contains the value + // returned by the identity provider as the token's sub (Subject) claim. + SubjectFromWebIdentityToken *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s AssumeRoleWithWebIdentityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithWebIdentityOutput) GoString() string { + return s.String() +} + +// SetAssumedRoleUser sets the AssumedRoleUser field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleWithWebIdentityOutput { + s.AssumedRoleUser = v + return s +} + +// SetAudience sets the Audience field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetAudience(v string) *AssumeRoleWithWebIdentityOutput { + s.Audience = &v + return s +} + +// SetCredentials sets the Credentials field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetCredentials(v *Credentials) *AssumeRoleWithWebIdentityOutput { + s.Credentials = v + return s +} + +// SetPackedPolicySize sets the PackedPolicySize field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetPackedPolicySize(v int64) *AssumeRoleWithWebIdentityOutput { + s.PackedPolicySize = &v + return s +} + +// SetProvider sets the Provider field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetProvider(v string) *AssumeRoleWithWebIdentityOutput { + s.Provider = &v + return s +} + +// SetSubjectFromWebIdentityToken sets the SubjectFromWebIdentityToken field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetSubjectFromWebIdentityToken(v string) *AssumeRoleWithWebIdentityOutput { + s.SubjectFromWebIdentityToken = &v + return s +} + +// The identifiers for the temporary security credentials that the operation +// returns. +type AssumedRoleUser struct { + _ struct{} `type:"structure"` + + // The ARN of the temporary security credentials that are returned from the + // AssumeRole action. For more information about ARNs and how to use them in + // policies, see IAM Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) + // in Using IAM. + // + // Arn is a required field + Arn *string `min:"20" type:"string" required:"true"` + + // A unique identifier that contains the role ID and the role session name of + // the role that is being assumed. The role ID is generated by AWS when the + // role is created. + // + // AssumedRoleId is a required field + AssumedRoleId *string `min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumedRoleUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumedRoleUser) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *AssumedRoleUser) SetArn(v string) *AssumedRoleUser { + s.Arn = &v + return s +} + +// SetAssumedRoleId sets the AssumedRoleId field's value. +func (s *AssumedRoleUser) SetAssumedRoleId(v string) *AssumedRoleUser { + s.AssumedRoleId = &v + return s +} + +// AWS credentials for API authentication. +type Credentials struct { + _ struct{} `type:"structure"` + + // The access key ID that identifies the temporary security credentials. + // + // AccessKeyId is a required field + AccessKeyId *string `min:"16" type:"string" required:"true"` + + // The date on which the current credentials expire. + // + // Expiration is a required field + Expiration *time.Time `type:"timestamp" required:"true"` + + // The secret access key that can be used to sign requests. + // + // SecretAccessKey is a required field + SecretAccessKey *string `type:"string" required:"true"` + + // The token that users must pass to the service API to use the temporary credentials. + // + // SessionToken is a required field + SessionToken *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s Credentials) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Credentials) GoString() string { + return s.String() +} + +// SetAccessKeyId sets the AccessKeyId field's value. +func (s *Credentials) SetAccessKeyId(v string) *Credentials { + s.AccessKeyId = &v + return s +} + +// SetExpiration sets the Expiration field's value. +func (s *Credentials) SetExpiration(v time.Time) *Credentials { + s.Expiration = &v + return s +} + +// SetSecretAccessKey sets the SecretAccessKey field's value. +func (s *Credentials) SetSecretAccessKey(v string) *Credentials { + s.SecretAccessKey = &v + return s +} + +// SetSessionToken sets the SessionToken field's value. +func (s *Credentials) SetSessionToken(v string) *Credentials { + s.SessionToken = &v + return s +} + +type DecodeAuthorizationMessageInput struct { + _ struct{} `type:"structure"` + + // The encoded message that was returned with the response. + // + // EncodedMessage is a required field + EncodedMessage *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DecodeAuthorizationMessageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DecodeAuthorizationMessageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DecodeAuthorizationMessageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DecodeAuthorizationMessageInput"} + if s.EncodedMessage == nil { + invalidParams.Add(request.NewErrParamRequired("EncodedMessage")) + } + if s.EncodedMessage != nil && len(*s.EncodedMessage) < 1 { + invalidParams.Add(request.NewErrParamMinLen("EncodedMessage", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEncodedMessage sets the EncodedMessage field's value. +func (s *DecodeAuthorizationMessageInput) SetEncodedMessage(v string) *DecodeAuthorizationMessageInput { + s.EncodedMessage = &v + return s +} + +// A document that contains additional information about the authorization status +// of a request from an encoded message that is returned in response to an AWS +// request. +type DecodeAuthorizationMessageOutput struct { + _ struct{} `type:"structure"` + + // An XML document that contains the decoded message. + DecodedMessage *string `type:"string"` +} + +// String returns the string representation +func (s DecodeAuthorizationMessageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DecodeAuthorizationMessageOutput) GoString() string { + return s.String() +} + +// SetDecodedMessage sets the DecodedMessage field's value. +func (s *DecodeAuthorizationMessageOutput) SetDecodedMessage(v string) *DecodeAuthorizationMessageOutput { + s.DecodedMessage = &v + return s +} + +// Identifiers for the federated user that is associated with the credentials. +type FederatedUser struct { + _ struct{} `type:"structure"` + + // The ARN that specifies the federated user that is associated with the credentials. + // For more information about ARNs and how to use them in policies, see IAM + // Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) + // in Using IAM. + // + // Arn is a required field + Arn *string `min:"20" type:"string" required:"true"` + + // The string that identifies the federated user associated with the credentials, + // similar to the unique ID of an IAM user. + // + // FederatedUserId is a required field + FederatedUserId *string `min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s FederatedUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FederatedUser) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *FederatedUser) SetArn(v string) *FederatedUser { + s.Arn = &v + return s +} + +// SetFederatedUserId sets the FederatedUserId field's value. +func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser { + s.FederatedUserId = &v + return s +} + +type GetAccessKeyInfoInput struct { + _ struct{} `type:"structure"` + + // The identifier of an access key. + // + // This parameter allows (through its regex pattern) a string of characters + // that can consist of any upper- or lowercased letter or digit. + // + // AccessKeyId is a required field + AccessKeyId *string `min:"16" type:"string" required:"true"` +} + +// String returns the string representation +func (s GetAccessKeyInfoInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetAccessKeyInfoInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetAccessKeyInfoInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetAccessKeyInfoInput"} + if s.AccessKeyId == nil { + invalidParams.Add(request.NewErrParamRequired("AccessKeyId")) + } + if s.AccessKeyId != nil && len(*s.AccessKeyId) < 16 { + invalidParams.Add(request.NewErrParamMinLen("AccessKeyId", 16)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAccessKeyId sets the AccessKeyId field's value. +func (s *GetAccessKeyInfoInput) SetAccessKeyId(v string) *GetAccessKeyInfoInput { + s.AccessKeyId = &v + return s +} + +type GetAccessKeyInfoOutput struct { + _ struct{} `type:"structure"` + + // The number used to identify the AWS account. + Account *string `type:"string"` +} + +// String returns the string representation +func (s GetAccessKeyInfoOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetAccessKeyInfoOutput) GoString() string { + return s.String() +} + +// SetAccount sets the Account field's value. +func (s *GetAccessKeyInfoOutput) SetAccount(v string) *GetAccessKeyInfoOutput { + s.Account = &v + return s +} + +type GetCallerIdentityInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetCallerIdentityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCallerIdentityInput) GoString() string { + return s.String() +} + +// Contains the response to a successful GetCallerIdentity request, including +// information about the entity making the request. +type GetCallerIdentityOutput struct { + _ struct{} `type:"structure"` + + // The AWS account ID number of the account that owns or contains the calling + // entity. + Account *string `type:"string"` + + // The AWS ARN associated with the calling entity. + Arn *string `min:"20" type:"string"` + + // The unique identifier of the calling entity. The exact value depends on the + // type of entity that is making the call. The values returned are those listed + // in the aws:userid column in the Principal table (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable) + // found on the Policy Variables reference page in the IAM User Guide. + UserId *string `type:"string"` +} + +// String returns the string representation +func (s GetCallerIdentityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCallerIdentityOutput) GoString() string { + return s.String() +} + +// SetAccount sets the Account field's value. +func (s *GetCallerIdentityOutput) SetAccount(v string) *GetCallerIdentityOutput { + s.Account = &v + return s +} + +// SetArn sets the Arn field's value. +func (s *GetCallerIdentityOutput) SetArn(v string) *GetCallerIdentityOutput { + s.Arn = &v + return s +} + +// SetUserId sets the UserId field's value. +func (s *GetCallerIdentityOutput) SetUserId(v string) *GetCallerIdentityOutput { + s.UserId = &v + return s +} + +type GetFederationTokenInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, that the session should last. Acceptable durations + // for federation sessions range from 900 seconds (15 minutes) to 129,600 seconds + // (36 hours), with 43,200 seconds (12 hours) as the default. Sessions obtained + // using AWS account root user credentials are restricted to a maximum of 3,600 + // seconds (one hour). If the specified duration is longer than one hour, the + // session obtained by using root user credentials defaults to one hour. + DurationSeconds *int64 `min:"900" type:"integer"` + + // The name of the federated user. The name is used as an identifier for the + // temporary security credentials (such as Bob). For example, you can reference + // the federated user name in a resource-based policy, such as in an Amazon + // S3 bucket policy. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // Name is a required field + Name *string `min:"2" type:"string" required:"true"` + + // An IAM policy in JSON format that you want to use as an inline session policy. + // + // You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // to this operation. You can pass a single JSON policy document to use as an + // inline session policy. You can also specify up to 10 managed policies to + // use as managed session policies. + // + // This parameter is optional. However, if you do not pass any session policies, + // then the resulting federated user session has no permissions. The only exception + // is when the credentials are used to access a resource that has a resource-based + // policy that specifically references the federated user session in the Principal + // element of the policy. + // + // When you pass session policies, the session permissions are the intersection + // of the IAM user policies and the session policies that you pass. This gives + // you a way to further restrict the permissions for a federated user. You cannot + // use session policies to grant more permissions than those that are defined + // in the permissions policy of the IAM user. For more information, see Session + // Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The plain text that you use for both inline and managed session policies + // shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII + // character from the space character to the end of the valid character list + // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Names (ARNs) of the IAM managed policies that you want + // to use as a managed session policy. The policies must exist in the same account + // as the IAM user that is requesting federated access. + // + // You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // to this operation. You can pass a single JSON policy document to use as an + // inline session policy. You can also specify up to 10 managed policies to + // use as managed session policies. The plain text that you use for both inline + // and managed session policies shouldn't exceed 2048 characters. You can provide + // up to 10 managed policy ARNs. For more information about ARNs, see Amazon + // Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + // + // This parameter is optional. However, if you do not pass any session policies, + // then the resulting federated user session has no permissions. The only exception + // is when the credentials are used to access a resource that has a resource-based + // policy that specifically references the federated user session in the Principal + // element of the policy. + // + // When you pass session policies, the session permissions are the intersection + // of the IAM user policies and the session policies that you pass. This gives + // you a way to further restrict the permissions for a federated user. You cannot + // use session policies to grant more permissions than those that are defined + // in the permissions policy of the IAM user. For more information, see Session + // Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + PolicyArns []*PolicyDescriptorType `type:"list"` +} + +// String returns the string representation +func (s GetFederationTokenInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetFederationTokenInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetFederationTokenInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetFederationTokenInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 2 { + invalidParams.Add(request.NewErrParamMinLen("Name", 2)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.PolicyArns != nil { + for i, v := range s.PolicyArns { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *GetFederationTokenInput) SetDurationSeconds(v int64) *GetFederationTokenInput { + s.DurationSeconds = &v + return s +} + +// SetName sets the Name field's value. +func (s *GetFederationTokenInput) SetName(v string) *GetFederationTokenInput { + s.Name = &v + return s +} + +// SetPolicy sets the Policy field's value. +func (s *GetFederationTokenInput) SetPolicy(v string) *GetFederationTokenInput { + s.Policy = &v + return s +} + +// SetPolicyArns sets the PolicyArns field's value. +func (s *GetFederationTokenInput) SetPolicyArns(v []*PolicyDescriptorType) *GetFederationTokenInput { + s.PolicyArns = v + return s +} + +// Contains the response to a successful GetFederationToken request, including +// temporary AWS credentials that can be used to make AWS requests. +type GetFederationTokenOutput struct { + _ struct{} `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` + + // Identifiers for the federated user associated with the credentials (such + // as arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob). You + // can use the federated user's ARN in your resource-based policies, such as + // an Amazon S3 bucket policy. + FederatedUser *FederatedUser `type:"structure"` + + // A percentage value indicating the size of the policy in packed form. The + // service rejects policies for which the packed size is greater than 100 percent + // of the allowed value. + PackedPolicySize *int64 `type:"integer"` +} + +// String returns the string representation +func (s GetFederationTokenOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetFederationTokenOutput) GoString() string { + return s.String() +} + +// SetCredentials sets the Credentials field's value. +func (s *GetFederationTokenOutput) SetCredentials(v *Credentials) *GetFederationTokenOutput { + s.Credentials = v + return s +} + +// SetFederatedUser sets the FederatedUser field's value. +func (s *GetFederationTokenOutput) SetFederatedUser(v *FederatedUser) *GetFederationTokenOutput { + s.FederatedUser = v + return s +} + +// SetPackedPolicySize sets the PackedPolicySize field's value. +func (s *GetFederationTokenOutput) SetPackedPolicySize(v int64) *GetFederationTokenOutput { + s.PackedPolicySize = &v + return s +} + +type GetSessionTokenInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, that the credentials should remain valid. Acceptable + // durations for IAM user sessions range from 900 seconds (15 minutes) to 129,600 + // seconds (36 hours), with 43,200 seconds (12 hours) as the default. Sessions + // for AWS account owners are restricted to a maximum of 3,600 seconds (one + // hour). If the duration is longer than one hour, the session for AWS account + // owners defaults to one hour. + DurationSeconds *int64 `min:"900" type:"integer"` + + // The identification number of the MFA device that is associated with the IAM + // user who is making the GetSessionToken call. Specify this value if the IAM + // user has a policy that requires MFA authentication. The value is either the + // serial number for a hardware device (such as GAHT12345678) or an Amazon Resource + // Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + // You can find the device for an IAM user by going to the AWS Management Console + // and viewing the user's security credentials. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@:/- + SerialNumber *string `min:"9" type:"string"` + + // The value provided by the MFA device, if MFA is required. If any policy requires + // the IAM user to submit an MFA code, specify this value. If MFA authentication + // is required, the user must provide a code when requesting a set of temporary + // security credentials. A user who fails to provide the code receives an "access + // denied" response when requesting resources that require MFA authentication. + // + // The format for this parameter, as described by its regex pattern, is a sequence + // of six numeric digits. + TokenCode *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s GetSessionTokenInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSessionTokenInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetSessionTokenInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetSessionTokenInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.SerialNumber != nil && len(*s.SerialNumber) < 9 { + invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9)) + } + if s.TokenCode != nil && len(*s.TokenCode) < 6 { + invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *GetSessionTokenInput) SetDurationSeconds(v int64) *GetSessionTokenInput { + s.DurationSeconds = &v + return s +} + +// SetSerialNumber sets the SerialNumber field's value. +func (s *GetSessionTokenInput) SetSerialNumber(v string) *GetSessionTokenInput { + s.SerialNumber = &v + return s +} + +// SetTokenCode sets the TokenCode field's value. +func (s *GetSessionTokenInput) SetTokenCode(v string) *GetSessionTokenInput { + s.TokenCode = &v + return s +} + +// Contains the response to a successful GetSessionToken request, including +// temporary AWS credentials that can be used to make AWS requests. +type GetSessionTokenOutput struct { + _ struct{} `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` +} + +// String returns the string representation +func (s GetSessionTokenOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSessionTokenOutput) GoString() string { + return s.String() +} + +// SetCredentials sets the Credentials field's value. +func (s *GetSessionTokenOutput) SetCredentials(v *Credentials) *GetSessionTokenOutput { + s.Credentials = v + return s +} + +// A reference to the IAM managed policy that is passed as a session policy +// for a role session or a federated user session. +type PolicyDescriptorType struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the IAM managed policy to use as a session + // policy for the role. For more information about ARNs, see Amazon Resource + // Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + Arn *string `locationName:"arn" min:"20" type:"string"` +} + +// String returns the string representation +func (s PolicyDescriptorType) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PolicyDescriptorType) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PolicyDescriptorType) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PolicyDescriptorType"} + if s.Arn != nil && len(*s.Arn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("Arn", 20)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetArn sets the Arn field's value. +func (s *PolicyDescriptorType) SetArn(v string) *PolicyDescriptorType { + s.Arn = &v + return s +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go new file mode 100644 index 000000000..fcb720dca --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go @@ -0,0 +1,108 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package sts provides the client and types for making API +// requests to AWS Security Token Service. +// +// The AWS Security Token Service (STS) is a web service that enables you to +// request temporary, limited-privilege credentials for AWS Identity and Access +// Management (IAM) users or for users that you authenticate (federated users). +// This guide provides descriptions of the STS API. For more detailed information +// about using this service, go to Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html). +// +// For information about setting up signatures and authorization through the +// API, go to Signing AWS API Requests (https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) +// in the AWS General Reference. For general information about the Query API, +// go to Making Query Requests (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html) +// in Using IAM. For information about using security tokens with other AWS +// products, go to AWS Services That Work with IAM (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) +// in the IAM User Guide. +// +// If you're new to AWS and need additional technical information about a specific +// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/ +// (http://aws.amazon.com/documentation/). +// +// Endpoints +// +// By default, AWS Security Token Service (STS) is available as a global service, +// and all AWS STS requests go to a single endpoint at https://sts.amazonaws.com. +// Global requests map to the US East (N. Virginia) region. AWS recommends using +// Regional AWS STS endpoints instead of the global endpoint to reduce latency, +// build in redundancy, and increase session token validity. For more information, +// see Managing AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// Most AWS Regions are enabled for operations in all AWS services by default. +// Those Regions are automatically activated for use with AWS STS. Some Regions, +// such as Asia Pacific (Hong Kong), must be manually enabled. To learn more +// about enabling and disabling AWS Regions, see Managing AWS Regions (https://docs.aws.amazon.com/general/latest/gr/rande-manage.html) +// in the AWS General Reference. When you enable these AWS Regions, they are +// automatically activated for use with AWS STS. You cannot activate the STS +// endpoint for a Region that is disabled. Tokens that are valid in all AWS +// Regions are longer than tokens that are valid in Regions that are enabled +// by default. Changing this setting might affect existing systems where you +// temporarily store tokens. For more information, see Managing Global Endpoint +// Session Tokens (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-manage-tokens) +// in the IAM User Guide. +// +// After you activate a Region for use with AWS STS, you can direct AWS STS +// API calls to that Region. AWS STS recommends that you provide both the Region +// and endpoint when you make calls to a Regional endpoint. You can provide +// the Region alone for manually enabled Regions, such as Asia Pacific (Hong +// Kong). In this case, the calls are directed to the STS Regional endpoint. +// However, if you provide the Region alone for Regions enabled by default, +// the calls are directed to the global endpoint of https://sts.amazonaws.com. +// +// To view the list of AWS STS endpoints and whether they are active by default, +// see Writing Code to Use AWS STS Regions (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#id_credentials_temp_enable-regions_writing_code) +// in the IAM User Guide. +// +// Recording API requests +// +// STS supports AWS CloudTrail, which is a service that records AWS calls for +// your AWS account and delivers log files to an Amazon S3 bucket. By using +// information collected by CloudTrail, you can determine what requests were +// successfully made to STS, who made the request, when it was made, and so +// on. +// +// If you activate AWS STS endpoints in Regions other than the default global +// endpoint, then you must also turn on CloudTrail logging in those Regions. +// This is necessary to record any AWS STS API calls that are made in those +// Regions. For more information, see Turning On CloudTrail in Additional Regions +// (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/aggregating_logs_regions_turn_on_ct.html) +// in the AWS CloudTrail User Guide. +// +// AWS Security Token Service (STS) is a global service with a single endpoint +// at https://sts.amazonaws.com. Calls to this endpoint are logged as calls +// to a global service. However, because this endpoint is physically located +// in the US East (N. Virginia) Region, your logs list us-east-1 as the event +// Region. CloudTrail does not write these logs to the US East (Ohio) Region +// unless you choose to include global service logs in that Region. CloudTrail +// writes calls to all Regional endpoints to their respective Regions. For example, +// calls to sts.us-east-2.amazonaws.com are published to the US East (Ohio) +// Region and calls to sts.eu-central-1.amazonaws.com are published to the EU +// (Frankfurt) Region. +// +// To learn more about CloudTrail, including how to turn it on and find your +// log files, see the AWS CloudTrail User Guide (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html). +// +// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service. +// +// See sts package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/ +// +// Using the Client +// +// To contact AWS Security Token Service with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the AWS Security Token Service client STS for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#New +package sts diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go b/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go new file mode 100644 index 000000000..41ea09c35 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go @@ -0,0 +1,73 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +const ( + + // ErrCodeExpiredTokenException for service response error code + // "ExpiredTokenException". + // + // The web identity token that was passed is expired or is not valid. Get a + // new identity token from the identity provider and then retry the request. + ErrCodeExpiredTokenException = "ExpiredTokenException" + + // ErrCodeIDPCommunicationErrorException for service response error code + // "IDPCommunicationError". + // + // The request could not be fulfilled because the non-AWS identity provider + // (IDP) that was asked to verify the incoming identity token could not be reached. + // This is often a transient error caused by network conditions. Retry the request + // a limited number of times so that you don't exceed the request rate. If the + // error persists, the non-AWS identity provider might be down or not responding. + ErrCodeIDPCommunicationErrorException = "IDPCommunicationError" + + // ErrCodeIDPRejectedClaimException for service response error code + // "IDPRejectedClaim". + // + // The identity provider (IdP) reported that authentication failed. This might + // be because the claim is invalid. + // + // If this error is returned for the AssumeRoleWithWebIdentity operation, it + // can also mean that the claim has expired or has been explicitly revoked. + ErrCodeIDPRejectedClaimException = "IDPRejectedClaim" + + // ErrCodeInvalidAuthorizationMessageException for service response error code + // "InvalidAuthorizationMessageException". + // + // The error returned if the message passed to DecodeAuthorizationMessage was + // invalid. This can happen if the token contains invalid characters, such as + // linebreaks. + ErrCodeInvalidAuthorizationMessageException = "InvalidAuthorizationMessageException" + + // ErrCodeInvalidIdentityTokenException for service response error code + // "InvalidIdentityToken". + // + // The web identity token that was passed could not be validated by AWS. Get + // a new identity token from the identity provider and then retry the request. + ErrCodeInvalidIdentityTokenException = "InvalidIdentityToken" + + // ErrCodeMalformedPolicyDocumentException for service response error code + // "MalformedPolicyDocument". + // + // The request was rejected because the policy document was malformed. The error + // message describes the specific error. + ErrCodeMalformedPolicyDocumentException = "MalformedPolicyDocument" + + // ErrCodePackedPolicyTooLargeException for service response error code + // "PackedPolicyTooLarge". + // + // The request was rejected because the policy document was too large. The error + // message describes how big the policy document is, in packed form, as a percentage + // of what the API allows. + ErrCodePackedPolicyTooLargeException = "PackedPolicyTooLarge" + + // ErrCodeRegionDisabledException for service response error code + // "RegionDisabledException". + // + // STS is not activated in the requested region for the account that is being + // asked to generate credentials. The account administrator must use the IAM + // console to activate STS in that region. For more information, see Activating + // and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) + // in the IAM User Guide. + ErrCodeRegionDisabledException = "RegionDisabledException" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/service.go b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go new file mode 100644 index 000000000..185c914d1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go @@ -0,0 +1,95 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol/query" +) + +// STS provides the API operation methods for making requests to +// AWS Security Token Service. See this package's package overview docs +// for details on the service. +// +// STS methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type STS struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "sts" // Name of service. + EndpointsID = ServiceName // ID to lookup a service endpoint with. + ServiceID = "STS" // ServiceID is a unique identifer of a specific service. +) + +// New creates a new instance of the STS client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// // Create a STS client from just a session. +// svc := sts.New(mySession) +// +// // Create a STS client with additional configuration +// svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *STS { + c := p.ClientConfig(EndpointsID, cfgs...) + return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *STS { + svc := &STS{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + Endpoint: endpoint, + APIVersion: "2011-06-15", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(query.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a STS operation and runs any +// custom request initialization. +func (c *STS) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go b/vendor/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go new file mode 100644 index 000000000..e2e1d6efe --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go @@ -0,0 +1,96 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package stsiface provides an interface to enable mocking the AWS Security Token Service service client +// for testing your code. +// +// It is important to note that this interface will have breaking changes +// when the service model is updated and adds new API operations, paginators, +// and waiters. +package stsiface + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/service/sts" +) + +// STSAPI provides an interface to enable mocking the +// sts.STS service client's API operation, +// paginators, and waiters. This make unit testing your code that calls out +// to the SDK's service client's calls easier. +// +// The best way to use this interface is so the SDK's service client's calls +// can be stubbed out for unit testing your code with the SDK without needing +// to inject custom request handlers into the SDK's request pipeline. +// +// // myFunc uses an SDK service client to make a request to +// // AWS Security Token Service. +// func myFunc(svc stsiface.STSAPI) bool { +// // Make svc.AssumeRole request +// } +// +// func main() { +// sess := session.New() +// svc := sts.New(sess) +// +// myFunc(svc) +// } +// +// In your _test.go file: +// +// // Define a mock struct to be used in your unit tests of myFunc. +// type mockSTSClient struct { +// stsiface.STSAPI +// } +// func (m *mockSTSClient) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) { +// // mock response/functionality +// } +// +// func TestMyFunc(t *testing.T) { +// // Setup Test +// mockSvc := &mockSTSClient{} +// +// myfunc(mockSvc) +// +// // Verify myFunc's functionality +// } +// +// It is important to note that this interface will have breaking changes +// when the service model is updated and adds new API operations, paginators, +// and waiters. Its suggested to use the pattern above for testing, or using +// tooling to generate mocks to satisfy the interfaces. +type STSAPI interface { + AssumeRole(*sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) + AssumeRoleWithContext(aws.Context, *sts.AssumeRoleInput, ...request.Option) (*sts.AssumeRoleOutput, error) + AssumeRoleRequest(*sts.AssumeRoleInput) (*request.Request, *sts.AssumeRoleOutput) + + AssumeRoleWithSAML(*sts.AssumeRoleWithSAMLInput) (*sts.AssumeRoleWithSAMLOutput, error) + AssumeRoleWithSAMLWithContext(aws.Context, *sts.AssumeRoleWithSAMLInput, ...request.Option) (*sts.AssumeRoleWithSAMLOutput, error) + AssumeRoleWithSAMLRequest(*sts.AssumeRoleWithSAMLInput) (*request.Request, *sts.AssumeRoleWithSAMLOutput) + + AssumeRoleWithWebIdentity(*sts.AssumeRoleWithWebIdentityInput) (*sts.AssumeRoleWithWebIdentityOutput, error) + AssumeRoleWithWebIdentityWithContext(aws.Context, *sts.AssumeRoleWithWebIdentityInput, ...request.Option) (*sts.AssumeRoleWithWebIdentityOutput, error) + AssumeRoleWithWebIdentityRequest(*sts.AssumeRoleWithWebIdentityInput) (*request.Request, *sts.AssumeRoleWithWebIdentityOutput) + + DecodeAuthorizationMessage(*sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error) + DecodeAuthorizationMessageWithContext(aws.Context, *sts.DecodeAuthorizationMessageInput, ...request.Option) (*sts.DecodeAuthorizationMessageOutput, error) + DecodeAuthorizationMessageRequest(*sts.DecodeAuthorizationMessageInput) (*request.Request, *sts.DecodeAuthorizationMessageOutput) + + GetAccessKeyInfo(*sts.GetAccessKeyInfoInput) (*sts.GetAccessKeyInfoOutput, error) + GetAccessKeyInfoWithContext(aws.Context, *sts.GetAccessKeyInfoInput, ...request.Option) (*sts.GetAccessKeyInfoOutput, error) + GetAccessKeyInfoRequest(*sts.GetAccessKeyInfoInput) (*request.Request, *sts.GetAccessKeyInfoOutput) + + GetCallerIdentity(*sts.GetCallerIdentityInput) (*sts.GetCallerIdentityOutput, error) + GetCallerIdentityWithContext(aws.Context, *sts.GetCallerIdentityInput, ...request.Option) (*sts.GetCallerIdentityOutput, error) + GetCallerIdentityRequest(*sts.GetCallerIdentityInput) (*request.Request, *sts.GetCallerIdentityOutput) + + GetFederationToken(*sts.GetFederationTokenInput) (*sts.GetFederationTokenOutput, error) + GetFederationTokenWithContext(aws.Context, *sts.GetFederationTokenInput, ...request.Option) (*sts.GetFederationTokenOutput, error) + GetFederationTokenRequest(*sts.GetFederationTokenInput) (*request.Request, *sts.GetFederationTokenOutput) + + GetSessionToken(*sts.GetSessionTokenInput) (*sts.GetSessionTokenOutput, error) + GetSessionTokenWithContext(aws.Context, *sts.GetSessionTokenInput, ...request.Option) (*sts.GetSessionTokenOutput, error) + GetSessionTokenRequest(*sts.GetSessionTokenInput) (*request.Request, *sts.GetSessionTokenOutput) +} + +var _ STSAPI = (*sts.STS)(nil) diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/AUTHORS b/vendor/github.com/census-instrumentation/opencensus-proto/AUTHORS new file mode 100644 index 000000000..e068e731e --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/AUTHORS @@ -0,0 +1 @@ +Google Inc. \ No newline at end of file diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/LICENSE b/vendor/github.com/census-instrumentation/opencensus-proto/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1/common.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1/common.pb.go new file mode 100644 index 000000000..12b578d06 --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1/common.pb.go @@ -0,0 +1,356 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: opencensus/proto/agent/common/v1/common.proto + +package v1 + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type LibraryInfo_Language int32 + +const ( + LibraryInfo_LANGUAGE_UNSPECIFIED LibraryInfo_Language = 0 + LibraryInfo_CPP LibraryInfo_Language = 1 + LibraryInfo_C_SHARP LibraryInfo_Language = 2 + LibraryInfo_ERLANG LibraryInfo_Language = 3 + LibraryInfo_GO_LANG LibraryInfo_Language = 4 + LibraryInfo_JAVA LibraryInfo_Language = 5 + LibraryInfo_NODE_JS LibraryInfo_Language = 6 + LibraryInfo_PHP LibraryInfo_Language = 7 + LibraryInfo_PYTHON LibraryInfo_Language = 8 + LibraryInfo_RUBY LibraryInfo_Language = 9 +) + +var LibraryInfo_Language_name = map[int32]string{ + 0: "LANGUAGE_UNSPECIFIED", + 1: "CPP", + 2: "C_SHARP", + 3: "ERLANG", + 4: "GO_LANG", + 5: "JAVA", + 6: "NODE_JS", + 7: "PHP", + 8: "PYTHON", + 9: "RUBY", +} + +var LibraryInfo_Language_value = map[string]int32{ + "LANGUAGE_UNSPECIFIED": 0, + "CPP": 1, + "C_SHARP": 2, + "ERLANG": 3, + "GO_LANG": 4, + "JAVA": 5, + "NODE_JS": 6, + "PHP": 7, + "PYTHON": 8, + "RUBY": 9, +} + +func (x LibraryInfo_Language) String() string { + return proto.EnumName(LibraryInfo_Language_name, int32(x)) +} + +func (LibraryInfo_Language) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_126c72ed8a252c84, []int{2, 0} +} + +// Identifier metadata of the Node that produces the span or tracing data. +// Note, this is not the metadata about the Node or service that is described by associated spans. +// In the future we plan to extend the identifier proto definition to support +// additional information (e.g cloud id, etc.) +type Node struct { + // Identifier that uniquely identifies a process within a VM/container. + Identifier *ProcessIdentifier `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` + // Information on the OpenCensus Library that initiates the stream. + LibraryInfo *LibraryInfo `protobuf:"bytes,2,opt,name=library_info,json=libraryInfo,proto3" json:"library_info,omitempty"` + // Additional information on service. + ServiceInfo *ServiceInfo `protobuf:"bytes,3,opt,name=service_info,json=serviceInfo,proto3" json:"service_info,omitempty"` + // Additional attributes. + Attributes map[string]string `protobuf:"bytes,4,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Node) Reset() { *m = Node{} } +func (m *Node) String() string { return proto.CompactTextString(m) } +func (*Node) ProtoMessage() {} +func (*Node) Descriptor() ([]byte, []int) { + return fileDescriptor_126c72ed8a252c84, []int{0} +} + +func (m *Node) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Node.Unmarshal(m, b) +} +func (m *Node) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Node.Marshal(b, m, deterministic) +} +func (m *Node) XXX_Merge(src proto.Message) { + xxx_messageInfo_Node.Merge(m, src) +} +func (m *Node) XXX_Size() int { + return xxx_messageInfo_Node.Size(m) +} +func (m *Node) XXX_DiscardUnknown() { + xxx_messageInfo_Node.DiscardUnknown(m) +} + +var xxx_messageInfo_Node proto.InternalMessageInfo + +func (m *Node) GetIdentifier() *ProcessIdentifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (m *Node) GetLibraryInfo() *LibraryInfo { + if m != nil { + return m.LibraryInfo + } + return nil +} + +func (m *Node) GetServiceInfo() *ServiceInfo { + if m != nil { + return m.ServiceInfo + } + return nil +} + +func (m *Node) GetAttributes() map[string]string { + if m != nil { + return m.Attributes + } + return nil +} + +// Identifier that uniquely identifies a process within a VM/container. +type ProcessIdentifier struct { + // The host name. Usually refers to the machine/container name. + // For example: os.Hostname() in Go, socket.gethostname() in Python. + HostName string `protobuf:"bytes,1,opt,name=host_name,json=hostName,proto3" json:"host_name,omitempty"` + // Process id. + Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` + // Start time of this ProcessIdentifier. Represented in epoch time. + StartTimestamp *timestamp.Timestamp `protobuf:"bytes,3,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ProcessIdentifier) Reset() { *m = ProcessIdentifier{} } +func (m *ProcessIdentifier) String() string { return proto.CompactTextString(m) } +func (*ProcessIdentifier) ProtoMessage() {} +func (*ProcessIdentifier) Descriptor() ([]byte, []int) { + return fileDescriptor_126c72ed8a252c84, []int{1} +} + +func (m *ProcessIdentifier) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProcessIdentifier.Unmarshal(m, b) +} +func (m *ProcessIdentifier) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProcessIdentifier.Marshal(b, m, deterministic) +} +func (m *ProcessIdentifier) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProcessIdentifier.Merge(m, src) +} +func (m *ProcessIdentifier) XXX_Size() int { + return xxx_messageInfo_ProcessIdentifier.Size(m) +} +func (m *ProcessIdentifier) XXX_DiscardUnknown() { + xxx_messageInfo_ProcessIdentifier.DiscardUnknown(m) +} + +var xxx_messageInfo_ProcessIdentifier proto.InternalMessageInfo + +func (m *ProcessIdentifier) GetHostName() string { + if m != nil { + return m.HostName + } + return "" +} + +func (m *ProcessIdentifier) GetPid() uint32 { + if m != nil { + return m.Pid + } + return 0 +} + +func (m *ProcessIdentifier) GetStartTimestamp() *timestamp.Timestamp { + if m != nil { + return m.StartTimestamp + } + return nil +} + +// Information on OpenCensus Library. +type LibraryInfo struct { + // Language of OpenCensus Library. + Language LibraryInfo_Language `protobuf:"varint,1,opt,name=language,proto3,enum=opencensus.proto.agent.common.v1.LibraryInfo_Language" json:"language,omitempty"` + // Version of Agent exporter of Library. + ExporterVersion string `protobuf:"bytes,2,opt,name=exporter_version,json=exporterVersion,proto3" json:"exporter_version,omitempty"` + // Version of OpenCensus Library. + CoreLibraryVersion string `protobuf:"bytes,3,opt,name=core_library_version,json=coreLibraryVersion,proto3" json:"core_library_version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LibraryInfo) Reset() { *m = LibraryInfo{} } +func (m *LibraryInfo) String() string { return proto.CompactTextString(m) } +func (*LibraryInfo) ProtoMessage() {} +func (*LibraryInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_126c72ed8a252c84, []int{2} +} + +func (m *LibraryInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LibraryInfo.Unmarshal(m, b) +} +func (m *LibraryInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LibraryInfo.Marshal(b, m, deterministic) +} +func (m *LibraryInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_LibraryInfo.Merge(m, src) +} +func (m *LibraryInfo) XXX_Size() int { + return xxx_messageInfo_LibraryInfo.Size(m) +} +func (m *LibraryInfo) XXX_DiscardUnknown() { + xxx_messageInfo_LibraryInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_LibraryInfo proto.InternalMessageInfo + +func (m *LibraryInfo) GetLanguage() LibraryInfo_Language { + if m != nil { + return m.Language + } + return LibraryInfo_LANGUAGE_UNSPECIFIED +} + +func (m *LibraryInfo) GetExporterVersion() string { + if m != nil { + return m.ExporterVersion + } + return "" +} + +func (m *LibraryInfo) GetCoreLibraryVersion() string { + if m != nil { + return m.CoreLibraryVersion + } + return "" +} + +// Additional service information. +type ServiceInfo struct { + // Name of the service. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceInfo) Reset() { *m = ServiceInfo{} } +func (m *ServiceInfo) String() string { return proto.CompactTextString(m) } +func (*ServiceInfo) ProtoMessage() {} +func (*ServiceInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_126c72ed8a252c84, []int{3} +} + +func (m *ServiceInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceInfo.Unmarshal(m, b) +} +func (m *ServiceInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceInfo.Marshal(b, m, deterministic) +} +func (m *ServiceInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceInfo.Merge(m, src) +} +func (m *ServiceInfo) XXX_Size() int { + return xxx_messageInfo_ServiceInfo.Size(m) +} +func (m *ServiceInfo) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceInfo proto.InternalMessageInfo + +func (m *ServiceInfo) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func init() { + proto.RegisterEnum("opencensus.proto.agent.common.v1.LibraryInfo_Language", LibraryInfo_Language_name, LibraryInfo_Language_value) + proto.RegisterType((*Node)(nil), "opencensus.proto.agent.common.v1.Node") + proto.RegisterMapType((map[string]string)(nil), "opencensus.proto.agent.common.v1.Node.AttributesEntry") + proto.RegisterType((*ProcessIdentifier)(nil), "opencensus.proto.agent.common.v1.ProcessIdentifier") + proto.RegisterType((*LibraryInfo)(nil), "opencensus.proto.agent.common.v1.LibraryInfo") + proto.RegisterType((*ServiceInfo)(nil), "opencensus.proto.agent.common.v1.ServiceInfo") +} + +func init() { + proto.RegisterFile("opencensus/proto/agent/common/v1/common.proto", fileDescriptor_126c72ed8a252c84) +} + +var fileDescriptor_126c72ed8a252c84 = []byte{ + // 590 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0x4f, 0x4f, 0xdb, 0x3e, + 0x1c, 0xc6, 0x7f, 0x69, 0x0a, 0xb4, 0xdf, 0xfc, 0x06, 0x99, 0xc5, 0xa1, 0x62, 0x87, 0xb1, 0xee, + 0xc2, 0x0e, 0x4d, 0x06, 0x48, 0xd3, 0x34, 0x69, 0x87, 0x52, 0x3a, 0x28, 0x42, 0x25, 0x72, 0x01, + 0x89, 0x5d, 0xa2, 0xb4, 0xb8, 0xc1, 0x5a, 0x63, 0x57, 0xb6, 0x53, 0x8d, 0xd3, 0x8e, 0xd3, 0xde, + 0xc0, 0x5e, 0xd4, 0x5e, 0xd5, 0x64, 0x3b, 0x69, 0xa3, 0x71, 0x28, 0xb7, 0xef, 0x9f, 0xe7, 0xf9, + 0x38, 0x7a, 0x6c, 0x05, 0x3a, 0x7c, 0x4e, 0xd8, 0x84, 0x30, 0x99, 0xcb, 0x70, 0x2e, 0xb8, 0xe2, + 0x61, 0x92, 0x12, 0xa6, 0xc2, 0x09, 0xcf, 0x32, 0xce, 0xc2, 0xc5, 0x61, 0x51, 0x05, 0x66, 0x89, + 0xf6, 0x57, 0x72, 0x3b, 0x09, 0x8c, 0x3c, 0x28, 0x44, 0x8b, 0xc3, 0xbd, 0xd7, 0x29, 0xe7, 0xe9, + 0x8c, 0x58, 0xd8, 0x38, 0x9f, 0x86, 0x8a, 0x66, 0x44, 0xaa, 0x24, 0x9b, 0x5b, 0x43, 0xfb, 0xb7, + 0x0b, 0xf5, 0x21, 0xbf, 0x27, 0x68, 0x04, 0x40, 0xef, 0x09, 0x53, 0x74, 0x4a, 0x89, 0x68, 0x39, + 0xfb, 0xce, 0x81, 0x77, 0x74, 0x1c, 0xac, 0x3b, 0x20, 0x88, 0x04, 0x9f, 0x10, 0x29, 0x07, 0x4b, + 0x2b, 0xae, 0x60, 0x50, 0x04, 0xff, 0xcf, 0xe8, 0x58, 0x24, 0xe2, 0x31, 0xa6, 0x6c, 0xca, 0x5b, + 0x35, 0x83, 0xed, 0xac, 0xc7, 0x5e, 0x5a, 0xd7, 0x80, 0x4d, 0x39, 0xf6, 0x66, 0xab, 0x46, 0x13, + 0x25, 0x11, 0x0b, 0x3a, 0x21, 0x96, 0xe8, 0x3e, 0x97, 0x38, 0xb2, 0x2e, 0x4b, 0x94, 0xab, 0x06, + 0xdd, 0x02, 0x24, 0x4a, 0x09, 0x3a, 0xce, 0x15, 0x91, 0xad, 0xfa, 0xbe, 0x7b, 0xe0, 0x1d, 0x7d, + 0x58, 0xcf, 0xd3, 0xa1, 0x05, 0xdd, 0xa5, 0xb1, 0xcf, 0x94, 0x78, 0xc4, 0x15, 0xd2, 0xde, 0x67, + 0xd8, 0xf9, 0x67, 0x8d, 0x7c, 0x70, 0xbf, 0x91, 0x47, 0x13, 0x6e, 0x13, 0xeb, 0x12, 0xed, 0xc2, + 0xc6, 0x22, 0x99, 0xe5, 0xc4, 0x24, 0xd3, 0xc4, 0xb6, 0xf9, 0x54, 0xfb, 0xe8, 0xb4, 0x7f, 0x3a, + 0xf0, 0xf2, 0x49, 0xb8, 0xe8, 0x15, 0x34, 0x1f, 0xb8, 0x54, 0x31, 0x4b, 0x32, 0x52, 0x70, 0x1a, + 0x7a, 0x30, 0x4c, 0x32, 0xa2, 0xf1, 0x73, 0x7a, 0x6f, 0x50, 0x2f, 0xb0, 0x2e, 0x51, 0x0f, 0x76, + 0xa4, 0x4a, 0x84, 0x8a, 0x97, 0xd7, 0x5e, 0x04, 0xb6, 0x17, 0xd8, 0x87, 0x11, 0x94, 0x0f, 0x23, + 0xb8, 0x2e, 0x15, 0x78, 0xdb, 0x58, 0x96, 0x7d, 0xfb, 0x4f, 0x0d, 0xbc, 0xca, 0x7d, 0x20, 0x0c, + 0x8d, 0x59, 0xc2, 0xd2, 0x3c, 0x49, 0xed, 0x27, 0x6c, 0x3f, 0x27, 0xae, 0x0a, 0x20, 0xb8, 0x2c, + 0xdc, 0x78, 0xc9, 0x41, 0xef, 0xc0, 0x27, 0xdf, 0xe7, 0x5c, 0x28, 0x22, 0xe2, 0x05, 0x11, 0x92, + 0x72, 0x56, 0x44, 0xb2, 0x53, 0xce, 0x6f, 0xed, 0x18, 0xbd, 0x87, 0xdd, 0x09, 0x17, 0x24, 0x2e, + 0x1f, 0x56, 0x29, 0x77, 0x8d, 0x1c, 0xe9, 0x5d, 0x71, 0x58, 0xe1, 0x68, 0xff, 0x72, 0xa0, 0x51, + 0x9e, 0x89, 0x5a, 0xb0, 0x7b, 0xd9, 0x1d, 0x9e, 0xdd, 0x74, 0xcf, 0xfa, 0xf1, 0xcd, 0x70, 0x14, + 0xf5, 0x7b, 0x83, 0x2f, 0x83, 0xfe, 0xa9, 0xff, 0x1f, 0xda, 0x02, 0xb7, 0x17, 0x45, 0xbe, 0x83, + 0x3c, 0xd8, 0xea, 0xc5, 0xa3, 0xf3, 0x2e, 0x8e, 0xfc, 0x1a, 0x02, 0xd8, 0xec, 0x63, 0xed, 0xf0, + 0x5d, 0xbd, 0x38, 0xbb, 0x8a, 0x4d, 0x53, 0x47, 0x0d, 0xa8, 0x5f, 0x74, 0x6f, 0xbb, 0xfe, 0x86, + 0x1e, 0x0f, 0xaf, 0x4e, 0xfb, 0xf1, 0xc5, 0xc8, 0xdf, 0xd4, 0x94, 0xe8, 0x3c, 0xf2, 0xb7, 0xb4, + 0x31, 0xba, 0xbb, 0x3e, 0xbf, 0x1a, 0xfa, 0x0d, 0xad, 0xc5, 0x37, 0x27, 0x77, 0x7e, 0xb3, 0xfd, + 0x06, 0xbc, 0xca, 0x4b, 0x44, 0x08, 0xea, 0x95, 0xab, 0x34, 0xf5, 0xc9, 0x0f, 0x78, 0x4b, 0xf9, + 0xda, 0x44, 0x4f, 0xbc, 0x9e, 0x29, 0x23, 0xbd, 0x8c, 0x9c, 0xaf, 0x83, 0x94, 0xaa, 0x87, 0x7c, + 0xac, 0x05, 0xa1, 0xf5, 0x75, 0x28, 0x93, 0x4a, 0xe4, 0x19, 0x61, 0x2a, 0x51, 0x94, 0xb3, 0x70, + 0x85, 0xec, 0xd8, 0x9f, 0x4b, 0x4a, 0x58, 0x27, 0x7d, 0xf2, 0x8f, 0x19, 0x6f, 0x9a, 0xed, 0xf1, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x94, 0xe5, 0x77, 0x76, 0x8e, 0x04, 0x00, 0x00, +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go new file mode 100644 index 000000000..801212d92 --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1/metrics_service.pb.go @@ -0,0 +1,264 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: opencensus/proto/agent/metrics/v1/metrics_service.proto + +package v1 + +import ( + context "context" + fmt "fmt" + v1 "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1" + v11 "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" + v12 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type ExportMetricsServiceRequest struct { + // This is required only in the first message on the stream or if the + // previous sent ExportMetricsServiceRequest message has a different Node (e.g. + // when the same RPC is used to send Metrics from multiple Applications). + Node *v1.Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + // A list of metrics that belong to the last received Node. + Metrics []*v11.Metric `protobuf:"bytes,2,rep,name=metrics,proto3" json:"metrics,omitempty"` + // The resource for the metrics in this message that do not have an explicit + // resource set. + // If unset, the most recently set resource in the RPC stream applies. It is + // valid to never be set within a stream, e.g. when no resource info is known + // at all or when all sent metrics have an explicit resource set. + Resource *v12.Resource `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExportMetricsServiceRequest) Reset() { *m = ExportMetricsServiceRequest{} } +func (m *ExportMetricsServiceRequest) String() string { return proto.CompactTextString(m) } +func (*ExportMetricsServiceRequest) ProtoMessage() {} +func (*ExportMetricsServiceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_47e253a956287d04, []int{0} +} + +func (m *ExportMetricsServiceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExportMetricsServiceRequest.Unmarshal(m, b) +} +func (m *ExportMetricsServiceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExportMetricsServiceRequest.Marshal(b, m, deterministic) +} +func (m *ExportMetricsServiceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExportMetricsServiceRequest.Merge(m, src) +} +func (m *ExportMetricsServiceRequest) XXX_Size() int { + return xxx_messageInfo_ExportMetricsServiceRequest.Size(m) +} +func (m *ExportMetricsServiceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ExportMetricsServiceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ExportMetricsServiceRequest proto.InternalMessageInfo + +func (m *ExportMetricsServiceRequest) GetNode() *v1.Node { + if m != nil { + return m.Node + } + return nil +} + +func (m *ExportMetricsServiceRequest) GetMetrics() []*v11.Metric { + if m != nil { + return m.Metrics + } + return nil +} + +func (m *ExportMetricsServiceRequest) GetResource() *v12.Resource { + if m != nil { + return m.Resource + } + return nil +} + +type ExportMetricsServiceResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExportMetricsServiceResponse) Reset() { *m = ExportMetricsServiceResponse{} } +func (m *ExportMetricsServiceResponse) String() string { return proto.CompactTextString(m) } +func (*ExportMetricsServiceResponse) ProtoMessage() {} +func (*ExportMetricsServiceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_47e253a956287d04, []int{1} +} + +func (m *ExportMetricsServiceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExportMetricsServiceResponse.Unmarshal(m, b) +} +func (m *ExportMetricsServiceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExportMetricsServiceResponse.Marshal(b, m, deterministic) +} +func (m *ExportMetricsServiceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExportMetricsServiceResponse.Merge(m, src) +} +func (m *ExportMetricsServiceResponse) XXX_Size() int { + return xxx_messageInfo_ExportMetricsServiceResponse.Size(m) +} +func (m *ExportMetricsServiceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ExportMetricsServiceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ExportMetricsServiceResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*ExportMetricsServiceRequest)(nil), "opencensus.proto.agent.metrics.v1.ExportMetricsServiceRequest") + proto.RegisterType((*ExportMetricsServiceResponse)(nil), "opencensus.proto.agent.metrics.v1.ExportMetricsServiceResponse") +} + +func init() { + proto.RegisterFile("opencensus/proto/agent/metrics/v1/metrics_service.proto", fileDescriptor_47e253a956287d04) +} + +var fileDescriptor_47e253a956287d04 = []byte{ + // 340 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0xc1, 0x4a, 0xf3, 0x40, + 0x14, 0x85, 0xff, 0xf9, 0x2b, 0x55, 0xa6, 0xe0, 0x62, 0xdc, 0x94, 0x2a, 0x52, 0xab, 0x48, 0x45, + 0x32, 0x63, 0xea, 0x42, 0x10, 0x54, 0x28, 0xb8, 0x11, 0x94, 0x12, 0x77, 0x6e, 0xa4, 0x4d, 0x2f, + 0x71, 0x16, 0x99, 0x1b, 0x67, 0x26, 0xc1, 0x57, 0x70, 0xe5, 0x3b, 0xf8, 0x5c, 0x3e, 0x8c, 0x24, + 0x93, 0xb4, 0x94, 0x18, 0x0b, 0xee, 0x2e, 0x99, 0xf3, 0x9d, 0x9c, 0x33, 0x73, 0xe9, 0x05, 0x26, + 0xa0, 0x42, 0x50, 0x26, 0x35, 0x22, 0xd1, 0x68, 0x51, 0x4c, 0x23, 0x50, 0x56, 0xc4, 0x60, 0xb5, + 0x0c, 0x8d, 0xc8, 0xfc, 0x6a, 0x7c, 0x36, 0xa0, 0x33, 0x19, 0x02, 0x2f, 0x64, 0xec, 0x60, 0x09, + 0xba, 0x2f, 0xbc, 0x00, 0x79, 0xa9, 0xe6, 0x99, 0xdf, 0xf3, 0x1a, 0xbc, 0x43, 0x8c, 0x63, 0x54, + 0xb9, 0xb5, 0x9b, 0x1c, 0xdf, 0x3b, 0xa9, 0xc9, 0xeb, 0x21, 0x4a, 0xe9, 0x69, 0x4d, 0xaa, 0xc1, + 0x60, 0xaa, 0x43, 0xc8, 0xb5, 0xd5, 0xec, 0xc4, 0x83, 0x2f, 0x42, 0x77, 0x6f, 0xdf, 0x12, 0xd4, + 0xf6, 0xde, 0x99, 0x3c, 0xba, 0x22, 0x01, 0xbc, 0xa6, 0x60, 0x2c, 0xbb, 0xa4, 0x1b, 0x0a, 0xe7, + 0xd0, 0x25, 0x7d, 0x32, 0xec, 0x8c, 0x8e, 0x79, 0x43, 0xb1, 0x32, 0x6b, 0xe6, 0xf3, 0x07, 0x9c, + 0x43, 0x50, 0x30, 0xec, 0x8a, 0x6e, 0x96, 0xc9, 0xba, 0xff, 0xfb, 0xad, 0x61, 0x67, 0x74, 0x58, + 0xc7, 0x97, 0x37, 0xc2, 0x5d, 0x80, 0xa0, 0x62, 0xd8, 0x98, 0x6e, 0x55, 0x61, 0xbb, 0xad, 0xa6, + 0xdf, 0x2f, 0xea, 0x64, 0x3e, 0x0f, 0xca, 0x39, 0x58, 0x70, 0x83, 0x7d, 0xba, 0xf7, 0x73, 0x3b, + 0x93, 0xa0, 0x32, 0x30, 0xfa, 0x24, 0x74, 0x7b, 0xf5, 0x88, 0x7d, 0x10, 0xda, 0x76, 0x0c, 0xbb, + 0xe6, 0x6b, 0xdf, 0x91, 0xff, 0x72, 0x79, 0xbd, 0x9b, 0x3f, 0xf3, 0x2e, 0xde, 0xe0, 0xdf, 0x90, + 0x9c, 0x91, 0xf1, 0x3b, 0xa1, 0x47, 0x12, 0xd7, 0x7b, 0x8d, 0x77, 0x56, 0x6d, 0x26, 0xb9, 0x6a, + 0x42, 0x9e, 0xee, 0x22, 0x69, 0x5f, 0xd2, 0x59, 0xfe, 0x48, 0xc2, 0x19, 0x78, 0x52, 0x19, 0xab, + 0xd3, 0x18, 0x94, 0x9d, 0x5a, 0x89, 0x4a, 0x2c, 0xbd, 0x3d, 0xb7, 0x32, 0x11, 0x28, 0x2f, 0xaa, + 0xef, 0xfb, 0xac, 0x5d, 0x1c, 0x9f, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x16, 0x61, 0x3b, 0xc3, + 0x1b, 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MetricsServiceClient is the client API for MetricsService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MetricsServiceClient interface { + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + Export(ctx context.Context, opts ...grpc.CallOption) (MetricsService_ExportClient, error) +} + +type metricsServiceClient struct { + cc *grpc.ClientConn +} + +func NewMetricsServiceClient(cc *grpc.ClientConn) MetricsServiceClient { + return &metricsServiceClient{cc} +} + +func (c *metricsServiceClient) Export(ctx context.Context, opts ...grpc.CallOption) (MetricsService_ExportClient, error) { + stream, err := c.cc.NewStream(ctx, &_MetricsService_serviceDesc.Streams[0], "/opencensus.proto.agent.metrics.v1.MetricsService/Export", opts...) + if err != nil { + return nil, err + } + x := &metricsServiceExportClient{stream} + return x, nil +} + +type MetricsService_ExportClient interface { + Send(*ExportMetricsServiceRequest) error + Recv() (*ExportMetricsServiceResponse, error) + grpc.ClientStream +} + +type metricsServiceExportClient struct { + grpc.ClientStream +} + +func (x *metricsServiceExportClient) Send(m *ExportMetricsServiceRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *metricsServiceExportClient) Recv() (*ExportMetricsServiceResponse, error) { + m := new(ExportMetricsServiceResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// MetricsServiceServer is the server API for MetricsService service. +type MetricsServiceServer interface { + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + Export(MetricsService_ExportServer) error +} + +func RegisterMetricsServiceServer(s *grpc.Server, srv MetricsServiceServer) { + s.RegisterService(&_MetricsService_serviceDesc, srv) +} + +func _MetricsService_Export_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(MetricsServiceServer).Export(&metricsServiceExportServer{stream}) +} + +type MetricsService_ExportServer interface { + Send(*ExportMetricsServiceResponse) error + Recv() (*ExportMetricsServiceRequest, error) + grpc.ServerStream +} + +type metricsServiceExportServer struct { + grpc.ServerStream +} + +func (x *metricsServiceExportServer) Send(m *ExportMetricsServiceResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *metricsServiceExportServer) Recv() (*ExportMetricsServiceRequest, error) { + m := new(ExportMetricsServiceRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _MetricsService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "opencensus.proto.agent.metrics.v1.MetricsService", + HandlerType: (*MetricsServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Export", + Handler: _MetricsService_Export_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "opencensus/proto/agent/metrics/v1/metrics_service.proto", +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go new file mode 100644 index 000000000..e7c49a387 --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.go @@ -0,0 +1,443 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: opencensus/proto/agent/trace/v1/trace_service.proto + +package v1 + +import ( + context "context" + fmt "fmt" + v1 "github.com/census-instrumentation/opencensus-proto/gen-go/agent/common/v1" + v12 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" + v11 "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type CurrentLibraryConfig struct { + // This is required only in the first message on the stream or if the + // previous sent CurrentLibraryConfig message has a different Node (e.g. + // when the same RPC is used to configure multiple Applications). + Node *v1.Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + // Current configuration. + Config *v11.TraceConfig `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CurrentLibraryConfig) Reset() { *m = CurrentLibraryConfig{} } +func (m *CurrentLibraryConfig) String() string { return proto.CompactTextString(m) } +func (*CurrentLibraryConfig) ProtoMessage() {} +func (*CurrentLibraryConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_7027f99caf7ac6a5, []int{0} +} + +func (m *CurrentLibraryConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CurrentLibraryConfig.Unmarshal(m, b) +} +func (m *CurrentLibraryConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CurrentLibraryConfig.Marshal(b, m, deterministic) +} +func (m *CurrentLibraryConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_CurrentLibraryConfig.Merge(m, src) +} +func (m *CurrentLibraryConfig) XXX_Size() int { + return xxx_messageInfo_CurrentLibraryConfig.Size(m) +} +func (m *CurrentLibraryConfig) XXX_DiscardUnknown() { + xxx_messageInfo_CurrentLibraryConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_CurrentLibraryConfig proto.InternalMessageInfo + +func (m *CurrentLibraryConfig) GetNode() *v1.Node { + if m != nil { + return m.Node + } + return nil +} + +func (m *CurrentLibraryConfig) GetConfig() *v11.TraceConfig { + if m != nil { + return m.Config + } + return nil +} + +type UpdatedLibraryConfig struct { + // This field is ignored when the RPC is used to configure only one Application. + // This is required only in the first message on the stream or if the + // previous sent UpdatedLibraryConfig message has a different Node. + Node *v1.Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + // Requested updated configuration. + Config *v11.TraceConfig `protobuf:"bytes,2,opt,name=config,proto3" json:"config,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UpdatedLibraryConfig) Reset() { *m = UpdatedLibraryConfig{} } +func (m *UpdatedLibraryConfig) String() string { return proto.CompactTextString(m) } +func (*UpdatedLibraryConfig) ProtoMessage() {} +func (*UpdatedLibraryConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_7027f99caf7ac6a5, []int{1} +} + +func (m *UpdatedLibraryConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UpdatedLibraryConfig.Unmarshal(m, b) +} +func (m *UpdatedLibraryConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UpdatedLibraryConfig.Marshal(b, m, deterministic) +} +func (m *UpdatedLibraryConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_UpdatedLibraryConfig.Merge(m, src) +} +func (m *UpdatedLibraryConfig) XXX_Size() int { + return xxx_messageInfo_UpdatedLibraryConfig.Size(m) +} +func (m *UpdatedLibraryConfig) XXX_DiscardUnknown() { + xxx_messageInfo_UpdatedLibraryConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_UpdatedLibraryConfig proto.InternalMessageInfo + +func (m *UpdatedLibraryConfig) GetNode() *v1.Node { + if m != nil { + return m.Node + } + return nil +} + +func (m *UpdatedLibraryConfig) GetConfig() *v11.TraceConfig { + if m != nil { + return m.Config + } + return nil +} + +type ExportTraceServiceRequest struct { + // This is required only in the first message on the stream or if the + // previous sent ExportTraceServiceRequest message has a different Node (e.g. + // when the same RPC is used to send Spans from multiple Applications). + Node *v1.Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + // A list of Spans that belong to the last received Node. + Spans []*v11.Span `protobuf:"bytes,2,rep,name=spans,proto3" json:"spans,omitempty"` + // The resource for the spans in this message that do not have an explicit + // resource set. + // If unset, the most recently set resource in the RPC stream applies. It is + // valid to never be set within a stream, e.g. when no resource info is known. + Resource *v12.Resource `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExportTraceServiceRequest) Reset() { *m = ExportTraceServiceRequest{} } +func (m *ExportTraceServiceRequest) String() string { return proto.CompactTextString(m) } +func (*ExportTraceServiceRequest) ProtoMessage() {} +func (*ExportTraceServiceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_7027f99caf7ac6a5, []int{2} +} + +func (m *ExportTraceServiceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExportTraceServiceRequest.Unmarshal(m, b) +} +func (m *ExportTraceServiceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExportTraceServiceRequest.Marshal(b, m, deterministic) +} +func (m *ExportTraceServiceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExportTraceServiceRequest.Merge(m, src) +} +func (m *ExportTraceServiceRequest) XXX_Size() int { + return xxx_messageInfo_ExportTraceServiceRequest.Size(m) +} +func (m *ExportTraceServiceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ExportTraceServiceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ExportTraceServiceRequest proto.InternalMessageInfo + +func (m *ExportTraceServiceRequest) GetNode() *v1.Node { + if m != nil { + return m.Node + } + return nil +} + +func (m *ExportTraceServiceRequest) GetSpans() []*v11.Span { + if m != nil { + return m.Spans + } + return nil +} + +func (m *ExportTraceServiceRequest) GetResource() *v12.Resource { + if m != nil { + return m.Resource + } + return nil +} + +type ExportTraceServiceResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExportTraceServiceResponse) Reset() { *m = ExportTraceServiceResponse{} } +func (m *ExportTraceServiceResponse) String() string { return proto.CompactTextString(m) } +func (*ExportTraceServiceResponse) ProtoMessage() {} +func (*ExportTraceServiceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_7027f99caf7ac6a5, []int{3} +} + +func (m *ExportTraceServiceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExportTraceServiceResponse.Unmarshal(m, b) +} +func (m *ExportTraceServiceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExportTraceServiceResponse.Marshal(b, m, deterministic) +} +func (m *ExportTraceServiceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExportTraceServiceResponse.Merge(m, src) +} +func (m *ExportTraceServiceResponse) XXX_Size() int { + return xxx_messageInfo_ExportTraceServiceResponse.Size(m) +} +func (m *ExportTraceServiceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ExportTraceServiceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ExportTraceServiceResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*CurrentLibraryConfig)(nil), "opencensus.proto.agent.trace.v1.CurrentLibraryConfig") + proto.RegisterType((*UpdatedLibraryConfig)(nil), "opencensus.proto.agent.trace.v1.UpdatedLibraryConfig") + proto.RegisterType((*ExportTraceServiceRequest)(nil), "opencensus.proto.agent.trace.v1.ExportTraceServiceRequest") + proto.RegisterType((*ExportTraceServiceResponse)(nil), "opencensus.proto.agent.trace.v1.ExportTraceServiceResponse") +} + +func init() { + proto.RegisterFile("opencensus/proto/agent/trace/v1/trace_service.proto", fileDescriptor_7027f99caf7ac6a5) +} + +var fileDescriptor_7027f99caf7ac6a5 = []byte{ + // 423 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x54, 0xbf, 0x6b, 0xdb, 0x40, + 0x14, 0xee, 0xd9, 0xad, 0x28, 0xe7, 0x2e, 0x15, 0x1d, 0x54, 0x51, 0xb0, 0x11, 0xb4, 0x18, 0x5a, + 0x9d, 0x2a, 0x1b, 0x2f, 0x2e, 0x74, 0xb0, 0x29, 0x74, 0x28, 0xc5, 0xc8, 0xed, 0x92, 0xc5, 0xc8, + 0xd2, 0x8b, 0xa2, 0xc1, 0x77, 0xca, 0xdd, 0x49, 0x24, 0x90, 0x2d, 0x43, 0xf6, 0x0c, 0xf9, 0xc3, + 0xf2, 0x17, 0x05, 0xdd, 0xc9, 0x3f, 0x12, 0x5b, 0x11, 0x24, 0x4b, 0xb6, 0x87, 0xde, 0xf7, 0x7d, + 0xf7, 0xbd, 0x7b, 0xdf, 0x09, 0x0f, 0x59, 0x06, 0x34, 0x02, 0x2a, 0x72, 0xe1, 0x65, 0x9c, 0x49, + 0xe6, 0x85, 0x09, 0x50, 0xe9, 0x49, 0x1e, 0x46, 0xe0, 0x15, 0xbe, 0x2e, 0x16, 0x02, 0x78, 0x91, + 0x46, 0x40, 0x14, 0xc4, 0xec, 0x6e, 0x49, 0xfa, 0x0b, 0x51, 0x24, 0xa2, 0xb0, 0xa4, 0xf0, 0x6d, + 0xb7, 0x46, 0x35, 0x62, 0xab, 0x15, 0xa3, 0xa5, 0xac, 0xae, 0x34, 0xdb, 0xfe, 0xba, 0x07, 0xe7, + 0x20, 0x58, 0xce, 0xb5, 0x83, 0x75, 0x5d, 0x81, 0x3f, 0xef, 0x81, 0xef, 0x7b, 0xad, 0x60, 0xdf, + 0x1a, 0x60, 0x8b, 0x88, 0xd1, 0xe3, 0x34, 0xd1, 0x68, 0xe7, 0x1a, 0xe1, 0x0f, 0xd3, 0x9c, 0x73, + 0xa0, 0xf2, 0x4f, 0xba, 0xe4, 0x21, 0x3f, 0x9f, 0xaa, 0xb6, 0x39, 0xc6, 0xaf, 0x29, 0x8b, 0xc1, + 0x42, 0x3d, 0xd4, 0xef, 0x0c, 0xbe, 0x90, 0x9a, 0xc9, 0xab, 0x71, 0x0a, 0x9f, 0xfc, 0x65, 0x31, + 0x04, 0x8a, 0x63, 0xfe, 0xc4, 0x86, 0x3e, 0xc4, 0x6a, 0xd5, 0xb1, 0xd7, 0x37, 0x46, 0xfe, 0x95, + 0x85, 0x3e, 0x33, 0xa8, 0x58, 0xca, 0xd4, 0xff, 0x2c, 0x0e, 0x25, 0xc4, 0x2f, 0xc7, 0xd4, 0x2d, + 0xc2, 0x1f, 0x7f, 0x9d, 0x65, 0x8c, 0x4b, 0xd5, 0x9d, 0xeb, 0x60, 0x04, 0x70, 0x9a, 0x83, 0x90, + 0xcf, 0x72, 0x36, 0xc2, 0x6f, 0x44, 0x16, 0x52, 0x61, 0xb5, 0x7a, 0xed, 0x7e, 0x67, 0xd0, 0x7d, + 0xc4, 0xd8, 0x3c, 0x0b, 0x69, 0xa0, 0xd1, 0xe6, 0x04, 0xbf, 0x5d, 0x27, 0xc4, 0x6a, 0xd7, 0x1d, + 0xbb, 0xc9, 0x50, 0xe1, 0x93, 0xa0, 0xaa, 0x83, 0x0d, 0xcf, 0xf9, 0x84, 0xed, 0x43, 0x33, 0x89, + 0x8c, 0x51, 0x01, 0x83, 0x9b, 0x16, 0x7e, 0xb7, 0xdb, 0x30, 0x2f, 0xb0, 0x51, 0x6d, 0x62, 0x44, + 0x1a, 0x9e, 0x02, 0x39, 0x94, 0x2a, 0xbb, 0x99, 0x76, 0x68, 0xef, 0xce, 0xab, 0x3e, 0xfa, 0x8e, + 0xcc, 0x2b, 0x84, 0x0d, 0xed, 0xd6, 0x1c, 0x37, 0xea, 0xd4, 0xae, 0xca, 0xfe, 0xf1, 0x24, 0xae, + 0xbe, 0x12, 0xed, 0x64, 0x72, 0x89, 0xb0, 0x93, 0xb2, 0x26, 0x9d, 0xc9, 0xfb, 0x5d, 0x89, 0x59, + 0x89, 0x98, 0xa1, 0xa3, 0xdf, 0x49, 0x2a, 0x4f, 0xf2, 0x65, 0x19, 0x05, 0x4f, 0x93, 0xdd, 0x94, + 0x0a, 0xc9, 0xf3, 0x15, 0x50, 0x19, 0xca, 0x94, 0x51, 0x6f, 0xab, 0xeb, 0xea, 0x17, 0x9c, 0x00, + 0x75, 0x93, 0x87, 0x7f, 0xa8, 0xa5, 0xa1, 0x9a, 0xc3, 0xbb, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcf, + 0x9c, 0x9b, 0xf7, 0xcb, 0x04, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// TraceServiceClient is the client API for TraceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type TraceServiceClient interface { + // After initialization, this RPC must be kept alive for the entire life of + // the application. The agent pushes configs down to applications via a + // stream. + Config(ctx context.Context, opts ...grpc.CallOption) (TraceService_ConfigClient, error) + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + Export(ctx context.Context, opts ...grpc.CallOption) (TraceService_ExportClient, error) +} + +type traceServiceClient struct { + cc *grpc.ClientConn +} + +func NewTraceServiceClient(cc *grpc.ClientConn) TraceServiceClient { + return &traceServiceClient{cc} +} + +func (c *traceServiceClient) Config(ctx context.Context, opts ...grpc.CallOption) (TraceService_ConfigClient, error) { + stream, err := c.cc.NewStream(ctx, &_TraceService_serviceDesc.Streams[0], "/opencensus.proto.agent.trace.v1.TraceService/Config", opts...) + if err != nil { + return nil, err + } + x := &traceServiceConfigClient{stream} + return x, nil +} + +type TraceService_ConfigClient interface { + Send(*CurrentLibraryConfig) error + Recv() (*UpdatedLibraryConfig, error) + grpc.ClientStream +} + +type traceServiceConfigClient struct { + grpc.ClientStream +} + +func (x *traceServiceConfigClient) Send(m *CurrentLibraryConfig) error { + return x.ClientStream.SendMsg(m) +} + +func (x *traceServiceConfigClient) Recv() (*UpdatedLibraryConfig, error) { + m := new(UpdatedLibraryConfig) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *traceServiceClient) Export(ctx context.Context, opts ...grpc.CallOption) (TraceService_ExportClient, error) { + stream, err := c.cc.NewStream(ctx, &_TraceService_serviceDesc.Streams[1], "/opencensus.proto.agent.trace.v1.TraceService/Export", opts...) + if err != nil { + return nil, err + } + x := &traceServiceExportClient{stream} + return x, nil +} + +type TraceService_ExportClient interface { + Send(*ExportTraceServiceRequest) error + Recv() (*ExportTraceServiceResponse, error) + grpc.ClientStream +} + +type traceServiceExportClient struct { + grpc.ClientStream +} + +func (x *traceServiceExportClient) Send(m *ExportTraceServiceRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *traceServiceExportClient) Recv() (*ExportTraceServiceResponse, error) { + m := new(ExportTraceServiceResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// TraceServiceServer is the server API for TraceService service. +type TraceServiceServer interface { + // After initialization, this RPC must be kept alive for the entire life of + // the application. The agent pushes configs down to applications via a + // stream. + Config(TraceService_ConfigServer) error + // For performance reasons, it is recommended to keep this RPC + // alive for the entire life of the application. + Export(TraceService_ExportServer) error +} + +func RegisterTraceServiceServer(s *grpc.Server, srv TraceServiceServer) { + s.RegisterService(&_TraceService_serviceDesc, srv) +} + +func _TraceService_Config_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(TraceServiceServer).Config(&traceServiceConfigServer{stream}) +} + +type TraceService_ConfigServer interface { + Send(*UpdatedLibraryConfig) error + Recv() (*CurrentLibraryConfig, error) + grpc.ServerStream +} + +type traceServiceConfigServer struct { + grpc.ServerStream +} + +func (x *traceServiceConfigServer) Send(m *UpdatedLibraryConfig) error { + return x.ServerStream.SendMsg(m) +} + +func (x *traceServiceConfigServer) Recv() (*CurrentLibraryConfig, error) { + m := new(CurrentLibraryConfig) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func _TraceService_Export_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(TraceServiceServer).Export(&traceServiceExportServer{stream}) +} + +type TraceService_ExportServer interface { + Send(*ExportTraceServiceResponse) error + Recv() (*ExportTraceServiceRequest, error) + grpc.ServerStream +} + +type traceServiceExportServer struct { + grpc.ServerStream +} + +func (x *traceServiceExportServer) Send(m *ExportTraceServiceResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *traceServiceExportServer) Recv() (*ExportTraceServiceRequest, error) { + m := new(ExportTraceServiceRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _TraceService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "opencensus.proto.agent.trace.v1.TraceService", + HandlerType: (*TraceServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "Config", + Handler: _TraceService_Config_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "Export", + Handler: _TraceService_Export_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "opencensus/proto/agent/trace/v1/trace_service.proto", +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go new file mode 100644 index 000000000..bd4b8a827 --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1/trace_service.pb.gw.go @@ -0,0 +1,154 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: opencensus/proto/agent/trace/v1/trace_service.proto + +/* +Package v1 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package v1 + +import ( + "io" + "net/http" + + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray + +func request_TraceService_Export_0(ctx context.Context, marshaler runtime.Marshaler, client TraceServiceClient, req *http.Request, pathParams map[string]string) (TraceService_ExportClient, runtime.ServerMetadata, error) { + var metadata runtime.ServerMetadata + stream, err := client.Export(ctx) + if err != nil { + grpclog.Infof("Failed to start streaming: %v", err) + return nil, metadata, err + } + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, berr + } + dec := marshaler.NewDecoder(newReader()) + handleSend := func() error { + var protoReq ExportTraceServiceRequest + err := dec.Decode(&protoReq) + if err == io.EOF { + return err + } + if err != nil { + grpclog.Infof("Failed to decode request: %v", err) + return err + } + if err := stream.Send(&protoReq); err != nil { + grpclog.Infof("Failed to send request: %v", err) + return err + } + return nil + } + if err := handleSend(); err != nil { + if cerr := stream.CloseSend(); cerr != nil { + grpclog.Infof("Failed to terminate client stream: %v", cerr) + } + if err == io.EOF { + return stream, metadata, nil + } + return nil, metadata, err + } + go func() { + for { + if err := handleSend(); err != nil { + break + } + } + if err := stream.CloseSend(); err != nil { + grpclog.Infof("Failed to terminate client stream: %v", err) + } + }() + header, err := stream.Header() + if err != nil { + grpclog.Infof("Failed to get header from client: %v", err) + return nil, metadata, err + } + metadata.HeaderMD = header + return stream, metadata, nil +} + +// RegisterTraceServiceHandlerFromEndpoint is same as RegisterTraceServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterTraceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterTraceServiceHandler(ctx, mux, conn) +} + +// RegisterTraceServiceHandler registers the http handlers for service TraceService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterTraceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterTraceServiceHandlerClient(ctx, mux, NewTraceServiceClient(conn)) +} + +// RegisterTraceServiceHandlerClient registers the http handlers for service TraceService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "TraceServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "TraceServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "TraceServiceClient" to call the correct interceptors. +func RegisterTraceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client TraceServiceClient) error { + + mux.Handle("POST", pattern_TraceService_Export_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TraceService_Export_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_TraceService_Export_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_TraceService_Export_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "trace"}, "")) +) + +var ( + forward_TraceService_Export_0 = runtime.ForwardResponseStream +) diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1/metrics.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1/metrics.pb.go new file mode 100644 index 000000000..53b8aa99e --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1/metrics.pb.go @@ -0,0 +1,1126 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: opencensus/proto/metrics/v1/metrics.proto + +package v1 + +import ( + fmt "fmt" + v1 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" + proto "github.com/golang/protobuf/proto" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + wrappers "github.com/golang/protobuf/ptypes/wrappers" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// The kind of metric. It describes how the data is reported. +// +// A gauge is an instantaneous measurement of a value. +// +// A cumulative measurement is a value accumulated over a time interval. In +// a time series, cumulative measurements should have the same start time, +// increasing values and increasing end times, until an event resets the +// cumulative value to zero and sets a new start time for the following +// points. +type MetricDescriptor_Type int32 + +const ( + // Do not use this default value. + MetricDescriptor_UNSPECIFIED MetricDescriptor_Type = 0 + // Integer gauge. The value can go both up and down. + MetricDescriptor_GAUGE_INT64 MetricDescriptor_Type = 1 + // Floating point gauge. The value can go both up and down. + MetricDescriptor_GAUGE_DOUBLE MetricDescriptor_Type = 2 + // Distribution gauge measurement. The count and sum can go both up and + // down. Recorded values are always >= 0. + // Used in scenarios like a snapshot of time the current items in a queue + // have spent there. + MetricDescriptor_GAUGE_DISTRIBUTION MetricDescriptor_Type = 3 + // Integer cumulative measurement. The value cannot decrease, if resets + // then the start_time should also be reset. + MetricDescriptor_CUMULATIVE_INT64 MetricDescriptor_Type = 4 + // Floating point cumulative measurement. The value cannot decrease, if + // resets then the start_time should also be reset. Recorded values are + // always >= 0. + MetricDescriptor_CUMULATIVE_DOUBLE MetricDescriptor_Type = 5 + // Distribution cumulative measurement. The count and sum cannot decrease, + // if resets then the start_time should also be reset. + MetricDescriptor_CUMULATIVE_DISTRIBUTION MetricDescriptor_Type = 6 + // Some frameworks implemented Histograms as a summary of observations + // (usually things like request durations and response sizes). While it + // also provides a total count of observations and a sum of all observed + // values, it calculates configurable percentiles over a sliding time + // window. This is not recommended, since it cannot be aggregated. + MetricDescriptor_SUMMARY MetricDescriptor_Type = 7 +) + +var MetricDescriptor_Type_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "GAUGE_INT64", + 2: "GAUGE_DOUBLE", + 3: "GAUGE_DISTRIBUTION", + 4: "CUMULATIVE_INT64", + 5: "CUMULATIVE_DOUBLE", + 6: "CUMULATIVE_DISTRIBUTION", + 7: "SUMMARY", +} + +var MetricDescriptor_Type_value = map[string]int32{ + "UNSPECIFIED": 0, + "GAUGE_INT64": 1, + "GAUGE_DOUBLE": 2, + "GAUGE_DISTRIBUTION": 3, + "CUMULATIVE_INT64": 4, + "CUMULATIVE_DOUBLE": 5, + "CUMULATIVE_DISTRIBUTION": 6, + "SUMMARY": 7, +} + +func (x MetricDescriptor_Type) String() string { + return proto.EnumName(MetricDescriptor_Type_name, int32(x)) +} + +func (MetricDescriptor_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{1, 0} +} + +// Defines a Metric which has one or more timeseries. +type Metric struct { + // The descriptor of the Metric. + // TODO(issue #152): consider only sending the name of descriptor for + // optimization. + MetricDescriptor *MetricDescriptor `protobuf:"bytes,1,opt,name=metric_descriptor,json=metricDescriptor,proto3" json:"metric_descriptor,omitempty"` + // One or more timeseries for a single metric, where each timeseries has + // one or more points. + Timeseries []*TimeSeries `protobuf:"bytes,2,rep,name=timeseries,proto3" json:"timeseries,omitempty"` + // The resource for the metric. If unset, it may be set to a default value + // provided for a sequence of messages in an RPC stream. + Resource *v1.Resource `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Metric) Reset() { *m = Metric{} } +func (m *Metric) String() string { return proto.CompactTextString(m) } +func (*Metric) ProtoMessage() {} +func (*Metric) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{0} +} + +func (m *Metric) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Metric.Unmarshal(m, b) +} +func (m *Metric) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Metric.Marshal(b, m, deterministic) +} +func (m *Metric) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metric.Merge(m, src) +} +func (m *Metric) XXX_Size() int { + return xxx_messageInfo_Metric.Size(m) +} +func (m *Metric) XXX_DiscardUnknown() { + xxx_messageInfo_Metric.DiscardUnknown(m) +} + +var xxx_messageInfo_Metric proto.InternalMessageInfo + +func (m *Metric) GetMetricDescriptor() *MetricDescriptor { + if m != nil { + return m.MetricDescriptor + } + return nil +} + +func (m *Metric) GetTimeseries() []*TimeSeries { + if m != nil { + return m.Timeseries + } + return nil +} + +func (m *Metric) GetResource() *v1.Resource { + if m != nil { + return m.Resource + } + return nil +} + +// Defines a metric type and its schema. +type MetricDescriptor struct { + // The metric type, including its DNS name prefix. It must be unique. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // A detailed description of the metric, which can be used in documentation. + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // The unit in which the metric value is reported. Follows the format + // described by http://unitsofmeasure.org/ucum.html. + Unit string `protobuf:"bytes,3,opt,name=unit,proto3" json:"unit,omitempty"` + Type MetricDescriptor_Type `protobuf:"varint,4,opt,name=type,proto3,enum=opencensus.proto.metrics.v1.MetricDescriptor_Type" json:"type,omitempty"` + // The label keys associated with the metric descriptor. + LabelKeys []*LabelKey `protobuf:"bytes,5,rep,name=label_keys,json=labelKeys,proto3" json:"label_keys,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MetricDescriptor) Reset() { *m = MetricDescriptor{} } +func (m *MetricDescriptor) String() string { return proto.CompactTextString(m) } +func (*MetricDescriptor) ProtoMessage() {} +func (*MetricDescriptor) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{1} +} + +func (m *MetricDescriptor) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MetricDescriptor.Unmarshal(m, b) +} +func (m *MetricDescriptor) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MetricDescriptor.Marshal(b, m, deterministic) +} +func (m *MetricDescriptor) XXX_Merge(src proto.Message) { + xxx_messageInfo_MetricDescriptor.Merge(m, src) +} +func (m *MetricDescriptor) XXX_Size() int { + return xxx_messageInfo_MetricDescriptor.Size(m) +} +func (m *MetricDescriptor) XXX_DiscardUnknown() { + xxx_messageInfo_MetricDescriptor.DiscardUnknown(m) +} + +var xxx_messageInfo_MetricDescriptor proto.InternalMessageInfo + +func (m *MetricDescriptor) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *MetricDescriptor) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *MetricDescriptor) GetUnit() string { + if m != nil { + return m.Unit + } + return "" +} + +func (m *MetricDescriptor) GetType() MetricDescriptor_Type { + if m != nil { + return m.Type + } + return MetricDescriptor_UNSPECIFIED +} + +func (m *MetricDescriptor) GetLabelKeys() []*LabelKey { + if m != nil { + return m.LabelKeys + } + return nil +} + +// Defines a label key associated with a metric descriptor. +type LabelKey struct { + // The key for the label. + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // A human-readable description of what this label key represents. + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LabelKey) Reset() { *m = LabelKey{} } +func (m *LabelKey) String() string { return proto.CompactTextString(m) } +func (*LabelKey) ProtoMessage() {} +func (*LabelKey) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{2} +} + +func (m *LabelKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LabelKey.Unmarshal(m, b) +} +func (m *LabelKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LabelKey.Marshal(b, m, deterministic) +} +func (m *LabelKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_LabelKey.Merge(m, src) +} +func (m *LabelKey) XXX_Size() int { + return xxx_messageInfo_LabelKey.Size(m) +} +func (m *LabelKey) XXX_DiscardUnknown() { + xxx_messageInfo_LabelKey.DiscardUnknown(m) +} + +var xxx_messageInfo_LabelKey proto.InternalMessageInfo + +func (m *LabelKey) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *LabelKey) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +// A collection of data points that describes the time-varying values +// of a metric. +type TimeSeries struct { + // Must be present for cumulative metrics. The time when the cumulative value + // was reset to zero. Exclusive. The cumulative value is over the time interval + // (start_timestamp, timestamp]. If not specified, the backend can use the + // previous recorded value. + StartTimestamp *timestamp.Timestamp `protobuf:"bytes,1,opt,name=start_timestamp,json=startTimestamp,proto3" json:"start_timestamp,omitempty"` + // The set of label values that uniquely identify this timeseries. Applies to + // all points. The order of label values must match that of label keys in the + // metric descriptor. + LabelValues []*LabelValue `protobuf:"bytes,2,rep,name=label_values,json=labelValues,proto3" json:"label_values,omitempty"` + // The data points of this timeseries. Point.value type MUST match the + // MetricDescriptor.type. + Points []*Point `protobuf:"bytes,3,rep,name=points,proto3" json:"points,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TimeSeries) Reset() { *m = TimeSeries{} } +func (m *TimeSeries) String() string { return proto.CompactTextString(m) } +func (*TimeSeries) ProtoMessage() {} +func (*TimeSeries) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{3} +} + +func (m *TimeSeries) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TimeSeries.Unmarshal(m, b) +} +func (m *TimeSeries) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TimeSeries.Marshal(b, m, deterministic) +} +func (m *TimeSeries) XXX_Merge(src proto.Message) { + xxx_messageInfo_TimeSeries.Merge(m, src) +} +func (m *TimeSeries) XXX_Size() int { + return xxx_messageInfo_TimeSeries.Size(m) +} +func (m *TimeSeries) XXX_DiscardUnknown() { + xxx_messageInfo_TimeSeries.DiscardUnknown(m) +} + +var xxx_messageInfo_TimeSeries proto.InternalMessageInfo + +func (m *TimeSeries) GetStartTimestamp() *timestamp.Timestamp { + if m != nil { + return m.StartTimestamp + } + return nil +} + +func (m *TimeSeries) GetLabelValues() []*LabelValue { + if m != nil { + return m.LabelValues + } + return nil +} + +func (m *TimeSeries) GetPoints() []*Point { + if m != nil { + return m.Points + } + return nil +} + +type LabelValue struct { + // The value for the label. + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + // If false the value field is ignored and considered not set. + // This is used to differentiate a missing label from an empty string. + HasValue bool `protobuf:"varint,2,opt,name=has_value,json=hasValue,proto3" json:"has_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LabelValue) Reset() { *m = LabelValue{} } +func (m *LabelValue) String() string { return proto.CompactTextString(m) } +func (*LabelValue) ProtoMessage() {} +func (*LabelValue) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{4} +} + +func (m *LabelValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LabelValue.Unmarshal(m, b) +} +func (m *LabelValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LabelValue.Marshal(b, m, deterministic) +} +func (m *LabelValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_LabelValue.Merge(m, src) +} +func (m *LabelValue) XXX_Size() int { + return xxx_messageInfo_LabelValue.Size(m) +} +func (m *LabelValue) XXX_DiscardUnknown() { + xxx_messageInfo_LabelValue.DiscardUnknown(m) +} + +var xxx_messageInfo_LabelValue proto.InternalMessageInfo + +func (m *LabelValue) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *LabelValue) GetHasValue() bool { + if m != nil { + return m.HasValue + } + return false +} + +// A timestamped measurement. +type Point struct { + // The moment when this point was recorded. Inclusive. + // If not specified, the timestamp will be decided by the backend. + Timestamp *timestamp.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // The actual point value. + // + // Types that are valid to be assigned to Value: + // *Point_Int64Value + // *Point_DoubleValue + // *Point_DistributionValue + // *Point_SummaryValue + Value isPoint_Value `protobuf_oneof:"value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Point) Reset() { *m = Point{} } +func (m *Point) String() string { return proto.CompactTextString(m) } +func (*Point) ProtoMessage() {} +func (*Point) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{5} +} + +func (m *Point) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Point.Unmarshal(m, b) +} +func (m *Point) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Point.Marshal(b, m, deterministic) +} +func (m *Point) XXX_Merge(src proto.Message) { + xxx_messageInfo_Point.Merge(m, src) +} +func (m *Point) XXX_Size() int { + return xxx_messageInfo_Point.Size(m) +} +func (m *Point) XXX_DiscardUnknown() { + xxx_messageInfo_Point.DiscardUnknown(m) +} + +var xxx_messageInfo_Point proto.InternalMessageInfo + +func (m *Point) GetTimestamp() *timestamp.Timestamp { + if m != nil { + return m.Timestamp + } + return nil +} + +type isPoint_Value interface { + isPoint_Value() +} + +type Point_Int64Value struct { + Int64Value int64 `protobuf:"varint,2,opt,name=int64_value,json=int64Value,proto3,oneof"` +} + +type Point_DoubleValue struct { + DoubleValue float64 `protobuf:"fixed64,3,opt,name=double_value,json=doubleValue,proto3,oneof"` +} + +type Point_DistributionValue struct { + DistributionValue *DistributionValue `protobuf:"bytes,4,opt,name=distribution_value,json=distributionValue,proto3,oneof"` +} + +type Point_SummaryValue struct { + SummaryValue *SummaryValue `protobuf:"bytes,5,opt,name=summary_value,json=summaryValue,proto3,oneof"` +} + +func (*Point_Int64Value) isPoint_Value() {} + +func (*Point_DoubleValue) isPoint_Value() {} + +func (*Point_DistributionValue) isPoint_Value() {} + +func (*Point_SummaryValue) isPoint_Value() {} + +func (m *Point) GetValue() isPoint_Value { + if m != nil { + return m.Value + } + return nil +} + +func (m *Point) GetInt64Value() int64 { + if x, ok := m.GetValue().(*Point_Int64Value); ok { + return x.Int64Value + } + return 0 +} + +func (m *Point) GetDoubleValue() float64 { + if x, ok := m.GetValue().(*Point_DoubleValue); ok { + return x.DoubleValue + } + return 0 +} + +func (m *Point) GetDistributionValue() *DistributionValue { + if x, ok := m.GetValue().(*Point_DistributionValue); ok { + return x.DistributionValue + } + return nil +} + +func (m *Point) GetSummaryValue() *SummaryValue { + if x, ok := m.GetValue().(*Point_SummaryValue); ok { + return x.SummaryValue + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Point) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Point_Int64Value)(nil), + (*Point_DoubleValue)(nil), + (*Point_DistributionValue)(nil), + (*Point_SummaryValue)(nil), + } +} + +// Distribution contains summary statistics for a population of values. It +// optionally contains a histogram representing the distribution of those +// values across a set of buckets. +type DistributionValue struct { + // The number of values in the population. Must be non-negative. This value + // must equal the sum of the values in bucket_counts if a histogram is + // provided. + Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` + // The sum of the values in the population. If count is zero then this field + // must be zero. + Sum float64 `protobuf:"fixed64,2,opt,name=sum,proto3" json:"sum,omitempty"` + // The sum of squared deviations from the mean of the values in the + // population. For values x_i this is: + // + // Sum[i=1..n]((x_i - mean)^2) + // + // Knuth, "The Art of Computer Programming", Vol. 2, page 323, 3rd edition + // describes Welford's method for accumulating this sum in one pass. + // + // If count is zero then this field must be zero. + SumOfSquaredDeviation float64 `protobuf:"fixed64,3,opt,name=sum_of_squared_deviation,json=sumOfSquaredDeviation,proto3" json:"sum_of_squared_deviation,omitempty"` + // Don't change bucket boundaries within a TimeSeries if your backend doesn't + // support this. + // TODO(issue #152): consider not required to send bucket options for + // optimization. + BucketOptions *DistributionValue_BucketOptions `protobuf:"bytes,4,opt,name=bucket_options,json=bucketOptions,proto3" json:"bucket_options,omitempty"` + // If the distribution does not have a histogram, then omit this field. + // If there is a histogram, then the sum of the values in the Bucket counts + // must equal the value in the count field of the distribution. + Buckets []*DistributionValue_Bucket `protobuf:"bytes,5,rep,name=buckets,proto3" json:"buckets,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DistributionValue) Reset() { *m = DistributionValue{} } +func (m *DistributionValue) String() string { return proto.CompactTextString(m) } +func (*DistributionValue) ProtoMessage() {} +func (*DistributionValue) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{6} +} + +func (m *DistributionValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DistributionValue.Unmarshal(m, b) +} +func (m *DistributionValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DistributionValue.Marshal(b, m, deterministic) +} +func (m *DistributionValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_DistributionValue.Merge(m, src) +} +func (m *DistributionValue) XXX_Size() int { + return xxx_messageInfo_DistributionValue.Size(m) +} +func (m *DistributionValue) XXX_DiscardUnknown() { + xxx_messageInfo_DistributionValue.DiscardUnknown(m) +} + +var xxx_messageInfo_DistributionValue proto.InternalMessageInfo + +func (m *DistributionValue) GetCount() int64 { + if m != nil { + return m.Count + } + return 0 +} + +func (m *DistributionValue) GetSum() float64 { + if m != nil { + return m.Sum + } + return 0 +} + +func (m *DistributionValue) GetSumOfSquaredDeviation() float64 { + if m != nil { + return m.SumOfSquaredDeviation + } + return 0 +} + +func (m *DistributionValue) GetBucketOptions() *DistributionValue_BucketOptions { + if m != nil { + return m.BucketOptions + } + return nil +} + +func (m *DistributionValue) GetBuckets() []*DistributionValue_Bucket { + if m != nil { + return m.Buckets + } + return nil +} + +// A Distribution may optionally contain a histogram of the values in the +// population. The bucket boundaries for that histogram are described by +// BucketOptions. +// +// If bucket_options has no type, then there is no histogram associated with +// the Distribution. +type DistributionValue_BucketOptions struct { + // Types that are valid to be assigned to Type: + // *DistributionValue_BucketOptions_Explicit_ + Type isDistributionValue_BucketOptions_Type `protobuf_oneof:"type"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DistributionValue_BucketOptions) Reset() { *m = DistributionValue_BucketOptions{} } +func (m *DistributionValue_BucketOptions) String() string { return proto.CompactTextString(m) } +func (*DistributionValue_BucketOptions) ProtoMessage() {} +func (*DistributionValue_BucketOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{6, 0} +} + +func (m *DistributionValue_BucketOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DistributionValue_BucketOptions.Unmarshal(m, b) +} +func (m *DistributionValue_BucketOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DistributionValue_BucketOptions.Marshal(b, m, deterministic) +} +func (m *DistributionValue_BucketOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_DistributionValue_BucketOptions.Merge(m, src) +} +func (m *DistributionValue_BucketOptions) XXX_Size() int { + return xxx_messageInfo_DistributionValue_BucketOptions.Size(m) +} +func (m *DistributionValue_BucketOptions) XXX_DiscardUnknown() { + xxx_messageInfo_DistributionValue_BucketOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_DistributionValue_BucketOptions proto.InternalMessageInfo + +type isDistributionValue_BucketOptions_Type interface { + isDistributionValue_BucketOptions_Type() +} + +type DistributionValue_BucketOptions_Explicit_ struct { + Explicit *DistributionValue_BucketOptions_Explicit `protobuf:"bytes,1,opt,name=explicit,proto3,oneof"` +} + +func (*DistributionValue_BucketOptions_Explicit_) isDistributionValue_BucketOptions_Type() {} + +func (m *DistributionValue_BucketOptions) GetType() isDistributionValue_BucketOptions_Type { + if m != nil { + return m.Type + } + return nil +} + +func (m *DistributionValue_BucketOptions) GetExplicit() *DistributionValue_BucketOptions_Explicit { + if x, ok := m.GetType().(*DistributionValue_BucketOptions_Explicit_); ok { + return x.Explicit + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*DistributionValue_BucketOptions) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*DistributionValue_BucketOptions_Explicit_)(nil), + } +} + +// Specifies a set of buckets with arbitrary upper-bounds. +// This defines size(bounds) + 1 (= N) buckets. The boundaries for bucket +// index i are: +// +// [0, bucket_bounds[i]) for i == 0 +// [bucket_bounds[i-1], bucket_bounds[i]) for 0 < i < N-1 +// [bucket_bounds[i], +infinity) for i == N-1 +type DistributionValue_BucketOptions_Explicit struct { + // The values must be strictly increasing and > 0. + Bounds []float64 `protobuf:"fixed64,1,rep,packed,name=bounds,proto3" json:"bounds,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DistributionValue_BucketOptions_Explicit) Reset() { + *m = DistributionValue_BucketOptions_Explicit{} +} +func (m *DistributionValue_BucketOptions_Explicit) String() string { return proto.CompactTextString(m) } +func (*DistributionValue_BucketOptions_Explicit) ProtoMessage() {} +func (*DistributionValue_BucketOptions_Explicit) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{6, 0, 0} +} + +func (m *DistributionValue_BucketOptions_Explicit) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DistributionValue_BucketOptions_Explicit.Unmarshal(m, b) +} +func (m *DistributionValue_BucketOptions_Explicit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DistributionValue_BucketOptions_Explicit.Marshal(b, m, deterministic) +} +func (m *DistributionValue_BucketOptions_Explicit) XXX_Merge(src proto.Message) { + xxx_messageInfo_DistributionValue_BucketOptions_Explicit.Merge(m, src) +} +func (m *DistributionValue_BucketOptions_Explicit) XXX_Size() int { + return xxx_messageInfo_DistributionValue_BucketOptions_Explicit.Size(m) +} +func (m *DistributionValue_BucketOptions_Explicit) XXX_DiscardUnknown() { + xxx_messageInfo_DistributionValue_BucketOptions_Explicit.DiscardUnknown(m) +} + +var xxx_messageInfo_DistributionValue_BucketOptions_Explicit proto.InternalMessageInfo + +func (m *DistributionValue_BucketOptions_Explicit) GetBounds() []float64 { + if m != nil { + return m.Bounds + } + return nil +} + +type DistributionValue_Bucket struct { + // The number of values in each bucket of the histogram, as described in + // bucket_bounds. + Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"` + // If the distribution does not have a histogram, then omit this field. + Exemplar *DistributionValue_Exemplar `protobuf:"bytes,2,opt,name=exemplar,proto3" json:"exemplar,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DistributionValue_Bucket) Reset() { *m = DistributionValue_Bucket{} } +func (m *DistributionValue_Bucket) String() string { return proto.CompactTextString(m) } +func (*DistributionValue_Bucket) ProtoMessage() {} +func (*DistributionValue_Bucket) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{6, 1} +} + +func (m *DistributionValue_Bucket) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DistributionValue_Bucket.Unmarshal(m, b) +} +func (m *DistributionValue_Bucket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DistributionValue_Bucket.Marshal(b, m, deterministic) +} +func (m *DistributionValue_Bucket) XXX_Merge(src proto.Message) { + xxx_messageInfo_DistributionValue_Bucket.Merge(m, src) +} +func (m *DistributionValue_Bucket) XXX_Size() int { + return xxx_messageInfo_DistributionValue_Bucket.Size(m) +} +func (m *DistributionValue_Bucket) XXX_DiscardUnknown() { + xxx_messageInfo_DistributionValue_Bucket.DiscardUnknown(m) +} + +var xxx_messageInfo_DistributionValue_Bucket proto.InternalMessageInfo + +func (m *DistributionValue_Bucket) GetCount() int64 { + if m != nil { + return m.Count + } + return 0 +} + +func (m *DistributionValue_Bucket) GetExemplar() *DistributionValue_Exemplar { + if m != nil { + return m.Exemplar + } + return nil +} + +// Exemplars are example points that may be used to annotate aggregated +// Distribution values. They are metadata that gives information about a +// particular value added to a Distribution bucket. +type DistributionValue_Exemplar struct { + // Value of the exemplar point. It determines which bucket the exemplar + // belongs to. + Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` + // The observation (sampling) time of the above value. + Timestamp *timestamp.Timestamp `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // Contextual information about the example value. + Attachments map[string]string `protobuf:"bytes,3,rep,name=attachments,proto3" json:"attachments,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DistributionValue_Exemplar) Reset() { *m = DistributionValue_Exemplar{} } +func (m *DistributionValue_Exemplar) String() string { return proto.CompactTextString(m) } +func (*DistributionValue_Exemplar) ProtoMessage() {} +func (*DistributionValue_Exemplar) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{6, 2} +} + +func (m *DistributionValue_Exemplar) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DistributionValue_Exemplar.Unmarshal(m, b) +} +func (m *DistributionValue_Exemplar) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DistributionValue_Exemplar.Marshal(b, m, deterministic) +} +func (m *DistributionValue_Exemplar) XXX_Merge(src proto.Message) { + xxx_messageInfo_DistributionValue_Exemplar.Merge(m, src) +} +func (m *DistributionValue_Exemplar) XXX_Size() int { + return xxx_messageInfo_DistributionValue_Exemplar.Size(m) +} +func (m *DistributionValue_Exemplar) XXX_DiscardUnknown() { + xxx_messageInfo_DistributionValue_Exemplar.DiscardUnknown(m) +} + +var xxx_messageInfo_DistributionValue_Exemplar proto.InternalMessageInfo + +func (m *DistributionValue_Exemplar) GetValue() float64 { + if m != nil { + return m.Value + } + return 0 +} + +func (m *DistributionValue_Exemplar) GetTimestamp() *timestamp.Timestamp { + if m != nil { + return m.Timestamp + } + return nil +} + +func (m *DistributionValue_Exemplar) GetAttachments() map[string]string { + if m != nil { + return m.Attachments + } + return nil +} + +// The start_timestamp only applies to the count and sum in the SummaryValue. +type SummaryValue struct { + // The total number of recorded values since start_time. Optional since + // some systems don't expose this. + Count *wrappers.Int64Value `protobuf:"bytes,1,opt,name=count,proto3" json:"count,omitempty"` + // The total sum of recorded values since start_time. Optional since some + // systems don't expose this. If count is zero then this field must be zero. + // This field must be unset if the sum is not available. + Sum *wrappers.DoubleValue `protobuf:"bytes,2,opt,name=sum,proto3" json:"sum,omitempty"` + // Values calculated over an arbitrary time window. + Snapshot *SummaryValue_Snapshot `protobuf:"bytes,3,opt,name=snapshot,proto3" json:"snapshot,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SummaryValue) Reset() { *m = SummaryValue{} } +func (m *SummaryValue) String() string { return proto.CompactTextString(m) } +func (*SummaryValue) ProtoMessage() {} +func (*SummaryValue) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{7} +} + +func (m *SummaryValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SummaryValue.Unmarshal(m, b) +} +func (m *SummaryValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SummaryValue.Marshal(b, m, deterministic) +} +func (m *SummaryValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_SummaryValue.Merge(m, src) +} +func (m *SummaryValue) XXX_Size() int { + return xxx_messageInfo_SummaryValue.Size(m) +} +func (m *SummaryValue) XXX_DiscardUnknown() { + xxx_messageInfo_SummaryValue.DiscardUnknown(m) +} + +var xxx_messageInfo_SummaryValue proto.InternalMessageInfo + +func (m *SummaryValue) GetCount() *wrappers.Int64Value { + if m != nil { + return m.Count + } + return nil +} + +func (m *SummaryValue) GetSum() *wrappers.DoubleValue { + if m != nil { + return m.Sum + } + return nil +} + +func (m *SummaryValue) GetSnapshot() *SummaryValue_Snapshot { + if m != nil { + return m.Snapshot + } + return nil +} + +// The values in this message can be reset at arbitrary unknown times, with +// the requirement that all of them are reset at the same time. +type SummaryValue_Snapshot struct { + // The number of values in the snapshot. Optional since some systems don't + // expose this. + Count *wrappers.Int64Value `protobuf:"bytes,1,opt,name=count,proto3" json:"count,omitempty"` + // The sum of values in the snapshot. Optional since some systems don't + // expose this. If count is zero then this field must be zero or not set + // (if not supported). + Sum *wrappers.DoubleValue `protobuf:"bytes,2,opt,name=sum,proto3" json:"sum,omitempty"` + // A list of values at different percentiles of the distribution calculated + // from the current snapshot. The percentiles must be strictly increasing. + PercentileValues []*SummaryValue_Snapshot_ValueAtPercentile `protobuf:"bytes,3,rep,name=percentile_values,json=percentileValues,proto3" json:"percentile_values,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SummaryValue_Snapshot) Reset() { *m = SummaryValue_Snapshot{} } +func (m *SummaryValue_Snapshot) String() string { return proto.CompactTextString(m) } +func (*SummaryValue_Snapshot) ProtoMessage() {} +func (*SummaryValue_Snapshot) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{7, 0} +} + +func (m *SummaryValue_Snapshot) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SummaryValue_Snapshot.Unmarshal(m, b) +} +func (m *SummaryValue_Snapshot) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SummaryValue_Snapshot.Marshal(b, m, deterministic) +} +func (m *SummaryValue_Snapshot) XXX_Merge(src proto.Message) { + xxx_messageInfo_SummaryValue_Snapshot.Merge(m, src) +} +func (m *SummaryValue_Snapshot) XXX_Size() int { + return xxx_messageInfo_SummaryValue_Snapshot.Size(m) +} +func (m *SummaryValue_Snapshot) XXX_DiscardUnknown() { + xxx_messageInfo_SummaryValue_Snapshot.DiscardUnknown(m) +} + +var xxx_messageInfo_SummaryValue_Snapshot proto.InternalMessageInfo + +func (m *SummaryValue_Snapshot) GetCount() *wrappers.Int64Value { + if m != nil { + return m.Count + } + return nil +} + +func (m *SummaryValue_Snapshot) GetSum() *wrappers.DoubleValue { + if m != nil { + return m.Sum + } + return nil +} + +func (m *SummaryValue_Snapshot) GetPercentileValues() []*SummaryValue_Snapshot_ValueAtPercentile { + if m != nil { + return m.PercentileValues + } + return nil +} + +// Represents the value at a given percentile of a distribution. +type SummaryValue_Snapshot_ValueAtPercentile struct { + // The percentile of a distribution. Must be in the interval + // (0.0, 100.0]. + Percentile float64 `protobuf:"fixed64,1,opt,name=percentile,proto3" json:"percentile,omitempty"` + // The value at the given percentile of a distribution. + Value float64 `protobuf:"fixed64,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SummaryValue_Snapshot_ValueAtPercentile) Reset() { + *m = SummaryValue_Snapshot_ValueAtPercentile{} +} +func (m *SummaryValue_Snapshot_ValueAtPercentile) String() string { return proto.CompactTextString(m) } +func (*SummaryValue_Snapshot_ValueAtPercentile) ProtoMessage() {} +func (*SummaryValue_Snapshot_ValueAtPercentile) Descriptor() ([]byte, []int) { + return fileDescriptor_0ee3deb72053811a, []int{7, 0, 0} +} + +func (m *SummaryValue_Snapshot_ValueAtPercentile) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SummaryValue_Snapshot_ValueAtPercentile.Unmarshal(m, b) +} +func (m *SummaryValue_Snapshot_ValueAtPercentile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SummaryValue_Snapshot_ValueAtPercentile.Marshal(b, m, deterministic) +} +func (m *SummaryValue_Snapshot_ValueAtPercentile) XXX_Merge(src proto.Message) { + xxx_messageInfo_SummaryValue_Snapshot_ValueAtPercentile.Merge(m, src) +} +func (m *SummaryValue_Snapshot_ValueAtPercentile) XXX_Size() int { + return xxx_messageInfo_SummaryValue_Snapshot_ValueAtPercentile.Size(m) +} +func (m *SummaryValue_Snapshot_ValueAtPercentile) XXX_DiscardUnknown() { + xxx_messageInfo_SummaryValue_Snapshot_ValueAtPercentile.DiscardUnknown(m) +} + +var xxx_messageInfo_SummaryValue_Snapshot_ValueAtPercentile proto.InternalMessageInfo + +func (m *SummaryValue_Snapshot_ValueAtPercentile) GetPercentile() float64 { + if m != nil { + return m.Percentile + } + return 0 +} + +func (m *SummaryValue_Snapshot_ValueAtPercentile) GetValue() float64 { + if m != nil { + return m.Value + } + return 0 +} + +func init() { + proto.RegisterEnum("opencensus.proto.metrics.v1.MetricDescriptor_Type", MetricDescriptor_Type_name, MetricDescriptor_Type_value) + proto.RegisterType((*Metric)(nil), "opencensus.proto.metrics.v1.Metric") + proto.RegisterType((*MetricDescriptor)(nil), "opencensus.proto.metrics.v1.MetricDescriptor") + proto.RegisterType((*LabelKey)(nil), "opencensus.proto.metrics.v1.LabelKey") + proto.RegisterType((*TimeSeries)(nil), "opencensus.proto.metrics.v1.TimeSeries") + proto.RegisterType((*LabelValue)(nil), "opencensus.proto.metrics.v1.LabelValue") + proto.RegisterType((*Point)(nil), "opencensus.proto.metrics.v1.Point") + proto.RegisterType((*DistributionValue)(nil), "opencensus.proto.metrics.v1.DistributionValue") + proto.RegisterType((*DistributionValue_BucketOptions)(nil), "opencensus.proto.metrics.v1.DistributionValue.BucketOptions") + proto.RegisterType((*DistributionValue_BucketOptions_Explicit)(nil), "opencensus.proto.metrics.v1.DistributionValue.BucketOptions.Explicit") + proto.RegisterType((*DistributionValue_Bucket)(nil), "opencensus.proto.metrics.v1.DistributionValue.Bucket") + proto.RegisterType((*DistributionValue_Exemplar)(nil), "opencensus.proto.metrics.v1.DistributionValue.Exemplar") + proto.RegisterMapType((map[string]string)(nil), "opencensus.proto.metrics.v1.DistributionValue.Exemplar.AttachmentsEntry") + proto.RegisterType((*SummaryValue)(nil), "opencensus.proto.metrics.v1.SummaryValue") + proto.RegisterType((*SummaryValue_Snapshot)(nil), "opencensus.proto.metrics.v1.SummaryValue.Snapshot") + proto.RegisterType((*SummaryValue_Snapshot_ValueAtPercentile)(nil), "opencensus.proto.metrics.v1.SummaryValue.Snapshot.ValueAtPercentile") +} + +func init() { + proto.RegisterFile("opencensus/proto/metrics/v1/metrics.proto", fileDescriptor_0ee3deb72053811a) +} + +var fileDescriptor_0ee3deb72053811a = []byte{ + // 1098 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xdd, 0x6e, 0x1b, 0xc5, + 0x17, 0xcf, 0xda, 0x8e, 0xe3, 0x9c, 0x75, 0xdb, 0xf5, 0xa8, 0xed, 0xdf, 0xda, 0xfc, 0x15, 0xc2, + 0x22, 0x20, 0x15, 0xca, 0x5a, 0x31, 0xa5, 0xad, 0x2a, 0x54, 0x14, 0xc7, 0x6e, 0x62, 0xc8, 0x87, + 0x35, 0xb6, 0x2b, 0xd1, 0x1b, 0x6b, 0xbd, 0x9e, 0x24, 0x4b, 0xbc, 0x1f, 0xdd, 0x99, 0x35, 0xf8, + 0x05, 0x78, 0x04, 0xae, 0xb9, 0x45, 0x3c, 0x07, 0x57, 0x3c, 0x01, 0x4f, 0x81, 0x78, 0x03, 0xb4, + 0x33, 0xb3, 0x1f, 0x89, 0xc1, 0xd4, 0x45, 0xe2, 0xee, 0x9c, 0x33, 0xe7, 0xfc, 0xfc, 0x3b, 0x9f, + 0x5e, 0x78, 0xe4, 0x07, 0xc4, 0xb3, 0x89, 0x47, 0x23, 0xda, 0x08, 0x42, 0x9f, 0xf9, 0x0d, 0x97, + 0xb0, 0xd0, 0xb1, 0x69, 0x63, 0xb6, 0x9f, 0x88, 0x26, 0x7f, 0x40, 0x5b, 0x99, 0xab, 0xb0, 0x98, + 0xc9, 0xfb, 0x6c, 0x5f, 0x7f, 0xef, 0xd2, 0xf7, 0x2f, 0xa7, 0x44, 0x60, 0x8c, 0xa3, 0x8b, 0x06, + 0x73, 0x5c, 0x42, 0x99, 0xe5, 0x06, 0xc2, 0x57, 0xdf, 0xbe, 0xed, 0xf0, 0x6d, 0x68, 0x05, 0x01, + 0x09, 0x25, 0x96, 0xfe, 0xc9, 0x02, 0x91, 0x90, 0x50, 0x3f, 0x0a, 0x6d, 0x12, 0x33, 0x49, 0x64, + 0xe1, 0x6c, 0xfc, 0xa1, 0x40, 0xf9, 0x94, 0xff, 0x38, 0x7a, 0x0d, 0x35, 0x41, 0x63, 0x34, 0x21, + 0xd4, 0x0e, 0x9d, 0x80, 0xf9, 0x61, 0x5d, 0xd9, 0x51, 0x76, 0xd5, 0xe6, 0x9e, 0xb9, 0x84, 0xb1, + 0x29, 0xe2, 0xdb, 0x69, 0x10, 0xd6, 0xdc, 0x5b, 0x16, 0x74, 0x04, 0xc0, 0xd3, 0x20, 0xa1, 0x43, + 0x68, 0xbd, 0xb0, 0x53, 0xdc, 0x55, 0x9b, 0x1f, 0x2f, 0x05, 0x1d, 0x38, 0x2e, 0xe9, 0x73, 0x77, + 0x9c, 0x0b, 0x45, 0x2d, 0xa8, 0x24, 0x19, 0xd4, 0x8b, 0x9c, 0xdb, 0x47, 0x8b, 0x30, 0x69, 0x8e, + 0xb3, 0x7d, 0x13, 0x4b, 0x19, 0xa7, 0x71, 0xc6, 0x0f, 0x45, 0xd0, 0x6e, 0x73, 0x46, 0x08, 0x4a, + 0x9e, 0xe5, 0x12, 0x9e, 0xf0, 0x26, 0xe6, 0x32, 0xda, 0x01, 0x35, 0x29, 0x85, 0xe3, 0x7b, 0xf5, + 0x02, 0x7f, 0xca, 0x9b, 0xe2, 0xa8, 0xc8, 0x73, 0x18, 0xa7, 0xb2, 0x89, 0xb9, 0x8c, 0x5e, 0x42, + 0x89, 0xcd, 0x03, 0x52, 0x2f, 0xed, 0x28, 0xbb, 0x77, 0x9b, 0xcd, 0x95, 0x4a, 0x67, 0x0e, 0xe6, + 0x01, 0xc1, 0x3c, 0x1e, 0xb5, 0x01, 0xa6, 0xd6, 0x98, 0x4c, 0x47, 0xd7, 0x64, 0x4e, 0xeb, 0xeb, + 0xbc, 0x66, 0x1f, 0x2e, 0x45, 0x3b, 0x89, 0xdd, 0xbf, 0x22, 0x73, 0xbc, 0x39, 0x95, 0x12, 0x35, + 0x7e, 0x52, 0xa0, 0x14, 0x83, 0xa2, 0x7b, 0xa0, 0x0e, 0xcf, 0xfa, 0xbd, 0xce, 0x61, 0xf7, 0x65, + 0xb7, 0xd3, 0xd6, 0xd6, 0x62, 0xc3, 0xd1, 0xc1, 0xf0, 0xa8, 0x33, 0xea, 0x9e, 0x0d, 0x9e, 0x3c, + 0xd6, 0x14, 0xa4, 0x41, 0x55, 0x18, 0xda, 0xe7, 0xc3, 0xd6, 0x49, 0x47, 0x2b, 0xa0, 0x87, 0x80, + 0xa4, 0xa5, 0xdb, 0x1f, 0xe0, 0x6e, 0x6b, 0x38, 0xe8, 0x9e, 0x9f, 0x69, 0x45, 0x74, 0x1f, 0xb4, + 0xc3, 0xe1, 0xe9, 0xf0, 0xe4, 0x60, 0xd0, 0x7d, 0x95, 0xc4, 0x97, 0xd0, 0x03, 0xa8, 0xe5, 0xac, + 0x12, 0x64, 0x1d, 0x6d, 0xc1, 0xff, 0xf2, 0xe6, 0x3c, 0x52, 0x19, 0xa9, 0xb0, 0xd1, 0x1f, 0x9e, + 0x9e, 0x1e, 0xe0, 0xaf, 0xb5, 0x0d, 0xe3, 0x05, 0x54, 0x92, 0x14, 0x90, 0x06, 0xc5, 0x6b, 0x32, + 0x97, 0xed, 0x88, 0xc5, 0x7f, 0xee, 0x86, 0xf1, 0x9b, 0x02, 0x90, 0xcd, 0x0d, 0x3a, 0x84, 0x7b, + 0x94, 0x59, 0x21, 0x1b, 0xa5, 0x1b, 0x24, 0xc7, 0x59, 0x37, 0xc5, 0x0a, 0x99, 0xc9, 0x0a, 0xf1, + 0x69, 0xe3, 0x1e, 0xf8, 0x2e, 0x0f, 0x49, 0x75, 0xf4, 0x25, 0x54, 0x45, 0x17, 0x66, 0xd6, 0x34, + 0x7a, 0xcb, 0xd9, 0xe5, 0x49, 0xbc, 0x8a, 0xfd, 0xb1, 0x3a, 0x4d, 0x65, 0x8a, 0x9e, 0x43, 0x39, + 0xf0, 0x1d, 0x8f, 0xd1, 0x7a, 0x91, 0xa3, 0x18, 0x4b, 0x51, 0x7a, 0xb1, 0x2b, 0x96, 0x11, 0xc6, + 0x17, 0x00, 0x19, 0x2c, 0xba, 0x0f, 0xeb, 0x9c, 0x8f, 0xac, 0x8f, 0x50, 0xd0, 0x16, 0x6c, 0x5e, + 0x59, 0x54, 0x30, 0xe5, 0xf5, 0xa9, 0xe0, 0xca, 0x95, 0x45, 0x79, 0x88, 0xf1, 0x4b, 0x01, 0xd6, + 0x39, 0x24, 0x7a, 0x06, 0x9b, 0xab, 0x54, 0x24, 0x73, 0x46, 0xef, 0x83, 0xea, 0x78, 0xec, 0xc9, + 0xe3, 0xdc, 0x4f, 0x14, 0x8f, 0xd7, 0x30, 0x70, 0xa3, 0x60, 0xf6, 0x01, 0x54, 0x27, 0x7e, 0x34, + 0x9e, 0x12, 0xe9, 0x13, 0x6f, 0x86, 0x72, 0xbc, 0x86, 0x55, 0x61, 0x15, 0x4e, 0x23, 0x40, 0x13, + 0x87, 0xb2, 0xd0, 0x19, 0x47, 0x71, 0xe3, 0xa4, 0x6b, 0x89, 0x53, 0x31, 0x97, 0x16, 0xa5, 0x9d, + 0x0b, 0xe3, 0x58, 0xc7, 0x6b, 0xb8, 0x36, 0xb9, 0x6d, 0x44, 0x3d, 0xb8, 0x43, 0x23, 0xd7, 0xb5, + 0xc2, 0xb9, 0xc4, 0x5e, 0xe7, 0xd8, 0x8f, 0x96, 0x62, 0xf7, 0x45, 0x44, 0x02, 0x5b, 0xa5, 0x39, + 0xbd, 0xb5, 0x21, 0x2b, 0x6e, 0xfc, 0x5a, 0x86, 0xda, 0x02, 0x8b, 0xb8, 0x21, 0xb6, 0x1f, 0x79, + 0x8c, 0xd7, 0xb3, 0x88, 0x85, 0x12, 0x0f, 0x31, 0x8d, 0x5c, 0x5e, 0x27, 0x05, 0xc7, 0x22, 0x7a, + 0x0a, 0x75, 0x1a, 0xb9, 0x23, 0xff, 0x62, 0x44, 0xdf, 0x44, 0x56, 0x48, 0x26, 0xa3, 0x09, 0x99, + 0x39, 0x16, 0x9f, 0x68, 0x5e, 0x2a, 0xfc, 0x80, 0x46, 0xee, 0xf9, 0x45, 0x5f, 0xbc, 0xb6, 0x93, + 0x47, 0x64, 0xc3, 0xdd, 0x71, 0x64, 0x5f, 0x13, 0x36, 0xf2, 0xf9, 0xb0, 0x53, 0x59, 0xae, 0xcf, + 0x57, 0x2b, 0x97, 0xd9, 0xe2, 0x20, 0xe7, 0x02, 0x03, 0xdf, 0x19, 0xe7, 0x55, 0x74, 0x0e, 0x1b, + 0xc2, 0x90, 0xdc, 0x9b, 0xcf, 0xde, 0x09, 0x1d, 0x27, 0x28, 0xfa, 0x8f, 0x0a, 0xdc, 0xb9, 0xf1, + 0x8b, 0xc8, 0x86, 0x0a, 0xf9, 0x2e, 0x98, 0x3a, 0xb6, 0xc3, 0xe4, 0xec, 0x75, 0xfe, 0x4d, 0x06, + 0x66, 0x47, 0x82, 0x1d, 0xaf, 0xe1, 0x14, 0x58, 0x37, 0xa0, 0x92, 0xd8, 0xd1, 0x43, 0x28, 0x8f, + 0xfd, 0xc8, 0x9b, 0xd0, 0xba, 0xb2, 0x53, 0xdc, 0x55, 0xb0, 0xd4, 0x5a, 0x65, 0x71, 0xa6, 0x75, + 0x0a, 0x65, 0x81, 0xf8, 0x37, 0x3d, 0xec, 0xc7, 0x84, 0x89, 0x1b, 0x4c, 0xad, 0x90, 0x37, 0x52, + 0x6d, 0x3e, 0x5d, 0x91, 0x70, 0x47, 0x86, 0xe3, 0x14, 0x48, 0xff, 0xbe, 0x10, 0x33, 0x14, 0xca, + 0xcd, 0x65, 0x56, 0x92, 0x65, 0xbe, 0xb1, 0xa5, 0x85, 0x55, 0xb6, 0xf4, 0x1b, 0x50, 0x2d, 0xc6, + 0x2c, 0xfb, 0xca, 0x25, 0xd9, 0xad, 0x39, 0x7e, 0x47, 0xd2, 0xe6, 0x41, 0x06, 0xd5, 0xf1, 0x58, + 0x38, 0xc7, 0x79, 0x70, 0xfd, 0x05, 0x68, 0xb7, 0x1d, 0xfe, 0xe2, 0x74, 0xa7, 0x19, 0x16, 0x72, + 0xe7, 0xea, 0x79, 0xe1, 0x99, 0x62, 0xfc, 0x5e, 0x84, 0x6a, 0x7e, 0xef, 0xd0, 0x7e, 0xbe, 0x09, + 0x6a, 0x73, 0x6b, 0x21, 0xe5, 0x6e, 0x7a, 0x6b, 0x92, 0x0e, 0x99, 0xd9, 0x96, 0xa9, 0xcd, 0xff, + 0x2f, 0x04, 0xb4, 0xb3, 0xc3, 0x23, 0x76, 0xf0, 0x0c, 0x2a, 0xd4, 0xb3, 0x02, 0x7a, 0xe5, 0x33, + 0xf9, 0x0d, 0xd1, 0x7c, 0xeb, 0xbb, 0x60, 0xf6, 0x65, 0x24, 0x4e, 0x31, 0xf4, 0x9f, 0x0b, 0x50, + 0x49, 0xcc, 0xff, 0x05, 0xff, 0x37, 0x50, 0x0b, 0x48, 0x68, 0x13, 0x8f, 0x39, 0xc9, 0x99, 0x4d, + 0xba, 0xdc, 0x5e, 0x3d, 0x11, 0x93, 0xab, 0x07, 0xac, 0x97, 0x42, 0x62, 0x2d, 0x83, 0x17, 0xff, + 0x5c, 0x7a, 0x17, 0x6a, 0x0b, 0x6e, 0x68, 0x1b, 0x20, 0x73, 0x94, 0xc3, 0x9b, 0xb3, 0xdc, 0xec, + 0x7a, 0x32, 0xd7, 0xad, 0x19, 0x6c, 0x3b, 0xfe, 0x32, 0x9a, 0xad, 0xaa, 0xf8, 0x2a, 0xa2, 0xbd, + 0xf8, 0xa1, 0xa7, 0xbc, 0x6e, 0x5f, 0x3a, 0xec, 0x2a, 0x1a, 0x9b, 0xb6, 0xef, 0x36, 0x44, 0xcc, + 0x9e, 0xe3, 0x51, 0x16, 0x46, 0xf1, 0xcc, 0xf1, 0xeb, 0xd8, 0xc8, 0xe0, 0xf6, 0xc4, 0x27, 0xef, + 0x25, 0xf1, 0xf6, 0x2e, 0xf3, 0x9f, 0xe0, 0xe3, 0x32, 0x7f, 0xf8, 0xf4, 0xcf, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x8e, 0xfc, 0xd7, 0x46, 0xa8, 0x0b, 0x00, 0x00, +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1/resource.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1/resource.pb.go new file mode 100644 index 000000000..38faa9fdf --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1/resource.pb.go @@ -0,0 +1,99 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: opencensus/proto/resource/v1/resource.proto + +package v1 + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Resource information. +type Resource struct { + // Type identifier for the resource. + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + // Set of labels that describe the resource. + Labels map[string]string `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Resource) Reset() { *m = Resource{} } +func (m *Resource) String() string { return proto.CompactTextString(m) } +func (*Resource) ProtoMessage() {} +func (*Resource) Descriptor() ([]byte, []int) { + return fileDescriptor_584700775a2fc762, []int{0} +} + +func (m *Resource) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Resource.Unmarshal(m, b) +} +func (m *Resource) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Resource.Marshal(b, m, deterministic) +} +func (m *Resource) XXX_Merge(src proto.Message) { + xxx_messageInfo_Resource.Merge(m, src) +} +func (m *Resource) XXX_Size() int { + return xxx_messageInfo_Resource.Size(m) +} +func (m *Resource) XXX_DiscardUnknown() { + xxx_messageInfo_Resource.DiscardUnknown(m) +} + +var xxx_messageInfo_Resource proto.InternalMessageInfo + +func (m *Resource) GetType() string { + if m != nil { + return m.Type + } + return "" +} + +func (m *Resource) GetLabels() map[string]string { + if m != nil { + return m.Labels + } + return nil +} + +func init() { + proto.RegisterType((*Resource)(nil), "opencensus.proto.resource.v1.Resource") + proto.RegisterMapType((map[string]string)(nil), "opencensus.proto.resource.v1.Resource.LabelsEntry") +} + +func init() { + proto.RegisterFile("opencensus/proto/resource/v1/resource.proto", fileDescriptor_584700775a2fc762) +} + +var fileDescriptor_584700775a2fc762 = []byte{ + // 234 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xce, 0x2f, 0x48, 0xcd, + 0x4b, 0x4e, 0xcd, 0x2b, 0x2e, 0x2d, 0xd6, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0xd7, 0x2f, 0x4a, 0x2d, + 0xce, 0x2f, 0x2d, 0x4a, 0x4e, 0xd5, 0x2f, 0x33, 0x84, 0xb3, 0xf5, 0xc0, 0x52, 0x42, 0x32, 0x08, + 0xc5, 0x10, 0x11, 0x3d, 0xb8, 0x82, 0x32, 0x43, 0xa5, 0xa5, 0x8c, 0x5c, 0x1c, 0x41, 0x50, 0xbe, + 0x90, 0x10, 0x17, 0x4b, 0x49, 0x65, 0x41, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x98, + 0x2d, 0xe4, 0xc5, 0xc5, 0x96, 0x93, 0x98, 0x94, 0x9a, 0x53, 0x2c, 0xc1, 0xa4, 0xc0, 0xac, 0xc1, + 0x6d, 0x64, 0xa4, 0x87, 0xcf, 0x3c, 0x3d, 0x98, 0x59, 0x7a, 0x3e, 0x60, 0x4d, 0xae, 0x79, 0x25, + 0x45, 0x95, 0x41, 0x50, 0x13, 0xa4, 0x2c, 0xb9, 0xb8, 0x91, 0x84, 0x85, 0x04, 0xb8, 0x98, 0xb3, + 0x53, 0x2b, 0xa1, 0xb6, 0x81, 0x98, 0x42, 0x22, 0x5c, 0xac, 0x65, 0x89, 0x39, 0xa5, 0xa9, 0x12, + 0x4c, 0x60, 0x31, 0x08, 0xc7, 0x8a, 0xc9, 0x82, 0xd1, 0xa9, 0x92, 0x4b, 0x3e, 0x33, 0x1f, 0xaf, + 0xd5, 0x4e, 0xbc, 0x30, 0xbb, 0x03, 0x40, 0x52, 0x01, 0x8c, 0x51, 0xae, 0xe9, 0x99, 0x25, 0x19, + 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x10, 0x5d, 0xba, 0x99, 0x79, 0xc5, 0x25, 0x45, 0xa5, + 0xb9, 0xa9, 0x79, 0x25, 0x89, 0x25, 0x99, 0xf9, 0x79, 0xfa, 0x08, 0x03, 0x75, 0x21, 0x01, 0x99, + 0x9e, 0x9a, 0xa7, 0x9b, 0x8e, 0x12, 0x9e, 0x49, 0x6c, 0x60, 0x19, 0x63, 0x40, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x8e, 0x11, 0xaf, 0xda, 0x76, 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go new file mode 100644 index 000000000..4de05355a --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace.pb.go @@ -0,0 +1,1543 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: opencensus/proto/trace/v1/trace.proto + +package v1 + +import ( + fmt "fmt" + v1 "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" + proto "github.com/golang/protobuf/proto" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + wrappers "github.com/golang/protobuf/ptypes/wrappers" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Type of span. Can be used to specify additional relationships between spans +// in addition to a parent/child relationship. +type Span_SpanKind int32 + +const ( + // Unspecified. + Span_SPAN_KIND_UNSPECIFIED Span_SpanKind = 0 + // Indicates that the span covers server-side handling of an RPC or other + // remote network request. + Span_SERVER Span_SpanKind = 1 + // Indicates that the span covers the client-side wrapper around an RPC or + // other remote request. + Span_CLIENT Span_SpanKind = 2 +) + +var Span_SpanKind_name = map[int32]string{ + 0: "SPAN_KIND_UNSPECIFIED", + 1: "SERVER", + 2: "CLIENT", +} + +var Span_SpanKind_value = map[string]int32{ + "SPAN_KIND_UNSPECIFIED": 0, + "SERVER": 1, + "CLIENT": 2, +} + +func (x Span_SpanKind) String() string { + return proto.EnumName(Span_SpanKind_name, int32(x)) +} + +func (Span_SpanKind) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 0} +} + +// Indicates whether the message was sent or received. +type Span_TimeEvent_MessageEvent_Type int32 + +const ( + // Unknown event type. + Span_TimeEvent_MessageEvent_TYPE_UNSPECIFIED Span_TimeEvent_MessageEvent_Type = 0 + // Indicates a sent message. + Span_TimeEvent_MessageEvent_SENT Span_TimeEvent_MessageEvent_Type = 1 + // Indicates a received message. + Span_TimeEvent_MessageEvent_RECEIVED Span_TimeEvent_MessageEvent_Type = 2 +) + +var Span_TimeEvent_MessageEvent_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "SENT", + 2: "RECEIVED", +} + +var Span_TimeEvent_MessageEvent_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "SENT": 1, + "RECEIVED": 2, +} + +func (x Span_TimeEvent_MessageEvent_Type) String() string { + return proto.EnumName(Span_TimeEvent_MessageEvent_Type_name, int32(x)) +} + +func (Span_TimeEvent_MessageEvent_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 2, 1, 0} +} + +// The relationship of the current span relative to the linked span: child, +// parent, or unspecified. +type Span_Link_Type int32 + +const ( + // The relationship of the two spans is unknown, or known but other + // than parent-child. + Span_Link_TYPE_UNSPECIFIED Span_Link_Type = 0 + // The linked span is a child of the current span. + Span_Link_CHILD_LINKED_SPAN Span_Link_Type = 1 + // The linked span is a parent of the current span. + Span_Link_PARENT_LINKED_SPAN Span_Link_Type = 2 +) + +var Span_Link_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "CHILD_LINKED_SPAN", + 2: "PARENT_LINKED_SPAN", +} + +var Span_Link_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "CHILD_LINKED_SPAN": 1, + "PARENT_LINKED_SPAN": 2, +} + +func (x Span_Link_Type) String() string { + return proto.EnumName(Span_Link_Type_name, int32(x)) +} + +func (Span_Link_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 4, 0} +} + +// A span represents a single operation within a trace. Spans can be +// nested to form a trace tree. Spans may also be linked to other spans +// from the same or different trace. And form graphs. Often, a trace +// contains a root span that describes the end-to-end latency, and one +// or more subspans for its sub-operations. A trace can also contain +// multiple root spans, or none at all. Spans do not need to be +// contiguous - there may be gaps or overlaps between spans in a trace. +// +// The next id is 17. +// TODO(bdrutu): Add an example. +type Span struct { + // A unique identifier for a trace. All spans from the same trace share + // the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes + // is considered invalid. + // + // This field is semantically required. Receiver should generate new + // random trace_id if empty or invalid trace_id was received. + // + // This field is required. + TraceId []byte `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` + // A unique identifier for a span within a trace, assigned when the span + // is created. The ID is an 8-byte array. An ID with all zeroes is considered + // invalid. + // + // This field is semantically required. Receiver should generate new + // random span_id if empty or invalid span_id was received. + // + // This field is required. + SpanId []byte `protobuf:"bytes,2,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"` + // The Tracestate on the span. + Tracestate *Span_Tracestate `protobuf:"bytes,15,opt,name=tracestate,proto3" json:"tracestate,omitempty"` + // The `span_id` of this span's parent span. If this is a root span, then this + // field must be empty. The ID is an 8-byte array. + ParentSpanId []byte `protobuf:"bytes,3,opt,name=parent_span_id,json=parentSpanId,proto3" json:"parent_span_id,omitempty"` + // A description of the span's operation. + // + // For example, the name can be a qualified method name or a file name + // and a line number where the operation is called. A best practice is to use + // the same display name at the same call point in an application. + // This makes it easier to correlate spans in different traces. + // + // This field is semantically required to be set to non-empty string. + // When null or empty string received - receiver may use string "name" + // as a replacement. There might be smarted algorithms implemented by + // receiver to fix the empty span name. + // + // This field is required. + Name *TruncatableString `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + // Distinguishes between spans generated in a particular context. For example, + // two spans with the same name may be distinguished using `CLIENT` (caller) + // and `SERVER` (callee) to identify queueing latency associated with the span. + Kind Span_SpanKind `protobuf:"varint,14,opt,name=kind,proto3,enum=opencensus.proto.trace.v1.Span_SpanKind" json:"kind,omitempty"` + // The start time of the span. On the client side, this is the time kept by + // the local machine where the span execution starts. On the server side, this + // is the time when the server's application handler starts running. + // + // This field is semantically required. When not set on receive - + // receiver should set it to the value of end_time field if it was + // set. Or to the current time if neither was set. It is important to + // keep end_time > start_time for consistency. + // + // This field is required. + StartTime *timestamp.Timestamp `protobuf:"bytes,5,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"` + // The end time of the span. On the client side, this is the time kept by + // the local machine where the span execution ends. On the server side, this + // is the time when the server application handler stops running. + // + // This field is semantically required. When not set on receive - + // receiver should set it to start_time value. It is important to + // keep end_time > start_time for consistency. + // + // This field is required. + EndTime *timestamp.Timestamp `protobuf:"bytes,6,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"` + // A set of attributes on the span. + Attributes *Span_Attributes `protobuf:"bytes,7,opt,name=attributes,proto3" json:"attributes,omitempty"` + // A stack trace captured at the start of the span. + StackTrace *StackTrace `protobuf:"bytes,8,opt,name=stack_trace,json=stackTrace,proto3" json:"stack_trace,omitempty"` + // The included time events. + TimeEvents *Span_TimeEvents `protobuf:"bytes,9,opt,name=time_events,json=timeEvents,proto3" json:"time_events,omitempty"` + // The included links. + Links *Span_Links `protobuf:"bytes,10,opt,name=links,proto3" json:"links,omitempty"` + // An optional final status for this span. Semantically when Status + // wasn't set it is means span ended without errors and assume + // Status.Ok (code = 0). + Status *Status `protobuf:"bytes,11,opt,name=status,proto3" json:"status,omitempty"` + // An optional resource that is associated with this span. If not set, this span + // should be part of a batch that does include the resource information, unless resource + // information is unknown. + Resource *v1.Resource `protobuf:"bytes,16,opt,name=resource,proto3" json:"resource,omitempty"` + // A highly recommended but not required flag that identifies when a + // trace crosses a process boundary. True when the parent_span belongs + // to the same process as the current span. This flag is most commonly + // used to indicate the need to adjust time as clocks in different + // processes may not be synchronized. + SameProcessAsParentSpan *wrappers.BoolValue `protobuf:"bytes,12,opt,name=same_process_as_parent_span,json=sameProcessAsParentSpan,proto3" json:"same_process_as_parent_span,omitempty"` + // An optional number of child spans that were generated while this span + // was active. If set, allows an implementation to detect missing child spans. + ChildSpanCount *wrappers.UInt32Value `protobuf:"bytes,13,opt,name=child_span_count,json=childSpanCount,proto3" json:"child_span_count,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span) Reset() { *m = Span{} } +func (m *Span) String() string { return proto.CompactTextString(m) } +func (*Span) ProtoMessage() {} +func (*Span) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0} +} + +func (m *Span) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span.Unmarshal(m, b) +} +func (m *Span) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span.Marshal(b, m, deterministic) +} +func (m *Span) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span.Merge(m, src) +} +func (m *Span) XXX_Size() int { + return xxx_messageInfo_Span.Size(m) +} +func (m *Span) XXX_DiscardUnknown() { + xxx_messageInfo_Span.DiscardUnknown(m) +} + +var xxx_messageInfo_Span proto.InternalMessageInfo + +func (m *Span) GetTraceId() []byte { + if m != nil { + return m.TraceId + } + return nil +} + +func (m *Span) GetSpanId() []byte { + if m != nil { + return m.SpanId + } + return nil +} + +func (m *Span) GetTracestate() *Span_Tracestate { + if m != nil { + return m.Tracestate + } + return nil +} + +func (m *Span) GetParentSpanId() []byte { + if m != nil { + return m.ParentSpanId + } + return nil +} + +func (m *Span) GetName() *TruncatableString { + if m != nil { + return m.Name + } + return nil +} + +func (m *Span) GetKind() Span_SpanKind { + if m != nil { + return m.Kind + } + return Span_SPAN_KIND_UNSPECIFIED +} + +func (m *Span) GetStartTime() *timestamp.Timestamp { + if m != nil { + return m.StartTime + } + return nil +} + +func (m *Span) GetEndTime() *timestamp.Timestamp { + if m != nil { + return m.EndTime + } + return nil +} + +func (m *Span) GetAttributes() *Span_Attributes { + if m != nil { + return m.Attributes + } + return nil +} + +func (m *Span) GetStackTrace() *StackTrace { + if m != nil { + return m.StackTrace + } + return nil +} + +func (m *Span) GetTimeEvents() *Span_TimeEvents { + if m != nil { + return m.TimeEvents + } + return nil +} + +func (m *Span) GetLinks() *Span_Links { + if m != nil { + return m.Links + } + return nil +} + +func (m *Span) GetStatus() *Status { + if m != nil { + return m.Status + } + return nil +} + +func (m *Span) GetResource() *v1.Resource { + if m != nil { + return m.Resource + } + return nil +} + +func (m *Span) GetSameProcessAsParentSpan() *wrappers.BoolValue { + if m != nil { + return m.SameProcessAsParentSpan + } + return nil +} + +func (m *Span) GetChildSpanCount() *wrappers.UInt32Value { + if m != nil { + return m.ChildSpanCount + } + return nil +} + +// This field conveys information about request position in multiple distributed tracing graphs. +// It is a list of Tracestate.Entry with a maximum of 32 members in the list. +// +// See the https://github.com/w3c/distributed-tracing for more details about this field. +type Span_Tracestate struct { + // A list of entries that represent the Tracestate. + Entries []*Span_Tracestate_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_Tracestate) Reset() { *m = Span_Tracestate{} } +func (m *Span_Tracestate) String() string { return proto.CompactTextString(m) } +func (*Span_Tracestate) ProtoMessage() {} +func (*Span_Tracestate) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 0} +} + +func (m *Span_Tracestate) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_Tracestate.Unmarshal(m, b) +} +func (m *Span_Tracestate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_Tracestate.Marshal(b, m, deterministic) +} +func (m *Span_Tracestate) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_Tracestate.Merge(m, src) +} +func (m *Span_Tracestate) XXX_Size() int { + return xxx_messageInfo_Span_Tracestate.Size(m) +} +func (m *Span_Tracestate) XXX_DiscardUnknown() { + xxx_messageInfo_Span_Tracestate.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_Tracestate proto.InternalMessageInfo + +func (m *Span_Tracestate) GetEntries() []*Span_Tracestate_Entry { + if m != nil { + return m.Entries + } + return nil +} + +type Span_Tracestate_Entry struct { + // The key must begin with a lowercase letter, and can only contain + // lowercase letters 'a'-'z', digits '0'-'9', underscores '_', dashes + // '-', asterisks '*', and forward slashes '/'. + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The value is opaque string up to 256 characters printable ASCII + // RFC0020 characters (i.e., the range 0x20 to 0x7E) except ',' and '='. + // Note that this also excludes tabs, newlines, carriage returns, etc. + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_Tracestate_Entry) Reset() { *m = Span_Tracestate_Entry{} } +func (m *Span_Tracestate_Entry) String() string { return proto.CompactTextString(m) } +func (*Span_Tracestate_Entry) ProtoMessage() {} +func (*Span_Tracestate_Entry) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 0, 0} +} + +func (m *Span_Tracestate_Entry) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_Tracestate_Entry.Unmarshal(m, b) +} +func (m *Span_Tracestate_Entry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_Tracestate_Entry.Marshal(b, m, deterministic) +} +func (m *Span_Tracestate_Entry) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_Tracestate_Entry.Merge(m, src) +} +func (m *Span_Tracestate_Entry) XXX_Size() int { + return xxx_messageInfo_Span_Tracestate_Entry.Size(m) +} +func (m *Span_Tracestate_Entry) XXX_DiscardUnknown() { + xxx_messageInfo_Span_Tracestate_Entry.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_Tracestate_Entry proto.InternalMessageInfo + +func (m *Span_Tracestate_Entry) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *Span_Tracestate_Entry) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +// A set of attributes, each with a key and a value. +type Span_Attributes struct { + // The set of attributes. The value can be a string, an integer, a double + // or the Boolean values `true` or `false`. Note, global attributes like + // server name can be set as tags using resource API. Examples of attributes: + // + // "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" + // "/http/server_latency": 300 + // "abc.com/myattribute": true + // "abc.com/score": 10.239 + AttributeMap map[string]*AttributeValue `protobuf:"bytes,1,rep,name=attribute_map,json=attributeMap,proto3" json:"attribute_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // The number of attributes that were discarded. Attributes can be discarded + // because their keys are too long or because there are too many attributes. + // If this value is 0, then no attributes were dropped. + DroppedAttributesCount int32 `protobuf:"varint,2,opt,name=dropped_attributes_count,json=droppedAttributesCount,proto3" json:"dropped_attributes_count,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_Attributes) Reset() { *m = Span_Attributes{} } +func (m *Span_Attributes) String() string { return proto.CompactTextString(m) } +func (*Span_Attributes) ProtoMessage() {} +func (*Span_Attributes) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 1} +} + +func (m *Span_Attributes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_Attributes.Unmarshal(m, b) +} +func (m *Span_Attributes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_Attributes.Marshal(b, m, deterministic) +} +func (m *Span_Attributes) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_Attributes.Merge(m, src) +} +func (m *Span_Attributes) XXX_Size() int { + return xxx_messageInfo_Span_Attributes.Size(m) +} +func (m *Span_Attributes) XXX_DiscardUnknown() { + xxx_messageInfo_Span_Attributes.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_Attributes proto.InternalMessageInfo + +func (m *Span_Attributes) GetAttributeMap() map[string]*AttributeValue { + if m != nil { + return m.AttributeMap + } + return nil +} + +func (m *Span_Attributes) GetDroppedAttributesCount() int32 { + if m != nil { + return m.DroppedAttributesCount + } + return 0 +} + +// A time-stamped annotation or message event in the Span. +type Span_TimeEvent struct { + // The time the event occurred. + Time *timestamp.Timestamp `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"` + // A `TimeEvent` can contain either an `Annotation` object or a + // `MessageEvent` object, but not both. + // + // Types that are valid to be assigned to Value: + // *Span_TimeEvent_Annotation_ + // *Span_TimeEvent_MessageEvent_ + Value isSpan_TimeEvent_Value `protobuf_oneof:"value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_TimeEvent) Reset() { *m = Span_TimeEvent{} } +func (m *Span_TimeEvent) String() string { return proto.CompactTextString(m) } +func (*Span_TimeEvent) ProtoMessage() {} +func (*Span_TimeEvent) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 2} +} + +func (m *Span_TimeEvent) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_TimeEvent.Unmarshal(m, b) +} +func (m *Span_TimeEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_TimeEvent.Marshal(b, m, deterministic) +} +func (m *Span_TimeEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_TimeEvent.Merge(m, src) +} +func (m *Span_TimeEvent) XXX_Size() int { + return xxx_messageInfo_Span_TimeEvent.Size(m) +} +func (m *Span_TimeEvent) XXX_DiscardUnknown() { + xxx_messageInfo_Span_TimeEvent.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_TimeEvent proto.InternalMessageInfo + +func (m *Span_TimeEvent) GetTime() *timestamp.Timestamp { + if m != nil { + return m.Time + } + return nil +} + +type isSpan_TimeEvent_Value interface { + isSpan_TimeEvent_Value() +} + +type Span_TimeEvent_Annotation_ struct { + Annotation *Span_TimeEvent_Annotation `protobuf:"bytes,2,opt,name=annotation,proto3,oneof"` +} + +type Span_TimeEvent_MessageEvent_ struct { + MessageEvent *Span_TimeEvent_MessageEvent `protobuf:"bytes,3,opt,name=message_event,json=messageEvent,proto3,oneof"` +} + +func (*Span_TimeEvent_Annotation_) isSpan_TimeEvent_Value() {} + +func (*Span_TimeEvent_MessageEvent_) isSpan_TimeEvent_Value() {} + +func (m *Span_TimeEvent) GetValue() isSpan_TimeEvent_Value { + if m != nil { + return m.Value + } + return nil +} + +func (m *Span_TimeEvent) GetAnnotation() *Span_TimeEvent_Annotation { + if x, ok := m.GetValue().(*Span_TimeEvent_Annotation_); ok { + return x.Annotation + } + return nil +} + +func (m *Span_TimeEvent) GetMessageEvent() *Span_TimeEvent_MessageEvent { + if x, ok := m.GetValue().(*Span_TimeEvent_MessageEvent_); ok { + return x.MessageEvent + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Span_TimeEvent) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Span_TimeEvent_Annotation_)(nil), + (*Span_TimeEvent_MessageEvent_)(nil), + } +} + +// A text annotation with a set of attributes. +type Span_TimeEvent_Annotation struct { + // A user-supplied message describing the event. + Description *TruncatableString `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + // A set of attributes on the annotation. + Attributes *Span_Attributes `protobuf:"bytes,2,opt,name=attributes,proto3" json:"attributes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_TimeEvent_Annotation) Reset() { *m = Span_TimeEvent_Annotation{} } +func (m *Span_TimeEvent_Annotation) String() string { return proto.CompactTextString(m) } +func (*Span_TimeEvent_Annotation) ProtoMessage() {} +func (*Span_TimeEvent_Annotation) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 2, 0} +} + +func (m *Span_TimeEvent_Annotation) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_TimeEvent_Annotation.Unmarshal(m, b) +} +func (m *Span_TimeEvent_Annotation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_TimeEvent_Annotation.Marshal(b, m, deterministic) +} +func (m *Span_TimeEvent_Annotation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_TimeEvent_Annotation.Merge(m, src) +} +func (m *Span_TimeEvent_Annotation) XXX_Size() int { + return xxx_messageInfo_Span_TimeEvent_Annotation.Size(m) +} +func (m *Span_TimeEvent_Annotation) XXX_DiscardUnknown() { + xxx_messageInfo_Span_TimeEvent_Annotation.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_TimeEvent_Annotation proto.InternalMessageInfo + +func (m *Span_TimeEvent_Annotation) GetDescription() *TruncatableString { + if m != nil { + return m.Description + } + return nil +} + +func (m *Span_TimeEvent_Annotation) GetAttributes() *Span_Attributes { + if m != nil { + return m.Attributes + } + return nil +} + +// An event describing a message sent/received between Spans. +type Span_TimeEvent_MessageEvent struct { + // The type of MessageEvent. Indicates whether the message was sent or + // received. + Type Span_TimeEvent_MessageEvent_Type `protobuf:"varint,1,opt,name=type,proto3,enum=opencensus.proto.trace.v1.Span_TimeEvent_MessageEvent_Type" json:"type,omitempty"` + // An identifier for the MessageEvent's message that can be used to match + // SENT and RECEIVED MessageEvents. For example, this field could + // represent a sequence ID for a streaming RPC. It is recommended to be + // unique within a Span. + Id uint64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` + // The number of uncompressed bytes sent or received. + UncompressedSize uint64 `protobuf:"varint,3,opt,name=uncompressed_size,json=uncompressedSize,proto3" json:"uncompressed_size,omitempty"` + // The number of compressed bytes sent or received. If zero, assumed to + // be the same size as uncompressed. + CompressedSize uint64 `protobuf:"varint,4,opt,name=compressed_size,json=compressedSize,proto3" json:"compressed_size,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_TimeEvent_MessageEvent) Reset() { *m = Span_TimeEvent_MessageEvent{} } +func (m *Span_TimeEvent_MessageEvent) String() string { return proto.CompactTextString(m) } +func (*Span_TimeEvent_MessageEvent) ProtoMessage() {} +func (*Span_TimeEvent_MessageEvent) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 2, 1} +} + +func (m *Span_TimeEvent_MessageEvent) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_TimeEvent_MessageEvent.Unmarshal(m, b) +} +func (m *Span_TimeEvent_MessageEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_TimeEvent_MessageEvent.Marshal(b, m, deterministic) +} +func (m *Span_TimeEvent_MessageEvent) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_TimeEvent_MessageEvent.Merge(m, src) +} +func (m *Span_TimeEvent_MessageEvent) XXX_Size() int { + return xxx_messageInfo_Span_TimeEvent_MessageEvent.Size(m) +} +func (m *Span_TimeEvent_MessageEvent) XXX_DiscardUnknown() { + xxx_messageInfo_Span_TimeEvent_MessageEvent.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_TimeEvent_MessageEvent proto.InternalMessageInfo + +func (m *Span_TimeEvent_MessageEvent) GetType() Span_TimeEvent_MessageEvent_Type { + if m != nil { + return m.Type + } + return Span_TimeEvent_MessageEvent_TYPE_UNSPECIFIED +} + +func (m *Span_TimeEvent_MessageEvent) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Span_TimeEvent_MessageEvent) GetUncompressedSize() uint64 { + if m != nil { + return m.UncompressedSize + } + return 0 +} + +func (m *Span_TimeEvent_MessageEvent) GetCompressedSize() uint64 { + if m != nil { + return m.CompressedSize + } + return 0 +} + +// A collection of `TimeEvent`s. A `TimeEvent` is a time-stamped annotation +// on the span, consisting of either user-supplied key-value pairs, or +// details of a message sent/received between Spans. +type Span_TimeEvents struct { + // A collection of `TimeEvent`s. + TimeEvent []*Span_TimeEvent `protobuf:"bytes,1,rep,name=time_event,json=timeEvent,proto3" json:"time_event,omitempty"` + // The number of dropped annotations in all the included time events. + // If the value is 0, then no annotations were dropped. + DroppedAnnotationsCount int32 `protobuf:"varint,2,opt,name=dropped_annotations_count,json=droppedAnnotationsCount,proto3" json:"dropped_annotations_count,omitempty"` + // The number of dropped message events in all the included time events. + // If the value is 0, then no message events were dropped. + DroppedMessageEventsCount int32 `protobuf:"varint,3,opt,name=dropped_message_events_count,json=droppedMessageEventsCount,proto3" json:"dropped_message_events_count,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_TimeEvents) Reset() { *m = Span_TimeEvents{} } +func (m *Span_TimeEvents) String() string { return proto.CompactTextString(m) } +func (*Span_TimeEvents) ProtoMessage() {} +func (*Span_TimeEvents) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 3} +} + +func (m *Span_TimeEvents) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_TimeEvents.Unmarshal(m, b) +} +func (m *Span_TimeEvents) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_TimeEvents.Marshal(b, m, deterministic) +} +func (m *Span_TimeEvents) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_TimeEvents.Merge(m, src) +} +func (m *Span_TimeEvents) XXX_Size() int { + return xxx_messageInfo_Span_TimeEvents.Size(m) +} +func (m *Span_TimeEvents) XXX_DiscardUnknown() { + xxx_messageInfo_Span_TimeEvents.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_TimeEvents proto.InternalMessageInfo + +func (m *Span_TimeEvents) GetTimeEvent() []*Span_TimeEvent { + if m != nil { + return m.TimeEvent + } + return nil +} + +func (m *Span_TimeEvents) GetDroppedAnnotationsCount() int32 { + if m != nil { + return m.DroppedAnnotationsCount + } + return 0 +} + +func (m *Span_TimeEvents) GetDroppedMessageEventsCount() int32 { + if m != nil { + return m.DroppedMessageEventsCount + } + return 0 +} + +// A pointer from the current span to another span in the same trace or in a +// different trace. For example, this can be used in batching operations, +// where a single batch handler processes multiple requests from different +// traces or when the handler receives a request from a different project. +type Span_Link struct { + // A unique identifier of a trace that this linked span is part of. The ID is a + // 16-byte array. + TraceId []byte `protobuf:"bytes,1,opt,name=trace_id,json=traceId,proto3" json:"trace_id,omitempty"` + // A unique identifier for the linked span. The ID is an 8-byte array. + SpanId []byte `protobuf:"bytes,2,opt,name=span_id,json=spanId,proto3" json:"span_id,omitempty"` + // The relationship of the current span relative to the linked span. + Type Span_Link_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencensus.proto.trace.v1.Span_Link_Type" json:"type,omitempty"` + // A set of attributes on the link. + Attributes *Span_Attributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_Link) Reset() { *m = Span_Link{} } +func (m *Span_Link) String() string { return proto.CompactTextString(m) } +func (*Span_Link) ProtoMessage() {} +func (*Span_Link) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 4} +} + +func (m *Span_Link) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_Link.Unmarshal(m, b) +} +func (m *Span_Link) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_Link.Marshal(b, m, deterministic) +} +func (m *Span_Link) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_Link.Merge(m, src) +} +func (m *Span_Link) XXX_Size() int { + return xxx_messageInfo_Span_Link.Size(m) +} +func (m *Span_Link) XXX_DiscardUnknown() { + xxx_messageInfo_Span_Link.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_Link proto.InternalMessageInfo + +func (m *Span_Link) GetTraceId() []byte { + if m != nil { + return m.TraceId + } + return nil +} + +func (m *Span_Link) GetSpanId() []byte { + if m != nil { + return m.SpanId + } + return nil +} + +func (m *Span_Link) GetType() Span_Link_Type { + if m != nil { + return m.Type + } + return Span_Link_TYPE_UNSPECIFIED +} + +func (m *Span_Link) GetAttributes() *Span_Attributes { + if m != nil { + return m.Attributes + } + return nil +} + +// A collection of links, which are references from this span to a span +// in the same or different trace. +type Span_Links struct { + // A collection of links. + Link []*Span_Link `protobuf:"bytes,1,rep,name=link,proto3" json:"link,omitempty"` + // The number of dropped links after the maximum size was enforced. If + // this value is 0, then no links were dropped. + DroppedLinksCount int32 `protobuf:"varint,2,opt,name=dropped_links_count,json=droppedLinksCount,proto3" json:"dropped_links_count,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Span_Links) Reset() { *m = Span_Links{} } +func (m *Span_Links) String() string { return proto.CompactTextString(m) } +func (*Span_Links) ProtoMessage() {} +func (*Span_Links) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{0, 5} +} + +func (m *Span_Links) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Span_Links.Unmarshal(m, b) +} +func (m *Span_Links) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Span_Links.Marshal(b, m, deterministic) +} +func (m *Span_Links) XXX_Merge(src proto.Message) { + xxx_messageInfo_Span_Links.Merge(m, src) +} +func (m *Span_Links) XXX_Size() int { + return xxx_messageInfo_Span_Links.Size(m) +} +func (m *Span_Links) XXX_DiscardUnknown() { + xxx_messageInfo_Span_Links.DiscardUnknown(m) +} + +var xxx_messageInfo_Span_Links proto.InternalMessageInfo + +func (m *Span_Links) GetLink() []*Span_Link { + if m != nil { + return m.Link + } + return nil +} + +func (m *Span_Links) GetDroppedLinksCount() int32 { + if m != nil { + return m.DroppedLinksCount + } + return 0 +} + +// The `Status` type defines a logical error model that is suitable for different +// programming environments, including REST APIs and RPC APIs. This proto's fields +// are a subset of those of +// [google.rpc.Status](https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto), +// which is used by [gRPC](https://github.com/grpc). +type Status struct { + // The status code. This is optional field. It is safe to assume 0 (OK) + // when not set. + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + // A developer-facing error message, which should be in English. + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Status) Reset() { *m = Status{} } +func (m *Status) String() string { return proto.CompactTextString(m) } +func (*Status) ProtoMessage() {} +func (*Status) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{1} +} + +func (m *Status) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Status.Unmarshal(m, b) +} +func (m *Status) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Status.Marshal(b, m, deterministic) +} +func (m *Status) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status.Merge(m, src) +} +func (m *Status) XXX_Size() int { + return xxx_messageInfo_Status.Size(m) +} +func (m *Status) XXX_DiscardUnknown() { + xxx_messageInfo_Status.DiscardUnknown(m) +} + +var xxx_messageInfo_Status proto.InternalMessageInfo + +func (m *Status) GetCode() int32 { + if m != nil { + return m.Code + } + return 0 +} + +func (m *Status) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +// The value of an Attribute. +type AttributeValue struct { + // The type of the value. + // + // Types that are valid to be assigned to Value: + // *AttributeValue_StringValue + // *AttributeValue_IntValue + // *AttributeValue_BoolValue + // *AttributeValue_DoubleValue + Value isAttributeValue_Value `protobuf_oneof:"value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *AttributeValue) Reset() { *m = AttributeValue{} } +func (m *AttributeValue) String() string { return proto.CompactTextString(m) } +func (*AttributeValue) ProtoMessage() {} +func (*AttributeValue) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{2} +} + +func (m *AttributeValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_AttributeValue.Unmarshal(m, b) +} +func (m *AttributeValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_AttributeValue.Marshal(b, m, deterministic) +} +func (m *AttributeValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_AttributeValue.Merge(m, src) +} +func (m *AttributeValue) XXX_Size() int { + return xxx_messageInfo_AttributeValue.Size(m) +} +func (m *AttributeValue) XXX_DiscardUnknown() { + xxx_messageInfo_AttributeValue.DiscardUnknown(m) +} + +var xxx_messageInfo_AttributeValue proto.InternalMessageInfo + +type isAttributeValue_Value interface { + isAttributeValue_Value() +} + +type AttributeValue_StringValue struct { + StringValue *TruncatableString `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` +} + +type AttributeValue_IntValue struct { + IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` +} + +type AttributeValue_BoolValue struct { + BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof"` +} + +type AttributeValue_DoubleValue struct { + DoubleValue float64 `protobuf:"fixed64,4,opt,name=double_value,json=doubleValue,proto3,oneof"` +} + +func (*AttributeValue_StringValue) isAttributeValue_Value() {} + +func (*AttributeValue_IntValue) isAttributeValue_Value() {} + +func (*AttributeValue_BoolValue) isAttributeValue_Value() {} + +func (*AttributeValue_DoubleValue) isAttributeValue_Value() {} + +func (m *AttributeValue) GetValue() isAttributeValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (m *AttributeValue) GetStringValue() *TruncatableString { + if x, ok := m.GetValue().(*AttributeValue_StringValue); ok { + return x.StringValue + } + return nil +} + +func (m *AttributeValue) GetIntValue() int64 { + if x, ok := m.GetValue().(*AttributeValue_IntValue); ok { + return x.IntValue + } + return 0 +} + +func (m *AttributeValue) GetBoolValue() bool { + if x, ok := m.GetValue().(*AttributeValue_BoolValue); ok { + return x.BoolValue + } + return false +} + +func (m *AttributeValue) GetDoubleValue() float64 { + if x, ok := m.GetValue().(*AttributeValue_DoubleValue); ok { + return x.DoubleValue + } + return 0 +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*AttributeValue) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*AttributeValue_StringValue)(nil), + (*AttributeValue_IntValue)(nil), + (*AttributeValue_BoolValue)(nil), + (*AttributeValue_DoubleValue)(nil), + } +} + +// The call stack which originated this span. +type StackTrace struct { + // Stack frames in this stack trace. + StackFrames *StackTrace_StackFrames `protobuf:"bytes,1,opt,name=stack_frames,json=stackFrames,proto3" json:"stack_frames,omitempty"` + // The hash ID is used to conserve network bandwidth for duplicate + // stack traces within a single trace. + // + // Often multiple spans will have identical stack traces. + // The first occurrence of a stack trace should contain both + // `stack_frames` and a value in `stack_trace_hash_id`. + // + // Subsequent spans within the same request can refer + // to that stack trace by setting only `stack_trace_hash_id`. + // + // TODO: describe how to deal with the case where stack_trace_hash_id is + // zero because it was not set. + StackTraceHashId uint64 `protobuf:"varint,2,opt,name=stack_trace_hash_id,json=stackTraceHashId,proto3" json:"stack_trace_hash_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StackTrace) Reset() { *m = StackTrace{} } +func (m *StackTrace) String() string { return proto.CompactTextString(m) } +func (*StackTrace) ProtoMessage() {} +func (*StackTrace) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{3} +} + +func (m *StackTrace) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StackTrace.Unmarshal(m, b) +} +func (m *StackTrace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StackTrace.Marshal(b, m, deterministic) +} +func (m *StackTrace) XXX_Merge(src proto.Message) { + xxx_messageInfo_StackTrace.Merge(m, src) +} +func (m *StackTrace) XXX_Size() int { + return xxx_messageInfo_StackTrace.Size(m) +} +func (m *StackTrace) XXX_DiscardUnknown() { + xxx_messageInfo_StackTrace.DiscardUnknown(m) +} + +var xxx_messageInfo_StackTrace proto.InternalMessageInfo + +func (m *StackTrace) GetStackFrames() *StackTrace_StackFrames { + if m != nil { + return m.StackFrames + } + return nil +} + +func (m *StackTrace) GetStackTraceHashId() uint64 { + if m != nil { + return m.StackTraceHashId + } + return 0 +} + +// A single stack frame in a stack trace. +type StackTrace_StackFrame struct { + // The fully-qualified name that uniquely identifies the function or + // method that is active in this frame. + FunctionName *TruncatableString `protobuf:"bytes,1,opt,name=function_name,json=functionName,proto3" json:"function_name,omitempty"` + // An un-mangled function name, if `function_name` is + // [mangled](http://www.avabodh.com/cxxin/namemangling.html). The name can + // be fully qualified. + OriginalFunctionName *TruncatableString `protobuf:"bytes,2,opt,name=original_function_name,json=originalFunctionName,proto3" json:"original_function_name,omitempty"` + // The name of the source file where the function call appears. + FileName *TruncatableString `protobuf:"bytes,3,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` + // The line number in `file_name` where the function call appears. + LineNumber int64 `protobuf:"varint,4,opt,name=line_number,json=lineNumber,proto3" json:"line_number,omitempty"` + // The column number where the function call appears, if available. + // This is important in JavaScript because of its anonymous functions. + ColumnNumber int64 `protobuf:"varint,5,opt,name=column_number,json=columnNumber,proto3" json:"column_number,omitempty"` + // The binary module from where the code was loaded. + LoadModule *Module `protobuf:"bytes,6,opt,name=load_module,json=loadModule,proto3" json:"load_module,omitempty"` + // The version of the deployed source code. + SourceVersion *TruncatableString `protobuf:"bytes,7,opt,name=source_version,json=sourceVersion,proto3" json:"source_version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StackTrace_StackFrame) Reset() { *m = StackTrace_StackFrame{} } +func (m *StackTrace_StackFrame) String() string { return proto.CompactTextString(m) } +func (*StackTrace_StackFrame) ProtoMessage() {} +func (*StackTrace_StackFrame) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{3, 0} +} + +func (m *StackTrace_StackFrame) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StackTrace_StackFrame.Unmarshal(m, b) +} +func (m *StackTrace_StackFrame) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StackTrace_StackFrame.Marshal(b, m, deterministic) +} +func (m *StackTrace_StackFrame) XXX_Merge(src proto.Message) { + xxx_messageInfo_StackTrace_StackFrame.Merge(m, src) +} +func (m *StackTrace_StackFrame) XXX_Size() int { + return xxx_messageInfo_StackTrace_StackFrame.Size(m) +} +func (m *StackTrace_StackFrame) XXX_DiscardUnknown() { + xxx_messageInfo_StackTrace_StackFrame.DiscardUnknown(m) +} + +var xxx_messageInfo_StackTrace_StackFrame proto.InternalMessageInfo + +func (m *StackTrace_StackFrame) GetFunctionName() *TruncatableString { + if m != nil { + return m.FunctionName + } + return nil +} + +func (m *StackTrace_StackFrame) GetOriginalFunctionName() *TruncatableString { + if m != nil { + return m.OriginalFunctionName + } + return nil +} + +func (m *StackTrace_StackFrame) GetFileName() *TruncatableString { + if m != nil { + return m.FileName + } + return nil +} + +func (m *StackTrace_StackFrame) GetLineNumber() int64 { + if m != nil { + return m.LineNumber + } + return 0 +} + +func (m *StackTrace_StackFrame) GetColumnNumber() int64 { + if m != nil { + return m.ColumnNumber + } + return 0 +} + +func (m *StackTrace_StackFrame) GetLoadModule() *Module { + if m != nil { + return m.LoadModule + } + return nil +} + +func (m *StackTrace_StackFrame) GetSourceVersion() *TruncatableString { + if m != nil { + return m.SourceVersion + } + return nil +} + +// A collection of stack frames, which can be truncated. +type StackTrace_StackFrames struct { + // Stack frames in this call stack. + Frame []*StackTrace_StackFrame `protobuf:"bytes,1,rep,name=frame,proto3" json:"frame,omitempty"` + // The number of stack frames that were dropped because there + // were too many stack frames. + // If this value is 0, then no stack frames were dropped. + DroppedFramesCount int32 `protobuf:"varint,2,opt,name=dropped_frames_count,json=droppedFramesCount,proto3" json:"dropped_frames_count,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StackTrace_StackFrames) Reset() { *m = StackTrace_StackFrames{} } +func (m *StackTrace_StackFrames) String() string { return proto.CompactTextString(m) } +func (*StackTrace_StackFrames) ProtoMessage() {} +func (*StackTrace_StackFrames) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{3, 1} +} + +func (m *StackTrace_StackFrames) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StackTrace_StackFrames.Unmarshal(m, b) +} +func (m *StackTrace_StackFrames) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StackTrace_StackFrames.Marshal(b, m, deterministic) +} +func (m *StackTrace_StackFrames) XXX_Merge(src proto.Message) { + xxx_messageInfo_StackTrace_StackFrames.Merge(m, src) +} +func (m *StackTrace_StackFrames) XXX_Size() int { + return xxx_messageInfo_StackTrace_StackFrames.Size(m) +} +func (m *StackTrace_StackFrames) XXX_DiscardUnknown() { + xxx_messageInfo_StackTrace_StackFrames.DiscardUnknown(m) +} + +var xxx_messageInfo_StackTrace_StackFrames proto.InternalMessageInfo + +func (m *StackTrace_StackFrames) GetFrame() []*StackTrace_StackFrame { + if m != nil { + return m.Frame + } + return nil +} + +func (m *StackTrace_StackFrames) GetDroppedFramesCount() int32 { + if m != nil { + return m.DroppedFramesCount + } + return 0 +} + +// A description of a binary module. +type Module struct { + // TODO: document the meaning of this field. + // For example: main binary, kernel modules, and dynamic libraries + // such as libc.so, sharedlib.so. + Module *TruncatableString `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` + // A unique identifier for the module, usually a hash of its + // contents. + BuildId *TruncatableString `protobuf:"bytes,2,opt,name=build_id,json=buildId,proto3" json:"build_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Module) Reset() { *m = Module{} } +func (m *Module) String() string { return proto.CompactTextString(m) } +func (*Module) ProtoMessage() {} +func (*Module) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{4} +} + +func (m *Module) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Module.Unmarshal(m, b) +} +func (m *Module) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Module.Marshal(b, m, deterministic) +} +func (m *Module) XXX_Merge(src proto.Message) { + xxx_messageInfo_Module.Merge(m, src) +} +func (m *Module) XXX_Size() int { + return xxx_messageInfo_Module.Size(m) +} +func (m *Module) XXX_DiscardUnknown() { + xxx_messageInfo_Module.DiscardUnknown(m) +} + +var xxx_messageInfo_Module proto.InternalMessageInfo + +func (m *Module) GetModule() *TruncatableString { + if m != nil { + return m.Module + } + return nil +} + +func (m *Module) GetBuildId() *TruncatableString { + if m != nil { + return m.BuildId + } + return nil +} + +// A string that might be shortened to a specified length. +type TruncatableString struct { + // The shortened string. For example, if the original string was 500 bytes long and + // the limit of the string was 128 bytes, then this value contains the first 128 + // bytes of the 500-byte string. Note that truncation always happens on a + // character boundary, to ensure that a truncated string is still valid UTF-8. + // Because it may contain multi-byte characters, the size of the truncated string + // may be less than the truncation limit. + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + // The number of bytes removed from the original string. If this + // value is 0, then the string was not shortened. + TruncatedByteCount int32 `protobuf:"varint,2,opt,name=truncated_byte_count,json=truncatedByteCount,proto3" json:"truncated_byte_count,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TruncatableString) Reset() { *m = TruncatableString{} } +func (m *TruncatableString) String() string { return proto.CompactTextString(m) } +func (*TruncatableString) ProtoMessage() {} +func (*TruncatableString) Descriptor() ([]byte, []int) { + return fileDescriptor_8ea38bbb821bf584, []int{5} +} + +func (m *TruncatableString) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TruncatableString.Unmarshal(m, b) +} +func (m *TruncatableString) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TruncatableString.Marshal(b, m, deterministic) +} +func (m *TruncatableString) XXX_Merge(src proto.Message) { + xxx_messageInfo_TruncatableString.Merge(m, src) +} +func (m *TruncatableString) XXX_Size() int { + return xxx_messageInfo_TruncatableString.Size(m) +} +func (m *TruncatableString) XXX_DiscardUnknown() { + xxx_messageInfo_TruncatableString.DiscardUnknown(m) +} + +var xxx_messageInfo_TruncatableString proto.InternalMessageInfo + +func (m *TruncatableString) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +func (m *TruncatableString) GetTruncatedByteCount() int32 { + if m != nil { + return m.TruncatedByteCount + } + return 0 +} + +func init() { + proto.RegisterEnum("opencensus.proto.trace.v1.Span_SpanKind", Span_SpanKind_name, Span_SpanKind_value) + proto.RegisterEnum("opencensus.proto.trace.v1.Span_TimeEvent_MessageEvent_Type", Span_TimeEvent_MessageEvent_Type_name, Span_TimeEvent_MessageEvent_Type_value) + proto.RegisterEnum("opencensus.proto.trace.v1.Span_Link_Type", Span_Link_Type_name, Span_Link_Type_value) + proto.RegisterType((*Span)(nil), "opencensus.proto.trace.v1.Span") + proto.RegisterType((*Span_Tracestate)(nil), "opencensus.proto.trace.v1.Span.Tracestate") + proto.RegisterType((*Span_Tracestate_Entry)(nil), "opencensus.proto.trace.v1.Span.Tracestate.Entry") + proto.RegisterType((*Span_Attributes)(nil), "opencensus.proto.trace.v1.Span.Attributes") + proto.RegisterMapType((map[string]*AttributeValue)(nil), "opencensus.proto.trace.v1.Span.Attributes.AttributeMapEntry") + proto.RegisterType((*Span_TimeEvent)(nil), "opencensus.proto.trace.v1.Span.TimeEvent") + proto.RegisterType((*Span_TimeEvent_Annotation)(nil), "opencensus.proto.trace.v1.Span.TimeEvent.Annotation") + proto.RegisterType((*Span_TimeEvent_MessageEvent)(nil), "opencensus.proto.trace.v1.Span.TimeEvent.MessageEvent") + proto.RegisterType((*Span_TimeEvents)(nil), "opencensus.proto.trace.v1.Span.TimeEvents") + proto.RegisterType((*Span_Link)(nil), "opencensus.proto.trace.v1.Span.Link") + proto.RegisterType((*Span_Links)(nil), "opencensus.proto.trace.v1.Span.Links") + proto.RegisterType((*Status)(nil), "opencensus.proto.trace.v1.Status") + proto.RegisterType((*AttributeValue)(nil), "opencensus.proto.trace.v1.AttributeValue") + proto.RegisterType((*StackTrace)(nil), "opencensus.proto.trace.v1.StackTrace") + proto.RegisterType((*StackTrace_StackFrame)(nil), "opencensus.proto.trace.v1.StackTrace.StackFrame") + proto.RegisterType((*StackTrace_StackFrames)(nil), "opencensus.proto.trace.v1.StackTrace.StackFrames") + proto.RegisterType((*Module)(nil), "opencensus.proto.trace.v1.Module") + proto.RegisterType((*TruncatableString)(nil), "opencensus.proto.trace.v1.TruncatableString") +} + +func init() { + proto.RegisterFile("opencensus/proto/trace/v1/trace.proto", fileDescriptor_8ea38bbb821bf584) +} + +var fileDescriptor_8ea38bbb821bf584 = []byte{ + // 1557 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0xeb, 0x52, 0x1b, 0x47, + 0x16, 0x66, 0x74, 0xd7, 0x91, 0x90, 0x45, 0x1b, 0xdb, 0x83, 0xd6, 0xbb, 0x66, 0x65, 0x7b, 0x17, + 0xaf, 0x17, 0x61, 0xb0, 0xd7, 0xe5, 0x6b, 0x79, 0x11, 0x88, 0x48, 0x06, 0x2b, 0x72, 0x4b, 0xa6, + 0x72, 0xa9, 0xd4, 0xd4, 0x48, 0xd3, 0x88, 0x09, 0x52, 0xcf, 0x64, 0xa6, 0x87, 0x14, 0x7e, 0x81, + 0x54, 0x2a, 0xff, 0x52, 0x95, 0xca, 0x0b, 0xe4, 0x47, 0x5e, 0x24, 0x0f, 0x90, 0xca, 0x73, 0xe4, + 0x09, 0xf2, 0x27, 0xd5, 0xdd, 0x73, 0x13, 0xd8, 0xa0, 0xc8, 0x7f, 0xa8, 0x9e, 0xee, 0xf3, 0x7d, + 0x7d, 0x4e, 0x9f, 0x2b, 0x82, 0xdb, 0x96, 0x4d, 0xe8, 0x80, 0x50, 0xd7, 0x73, 0xd7, 0x6c, 0xc7, + 0x62, 0xd6, 0x1a, 0x73, 0xf4, 0x01, 0x59, 0x3b, 0x5e, 0x97, 0x8b, 0x9a, 0xd8, 0x44, 0x4b, 0x91, + 0x98, 0xdc, 0xa9, 0xc9, 0xd3, 0xe3, 0xf5, 0xca, 0xdd, 0x33, 0x0c, 0x0e, 0x71, 0x2d, 0xcf, 0x91, + 0x24, 0xc1, 0x5a, 0xa2, 0x2a, 0x37, 0x86, 0x96, 0x35, 0x1c, 0x11, 0x29, 0xd8, 0xf7, 0x0e, 0xd6, + 0x98, 0x39, 0x26, 0x2e, 0xd3, 0xc7, 0xb6, 0x2f, 0xf0, 0x8f, 0xd3, 0x02, 0x5f, 0x3b, 0xba, 0x6d, + 0x13, 0xc7, 0xbf, 0xb6, 0xfa, 0xcb, 0x15, 0x48, 0x75, 0x6d, 0x9d, 0xa2, 0x25, 0xc8, 0x09, 0x15, + 0x34, 0xd3, 0x50, 0x95, 0x65, 0x65, 0xa5, 0x88, 0xb3, 0xe2, 0xbb, 0x65, 0xa0, 0x6b, 0x90, 0x75, + 0x6d, 0x9d, 0xf2, 0x93, 0x84, 0x38, 0xc9, 0xf0, 0xcf, 0x96, 0x81, 0x5e, 0x02, 0x08, 0x19, 0x97, + 0xe9, 0x8c, 0xa8, 0x97, 0x96, 0x95, 0x95, 0xc2, 0xc6, 0x7f, 0x6a, 0xef, 0x35, 0xad, 0xc6, 0x2f, + 0xaa, 0xf5, 0x42, 0x04, 0x8e, 0xa1, 0xd1, 0x2d, 0x28, 0xd9, 0xba, 0x43, 0x28, 0xd3, 0x82, 0xbb, + 0x92, 0xe2, 0xae, 0xa2, 0xdc, 0xed, 0xca, 0x1b, 0xff, 0x0f, 0x29, 0xaa, 0x8f, 0x89, 0x9a, 0x12, + 0x77, 0xfd, 0xf7, 0x9c, 0xbb, 0x7a, 0x8e, 0x47, 0x07, 0x3a, 0xd3, 0xfb, 0x23, 0xd2, 0x65, 0x8e, + 0x49, 0x87, 0x58, 0x20, 0xd1, 0x33, 0x48, 0x1d, 0x99, 0xd4, 0x50, 0x4b, 0xcb, 0xca, 0x4a, 0x69, + 0x63, 0xe5, 0x22, 0x6d, 0xf9, 0x9f, 0x5d, 0x93, 0x1a, 0x58, 0xa0, 0xd0, 0x63, 0x00, 0x97, 0xe9, + 0x0e, 0xd3, 0xf8, 0x3b, 0xab, 0x69, 0xa1, 0x45, 0xa5, 0x26, 0xdf, 0xb8, 0x16, 0xbc, 0x71, 0xad, + 0x17, 0x38, 0x01, 0xe7, 0x85, 0x34, 0xff, 0x46, 0xff, 0x83, 0x1c, 0xa1, 0x86, 0x04, 0x66, 0x2e, + 0x04, 0x66, 0x09, 0x35, 0x04, 0xec, 0x25, 0x80, 0xce, 0x98, 0x63, 0xf6, 0x3d, 0x46, 0x5c, 0x35, + 0x3b, 0xdd, 0x1b, 0x6f, 0x86, 0x08, 0x1c, 0x43, 0xa3, 0x1d, 0x28, 0xb8, 0x4c, 0x1f, 0x1c, 0x69, + 0x42, 0x5a, 0xcd, 0x09, 0xb2, 0xdb, 0xe7, 0x91, 0x71, 0x69, 0xe1, 0x30, 0x0c, 0x6e, 0xb8, 0x46, + 0xbb, 0x50, 0xe0, 0x66, 0x68, 0xe4, 0x98, 0x50, 0xe6, 0xaa, 0xf9, 0x29, 0x1d, 0x6f, 0x8e, 0x49, + 0x43, 0x20, 0x30, 0xb0, 0x70, 0x8d, 0x9e, 0x42, 0x7a, 0x64, 0xd2, 0x23, 0x57, 0x85, 0x8b, 0xd5, + 0xe1, 0x34, 0x7b, 0x5c, 0x18, 0x4b, 0x0c, 0x7a, 0x0c, 0x19, 0x1e, 0x3e, 0x9e, 0xab, 0x16, 0x04, + 0xfa, 0x9f, 0xe7, 0x1b, 0xc3, 0x3c, 0x17, 0xfb, 0x00, 0x54, 0x87, 0x5c, 0x90, 0x4c, 0x6a, 0x59, + 0x80, 0xff, 0x75, 0x16, 0x1c, 0xa6, 0xdb, 0xf1, 0x7a, 0x0d, 0xfb, 0x6b, 0x1c, 0xe2, 0xd0, 0x27, + 0xf0, 0x37, 0x57, 0x1f, 0x13, 0xcd, 0x76, 0xac, 0x01, 0x71, 0x5d, 0x4d, 0x77, 0xb5, 0x58, 0x10, + 0xab, 0xc5, 0xf7, 0xb8, 0xb9, 0x6e, 0x59, 0xa3, 0x7d, 0x7d, 0xe4, 0x11, 0x7c, 0x8d, 0xc3, 0x3b, + 0x12, 0xbd, 0xe9, 0x76, 0xc2, 0x50, 0x47, 0x3b, 0x50, 0x1e, 0x1c, 0x9a, 0x23, 0x43, 0x66, 0xc3, + 0xc0, 0xf2, 0x28, 0x53, 0xe7, 0x05, 0xdd, 0xf5, 0x33, 0x74, 0x6f, 0x5a, 0x94, 0xdd, 0xdf, 0x90, + 0x84, 0x25, 0x81, 0xe2, 0x14, 0x5b, 0x1c, 0x53, 0xf9, 0x56, 0x01, 0x88, 0x32, 0x0e, 0xbd, 0x84, + 0x2c, 0xa1, 0xcc, 0x31, 0x89, 0xab, 0x2a, 0xcb, 0xc9, 0x95, 0xc2, 0xc6, 0xbd, 0xe9, 0xd3, 0xb5, + 0xd6, 0xa0, 0xcc, 0x39, 0xc1, 0x01, 0x41, 0x65, 0x0d, 0xd2, 0x62, 0x07, 0x95, 0x21, 0x79, 0x44, + 0x4e, 0x44, 0xd5, 0xc8, 0x63, 0xbe, 0x44, 0x8b, 0x90, 0x3e, 0xe6, 0xea, 0x88, 0x7a, 0x91, 0xc7, + 0xf2, 0xa3, 0xf2, 0x43, 0x02, 0x20, 0x8a, 0x4c, 0xa4, 0xc3, 0x7c, 0x18, 0x9b, 0xda, 0x58, 0xb7, + 0x7d, 0x8d, 0x9e, 0x4d, 0x1f, 0xdc, 0xd1, 0xf2, 0x95, 0x6e, 0x4b, 0xed, 0x8a, 0x7a, 0x6c, 0x0b, + 0x3d, 0x02, 0xd5, 0x70, 0x2c, 0xdb, 0x26, 0x86, 0x16, 0xa5, 0x81, 0xff, 0x9a, 0x5c, 0xb5, 0x34, + 0xbe, 0xea, 0x9f, 0x47, 0xa4, 0xf2, 0xdd, 0xbe, 0x84, 0x85, 0x33, 0xe4, 0xef, 0x30, 0xf4, 0x45, + 0xdc, 0xd0, 0xc2, 0xc6, 0x9d, 0x73, 0x74, 0x0f, 0xe9, 0xa4, 0xa3, 0x24, 0xee, 0x49, 0xe2, 0x91, + 0x52, 0xf9, 0x29, 0x0d, 0xf9, 0x30, 0x39, 0x50, 0x0d, 0x52, 0xa2, 0x46, 0x28, 0x17, 0xd6, 0x08, + 0x21, 0x87, 0xf6, 0x01, 0x74, 0x4a, 0x2d, 0xa6, 0x33, 0xd3, 0xa2, 0xbe, 0x1e, 0x0f, 0xa6, 0xce, + 0xc5, 0xda, 0x66, 0x88, 0x6d, 0xce, 0xe1, 0x18, 0x13, 0xfa, 0x02, 0xe6, 0xc7, 0xc4, 0x75, 0xf5, + 0xa1, 0x9f, 0xe7, 0xa2, 0x1e, 0x17, 0x36, 0x1e, 0x4e, 0x4f, 0xfd, 0x4a, 0xc2, 0xc5, 0x47, 0x73, + 0x0e, 0x17, 0xc7, 0xb1, 0xef, 0xca, 0xcf, 0x0a, 0x40, 0x74, 0x37, 0x6a, 0x43, 0xc1, 0x20, 0xee, + 0xc0, 0x31, 0x6d, 0x61, 0x86, 0x32, 0x43, 0x7d, 0x8f, 0x13, 0x9c, 0x2a, 0x9b, 0x89, 0x0f, 0x29, + 0x9b, 0x95, 0x3f, 0x14, 0x28, 0xc6, 0x6d, 0x41, 0x1f, 0x43, 0x8a, 0x9d, 0xd8, 0xd2, 0x45, 0xa5, + 0x8d, 0xa7, 0xb3, 0xbd, 0x48, 0xad, 0x77, 0x62, 0x13, 0x2c, 0x88, 0x50, 0x09, 0x12, 0x7e, 0x73, + 0x4d, 0xe1, 0x84, 0x69, 0xa0, 0xbb, 0xb0, 0xe0, 0xd1, 0x81, 0x35, 0xb6, 0x1d, 0xe2, 0xba, 0xc4, + 0xd0, 0x5c, 0xf3, 0x2d, 0x11, 0xef, 0x9f, 0xc2, 0xe5, 0xf8, 0x41, 0xd7, 0x7c, 0x4b, 0xd0, 0xbf, + 0xe1, 0xd2, 0x69, 0xd1, 0x94, 0x10, 0x2d, 0x4d, 0x0a, 0x56, 0x1f, 0x40, 0x8a, 0xdf, 0x89, 0x16, + 0xa1, 0xdc, 0xfb, 0xb4, 0xd3, 0xd0, 0xde, 0xb4, 0xbb, 0x9d, 0xc6, 0x56, 0x6b, 0xa7, 0xd5, 0xd8, + 0x2e, 0xcf, 0xa1, 0x1c, 0xa4, 0xba, 0x8d, 0x76, 0xaf, 0xac, 0xa0, 0x22, 0xe4, 0x70, 0x63, 0xab, + 0xd1, 0xda, 0x6f, 0x6c, 0x97, 0x13, 0xf5, 0xac, 0x1f, 0xe2, 0x95, 0xdf, 0x78, 0x29, 0x89, 0xea, + 0x76, 0x13, 0x20, 0x6a, 0x02, 0x7e, 0xee, 0xde, 0x99, 0xfa, 0x29, 0x70, 0x3e, 0x6c, 0x01, 0xe8, + 0x09, 0x2c, 0x85, 0x59, 0x1a, 0x46, 0xc4, 0x64, 0x9a, 0x5e, 0x0b, 0xd2, 0x34, 0x3a, 0x17, 0x79, + 0x8a, 0x5e, 0xc0, 0xf5, 0x00, 0x3b, 0x11, 0xad, 0x01, 0x3c, 0x29, 0xe0, 0x01, 0x7f, 0xfc, 0xfd, + 0xfd, 0x44, 0xff, 0x3e, 0x01, 0x29, 0xde, 0x52, 0x66, 0x1a, 0x80, 0x9e, 0xfb, 0x81, 0x90, 0x14, + 0x81, 0x70, 0x67, 0x9a, 0xd6, 0x15, 0x77, 0xfb, 0x64, 0x90, 0xa6, 0x3e, 0x24, 0x48, 0xab, 0xbb, + 0xe7, 0x3a, 0xf7, 0x0a, 0x2c, 0x6c, 0x35, 0x5b, 0x7b, 0xdb, 0xda, 0x5e, 0xab, 0xbd, 0xdb, 0xd8, + 0xd6, 0xba, 0x9d, 0xcd, 0x76, 0x59, 0x41, 0x57, 0x01, 0x75, 0x36, 0x71, 0xa3, 0xdd, 0x9b, 0xd8, + 0x4f, 0x54, 0xbe, 0x82, 0xb4, 0x68, 0xb3, 0xe8, 0x11, 0xa4, 0x78, 0xa3, 0xf5, 0xdd, 0x7b, 0x6b, + 0x1a, 0x03, 0xb1, 0x40, 0xa0, 0x1a, 0x5c, 0x0e, 0x1c, 0x23, 0x5a, 0xf5, 0x84, 0x3b, 0x17, 0xfc, + 0x23, 0x71, 0x89, 0xf0, 0x43, 0xf5, 0x39, 0xe4, 0x82, 0x59, 0x0b, 0x2d, 0xc1, 0x15, 0xae, 0x88, + 0xb6, 0xdb, 0x6a, 0x6f, 0x9f, 0x32, 0x04, 0x20, 0xd3, 0x6d, 0xe0, 0xfd, 0x06, 0x2e, 0x2b, 0x7c, + 0xbd, 0xb5, 0xd7, 0xe2, 0x31, 0x9b, 0xa8, 0x3e, 0x84, 0x8c, 0xec, 0xef, 0x08, 0x41, 0x6a, 0x60, + 0x19, 0x32, 0x39, 0xd3, 0x58, 0xac, 0x91, 0x0a, 0x59, 0x3f, 0x3a, 0xfc, 0x8e, 0x14, 0x7c, 0x56, + 0x7f, 0x55, 0xa0, 0x34, 0x59, 0x99, 0xd1, 0x6b, 0x28, 0xba, 0xa2, 0xa2, 0x68, 0xb2, 0xb4, 0xcf, + 0x50, 0x8b, 0x9a, 0x73, 0xb8, 0x20, 0x39, 0x24, 0xe5, 0xdf, 0x21, 0x6f, 0x52, 0xa6, 0x45, 0xad, + 0x22, 0xd9, 0x9c, 0xc3, 0x39, 0x93, 0x32, 0x79, 0x7c, 0x03, 0xa0, 0x6f, 0x59, 0x23, 0xff, 0x9c, + 0x07, 0x53, 0xae, 0x39, 0x87, 0xf3, 0xfd, 0x60, 0x4c, 0x40, 0x37, 0xa1, 0x68, 0x58, 0x5e, 0x7f, + 0x44, 0x7c, 0x11, 0x1e, 0x2a, 0x0a, 0xbf, 0x44, 0xee, 0x0a, 0xa1, 0x30, 0x51, 0xab, 0xdf, 0x65, + 0x00, 0xa2, 0xc9, 0x0d, 0xf5, 0xb8, 0x3d, 0x7c, 0xea, 0x3b, 0x70, 0xf4, 0xb1, 0x68, 0xfc, 0xdc, + 0x9e, 0xf5, 0xa9, 0xc6, 0x3e, 0xb9, 0xdc, 0x11, 0x40, 0x2c, 0x87, 0x47, 0xf9, 0x81, 0x56, 0xe1, + 0x72, 0x6c, 0x96, 0xd4, 0x0e, 0x75, 0xf7, 0x50, 0x0b, 0x6b, 0x58, 0x39, 0x1a, 0x16, 0x9b, 0xba, + 0x7b, 0xd8, 0x32, 0x2a, 0xbf, 0x27, 0x7d, 0x9d, 0x04, 0x1c, 0xbd, 0x86, 0xf9, 0x03, 0x8f, 0x0e, + 0x78, 0x22, 0x6b, 0x62, 0xa0, 0x9f, 0xa5, 0xe0, 0x17, 0x03, 0x8a, 0x36, 0xa7, 0xec, 0xc3, 0x55, + 0xcb, 0x31, 0x87, 0x26, 0xd5, 0x47, 0xda, 0x24, 0x77, 0x62, 0x06, 0xee, 0xc5, 0x80, 0x6b, 0x27, + 0x7e, 0x47, 0x0b, 0xf2, 0x07, 0xe6, 0x88, 0x48, 0xda, 0xe4, 0x0c, 0xb4, 0x39, 0x0e, 0x17, 0x54, + 0x37, 0xa0, 0x30, 0x32, 0x29, 0xd1, 0xa8, 0x37, 0xee, 0x13, 0x47, 0x78, 0x34, 0x89, 0x81, 0x6f, + 0xb5, 0xc5, 0x0e, 0xba, 0x09, 0xf3, 0x03, 0x6b, 0xe4, 0x8d, 0x69, 0x20, 0x92, 0x16, 0x22, 0x45, + 0xb9, 0xe9, 0x0b, 0xd5, 0xa1, 0x30, 0xb2, 0x74, 0x43, 0x1b, 0x5b, 0x86, 0x37, 0x0a, 0xfe, 0xaf, + 0x38, 0x6f, 0x08, 0x7e, 0x25, 0x04, 0x31, 0x70, 0x94, 0x5c, 0xa3, 0x2e, 0x94, 0xe4, 0x38, 0xab, + 0x1d, 0x13, 0xc7, 0xe5, 0xdd, 0x37, 0x3b, 0x83, 0x65, 0xf3, 0x92, 0x63, 0x5f, 0x52, 0x54, 0xbe, + 0x51, 0xa0, 0x10, 0x8b, 0x1d, 0xb4, 0x03, 0x69, 0x11, 0x7e, 0xd3, 0x8c, 0x9d, 0xef, 0x8a, 0x3e, + 0x2c, 0xe1, 0xe8, 0x1e, 0x2c, 0x06, 0x65, 0x45, 0x86, 0xf3, 0x44, 0x5d, 0x41, 0xfe, 0x99, 0xbc, + 0x54, 0x16, 0x96, 0x1f, 0x15, 0xc8, 0xf8, 0x96, 0x6e, 0x43, 0xc6, 0x7f, 0xa8, 0x59, 0xc2, 0xcd, + 0xc7, 0xa2, 0x8f, 0x20, 0xd7, 0xf7, 0xf8, 0x68, 0xee, 0x87, 0xfb, 0x5f, 0xe5, 0xc9, 0x0a, 0x74, + 0xcb, 0xa8, 0x7e, 0x0e, 0x0b, 0x67, 0x4e, 0xa3, 0xd1, 0x59, 0x89, 0x8d, 0xce, 0xdc, 0x6c, 0x26, + 0x45, 0x89, 0xa1, 0xf5, 0x4f, 0x18, 0x99, 0x34, 0x3b, 0x3c, 0xab, 0x9f, 0x30, 0x22, 0xcc, 0xae, + 0xdb, 0x70, 0xdd, 0xb4, 0xde, 0xaf, 0x57, 0x5d, 0xfe, 0x57, 0xd0, 0xe1, 0x9b, 0x1d, 0xe5, 0xb3, + 0xfa, 0xd0, 0x64, 0x87, 0x5e, 0xbf, 0x36, 0xb0, 0xc6, 0x6b, 0x52, 0x7e, 0xd5, 0xa4, 0x2e, 0x73, + 0xbc, 0x31, 0xa1, 0xb2, 0xdf, 0xae, 0x45, 0x54, 0xab, 0xf2, 0x67, 0x89, 0x21, 0xa1, 0xab, 0xc3, + 0xe8, 0xf7, 0x8d, 0x7e, 0x46, 0x6c, 0xdf, 0xff, 0x33, 0x00, 0x00, 0xff, 0xff, 0x1e, 0xe0, 0x94, + 0x45, 0x03, 0x11, 0x00, 0x00, +} diff --git a/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go new file mode 100644 index 000000000..2ac2d28c4 --- /dev/null +++ b/vendor/github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1/trace_config.pb.go @@ -0,0 +1,358 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: opencensus/proto/trace/v1/trace_config.proto + +package v1 + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// How spans should be sampled: +// - Always off +// - Always on +// - Always follow the parent Span's decision (off if no parent). +type ConstantSampler_ConstantDecision int32 + +const ( + ConstantSampler_ALWAYS_OFF ConstantSampler_ConstantDecision = 0 + ConstantSampler_ALWAYS_ON ConstantSampler_ConstantDecision = 1 + ConstantSampler_ALWAYS_PARENT ConstantSampler_ConstantDecision = 2 +) + +var ConstantSampler_ConstantDecision_name = map[int32]string{ + 0: "ALWAYS_OFF", + 1: "ALWAYS_ON", + 2: "ALWAYS_PARENT", +} + +var ConstantSampler_ConstantDecision_value = map[string]int32{ + "ALWAYS_OFF": 0, + "ALWAYS_ON": 1, + "ALWAYS_PARENT": 2, +} + +func (x ConstantSampler_ConstantDecision) String() string { + return proto.EnumName(ConstantSampler_ConstantDecision_name, int32(x)) +} + +func (ConstantSampler_ConstantDecision) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_5359209b41ff50c5, []int{2, 0} +} + +// Global configuration of the trace service. All fields must be specified, or +// the default (zero) values will be used for each type. +type TraceConfig struct { + // The global default sampler used to make decisions on span sampling. + // + // Types that are valid to be assigned to Sampler: + // *TraceConfig_ProbabilitySampler + // *TraceConfig_ConstantSampler + // *TraceConfig_RateLimitingSampler + Sampler isTraceConfig_Sampler `protobuf_oneof:"sampler"` + // The global default max number of attributes per span. + MaxNumberOfAttributes int64 `protobuf:"varint,4,opt,name=max_number_of_attributes,json=maxNumberOfAttributes,proto3" json:"max_number_of_attributes,omitempty"` + // The global default max number of annotation events per span. + MaxNumberOfAnnotations int64 `protobuf:"varint,5,opt,name=max_number_of_annotations,json=maxNumberOfAnnotations,proto3" json:"max_number_of_annotations,omitempty"` + // The global default max number of message events per span. + MaxNumberOfMessageEvents int64 `protobuf:"varint,6,opt,name=max_number_of_message_events,json=maxNumberOfMessageEvents,proto3" json:"max_number_of_message_events,omitempty"` + // The global default max number of link entries per span. + MaxNumberOfLinks int64 `protobuf:"varint,7,opt,name=max_number_of_links,json=maxNumberOfLinks,proto3" json:"max_number_of_links,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TraceConfig) Reset() { *m = TraceConfig{} } +func (m *TraceConfig) String() string { return proto.CompactTextString(m) } +func (*TraceConfig) ProtoMessage() {} +func (*TraceConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_5359209b41ff50c5, []int{0} +} + +func (m *TraceConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TraceConfig.Unmarshal(m, b) +} +func (m *TraceConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TraceConfig.Marshal(b, m, deterministic) +} +func (m *TraceConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_TraceConfig.Merge(m, src) +} +func (m *TraceConfig) XXX_Size() int { + return xxx_messageInfo_TraceConfig.Size(m) +} +func (m *TraceConfig) XXX_DiscardUnknown() { + xxx_messageInfo_TraceConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_TraceConfig proto.InternalMessageInfo + +type isTraceConfig_Sampler interface { + isTraceConfig_Sampler() +} + +type TraceConfig_ProbabilitySampler struct { + ProbabilitySampler *ProbabilitySampler `protobuf:"bytes,1,opt,name=probability_sampler,json=probabilitySampler,proto3,oneof"` +} + +type TraceConfig_ConstantSampler struct { + ConstantSampler *ConstantSampler `protobuf:"bytes,2,opt,name=constant_sampler,json=constantSampler,proto3,oneof"` +} + +type TraceConfig_RateLimitingSampler struct { + RateLimitingSampler *RateLimitingSampler `protobuf:"bytes,3,opt,name=rate_limiting_sampler,json=rateLimitingSampler,proto3,oneof"` +} + +func (*TraceConfig_ProbabilitySampler) isTraceConfig_Sampler() {} + +func (*TraceConfig_ConstantSampler) isTraceConfig_Sampler() {} + +func (*TraceConfig_RateLimitingSampler) isTraceConfig_Sampler() {} + +func (m *TraceConfig) GetSampler() isTraceConfig_Sampler { + if m != nil { + return m.Sampler + } + return nil +} + +func (m *TraceConfig) GetProbabilitySampler() *ProbabilitySampler { + if x, ok := m.GetSampler().(*TraceConfig_ProbabilitySampler); ok { + return x.ProbabilitySampler + } + return nil +} + +func (m *TraceConfig) GetConstantSampler() *ConstantSampler { + if x, ok := m.GetSampler().(*TraceConfig_ConstantSampler); ok { + return x.ConstantSampler + } + return nil +} + +func (m *TraceConfig) GetRateLimitingSampler() *RateLimitingSampler { + if x, ok := m.GetSampler().(*TraceConfig_RateLimitingSampler); ok { + return x.RateLimitingSampler + } + return nil +} + +func (m *TraceConfig) GetMaxNumberOfAttributes() int64 { + if m != nil { + return m.MaxNumberOfAttributes + } + return 0 +} + +func (m *TraceConfig) GetMaxNumberOfAnnotations() int64 { + if m != nil { + return m.MaxNumberOfAnnotations + } + return 0 +} + +func (m *TraceConfig) GetMaxNumberOfMessageEvents() int64 { + if m != nil { + return m.MaxNumberOfMessageEvents + } + return 0 +} + +func (m *TraceConfig) GetMaxNumberOfLinks() int64 { + if m != nil { + return m.MaxNumberOfLinks + } + return 0 +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*TraceConfig) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*TraceConfig_ProbabilitySampler)(nil), + (*TraceConfig_ConstantSampler)(nil), + (*TraceConfig_RateLimitingSampler)(nil), + } +} + +// Sampler that tries to uniformly sample traces with a given probability. +// The probability of sampling a trace is equal to that of the specified probability. +type ProbabilitySampler struct { + // The desired probability of sampling. Must be within [0.0, 1.0]. + SamplingProbability float64 `protobuf:"fixed64,1,opt,name=samplingProbability,proto3" json:"samplingProbability,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ProbabilitySampler) Reset() { *m = ProbabilitySampler{} } +func (m *ProbabilitySampler) String() string { return proto.CompactTextString(m) } +func (*ProbabilitySampler) ProtoMessage() {} +func (*ProbabilitySampler) Descriptor() ([]byte, []int) { + return fileDescriptor_5359209b41ff50c5, []int{1} +} + +func (m *ProbabilitySampler) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ProbabilitySampler.Unmarshal(m, b) +} +func (m *ProbabilitySampler) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ProbabilitySampler.Marshal(b, m, deterministic) +} +func (m *ProbabilitySampler) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProbabilitySampler.Merge(m, src) +} +func (m *ProbabilitySampler) XXX_Size() int { + return xxx_messageInfo_ProbabilitySampler.Size(m) +} +func (m *ProbabilitySampler) XXX_DiscardUnknown() { + xxx_messageInfo_ProbabilitySampler.DiscardUnknown(m) +} + +var xxx_messageInfo_ProbabilitySampler proto.InternalMessageInfo + +func (m *ProbabilitySampler) GetSamplingProbability() float64 { + if m != nil { + return m.SamplingProbability + } + return 0 +} + +// Sampler that always makes a constant decision on span sampling. +type ConstantSampler struct { + Decision ConstantSampler_ConstantDecision `protobuf:"varint,1,opt,name=decision,proto3,enum=opencensus.proto.trace.v1.ConstantSampler_ConstantDecision" json:"decision,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ConstantSampler) Reset() { *m = ConstantSampler{} } +func (m *ConstantSampler) String() string { return proto.CompactTextString(m) } +func (*ConstantSampler) ProtoMessage() {} +func (*ConstantSampler) Descriptor() ([]byte, []int) { + return fileDescriptor_5359209b41ff50c5, []int{2} +} + +func (m *ConstantSampler) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ConstantSampler.Unmarshal(m, b) +} +func (m *ConstantSampler) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ConstantSampler.Marshal(b, m, deterministic) +} +func (m *ConstantSampler) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConstantSampler.Merge(m, src) +} +func (m *ConstantSampler) XXX_Size() int { + return xxx_messageInfo_ConstantSampler.Size(m) +} +func (m *ConstantSampler) XXX_DiscardUnknown() { + xxx_messageInfo_ConstantSampler.DiscardUnknown(m) +} + +var xxx_messageInfo_ConstantSampler proto.InternalMessageInfo + +func (m *ConstantSampler) GetDecision() ConstantSampler_ConstantDecision { + if m != nil { + return m.Decision + } + return ConstantSampler_ALWAYS_OFF +} + +// Sampler that tries to sample with a rate per time window. +type RateLimitingSampler struct { + // Rate per second. + Qps int64 `protobuf:"varint,1,opt,name=qps,proto3" json:"qps,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RateLimitingSampler) Reset() { *m = RateLimitingSampler{} } +func (m *RateLimitingSampler) String() string { return proto.CompactTextString(m) } +func (*RateLimitingSampler) ProtoMessage() {} +func (*RateLimitingSampler) Descriptor() ([]byte, []int) { + return fileDescriptor_5359209b41ff50c5, []int{3} +} + +func (m *RateLimitingSampler) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RateLimitingSampler.Unmarshal(m, b) +} +func (m *RateLimitingSampler) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RateLimitingSampler.Marshal(b, m, deterministic) +} +func (m *RateLimitingSampler) XXX_Merge(src proto.Message) { + xxx_messageInfo_RateLimitingSampler.Merge(m, src) +} +func (m *RateLimitingSampler) XXX_Size() int { + return xxx_messageInfo_RateLimitingSampler.Size(m) +} +func (m *RateLimitingSampler) XXX_DiscardUnknown() { + xxx_messageInfo_RateLimitingSampler.DiscardUnknown(m) +} + +var xxx_messageInfo_RateLimitingSampler proto.InternalMessageInfo + +func (m *RateLimitingSampler) GetQps() int64 { + if m != nil { + return m.Qps + } + return 0 +} + +func init() { + proto.RegisterEnum("opencensus.proto.trace.v1.ConstantSampler_ConstantDecision", ConstantSampler_ConstantDecision_name, ConstantSampler_ConstantDecision_value) + proto.RegisterType((*TraceConfig)(nil), "opencensus.proto.trace.v1.TraceConfig") + proto.RegisterType((*ProbabilitySampler)(nil), "opencensus.proto.trace.v1.ProbabilitySampler") + proto.RegisterType((*ConstantSampler)(nil), "opencensus.proto.trace.v1.ConstantSampler") + proto.RegisterType((*RateLimitingSampler)(nil), "opencensus.proto.trace.v1.RateLimitingSampler") +} + +func init() { + proto.RegisterFile("opencensus/proto/trace/v1/trace_config.proto", fileDescriptor_5359209b41ff50c5) +} + +var fileDescriptor_5359209b41ff50c5 = []byte{ + // 486 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xc1, 0x4e, 0xdb, 0x40, + 0x10, 0x86, 0x31, 0xa1, 0x50, 0x06, 0x01, 0xee, 0x5a, 0x54, 0x46, 0xe2, 0x80, 0x7c, 0x29, 0xaa, + 0x6a, 0xbb, 0xd0, 0x43, 0x55, 0x55, 0xaa, 0x94, 0x00, 0x51, 0x0f, 0x69, 0x88, 0x0c, 0x52, 0xd4, + 0x5e, 0xdc, 0xb5, 0xd9, 0xb8, 0xab, 0xc6, 0xb3, 0xae, 0x77, 0x1d, 0xd1, 0x77, 0xe9, 0x43, 0xf4, + 0x11, 0xab, 0xac, 0x5d, 0xdb, 0x49, 0x00, 0x71, 0xdb, 0xf9, 0xff, 0xf9, 0x7e, 0xaf, 0xbc, 0x33, + 0xf0, 0x46, 0x64, 0x0c, 0x63, 0x86, 0xb2, 0x90, 0x7e, 0x96, 0x0b, 0x25, 0x7c, 0x95, 0xd3, 0x98, + 0xf9, 0xb3, 0xd3, 0xf2, 0x10, 0xc6, 0x02, 0x27, 0x3c, 0xf1, 0xb4, 0x47, 0x0e, 0x9b, 0xee, 0x52, + 0xf1, 0x74, 0x93, 0x37, 0x3b, 0x75, 0xfe, 0x6c, 0xc0, 0xce, 0xcd, 0xbc, 0x38, 0xd7, 0x00, 0xf9, + 0x0e, 0x56, 0x96, 0x8b, 0x88, 0x46, 0x7c, 0xca, 0xd5, 0xef, 0x50, 0xd2, 0x34, 0x9b, 0xb2, 0xdc, + 0x36, 0x8e, 0x8d, 0x93, 0x9d, 0x33, 0xd7, 0x7b, 0x30, 0xc8, 0x1b, 0x35, 0xd4, 0x75, 0x09, 0x7d, + 0x5e, 0x0b, 0x48, 0xb6, 0xa2, 0x92, 0x31, 0x98, 0xb1, 0x40, 0xa9, 0x28, 0xaa, 0x3a, 0x7e, 0x5d, + 0xc7, 0xbf, 0x7e, 0x24, 0xfe, 0xbc, 0x42, 0x9a, 0xec, 0xfd, 0x78, 0x51, 0x22, 0xb7, 0x70, 0x90, + 0x53, 0xc5, 0xc2, 0x29, 0x4f, 0xb9, 0xe2, 0x98, 0xd4, 0xe9, 0x1d, 0x9d, 0xee, 0x3d, 0x92, 0x1e, + 0x50, 0xc5, 0x06, 0x15, 0xd6, 0x7c, 0xc1, 0xca, 0x57, 0x65, 0xf2, 0x1e, 0xec, 0x94, 0xde, 0x85, + 0x58, 0xa4, 0x11, 0xcb, 0x43, 0x31, 0x09, 0xa9, 0x52, 0x39, 0x8f, 0x0a, 0xc5, 0xa4, 0xbd, 0x71, + 0x6c, 0x9c, 0x74, 0x82, 0x83, 0x94, 0xde, 0x0d, 0xb5, 0x7d, 0x35, 0xe9, 0xd6, 0x26, 0xf9, 0x00, + 0x87, 0x4b, 0x20, 0xa2, 0x50, 0x54, 0x71, 0x81, 0xd2, 0x7e, 0xa6, 0xc9, 0x97, 0x6d, 0xb2, 0x71, + 0xc9, 0x27, 0x38, 0x5a, 0x44, 0x53, 0x26, 0x25, 0x4d, 0x58, 0xc8, 0x66, 0x0c, 0x95, 0xb4, 0x37, + 0x35, 0x6d, 0xb7, 0xe8, 0x2f, 0x65, 0xc3, 0xa5, 0xf6, 0x89, 0x0b, 0xd6, 0x22, 0x3f, 0xe5, 0xf8, + 0x53, 0xda, 0x5b, 0x1a, 0x33, 0x5b, 0xd8, 0x60, 0xae, 0xf7, 0xb6, 0x61, 0xab, 0xfa, 0x75, 0x4e, + 0x1f, 0xc8, 0xea, 0xc3, 0x92, 0xb7, 0x60, 0xe9, 0x06, 0x8e, 0x49, 0xcb, 0xd5, 0x43, 0x62, 0x04, + 0xf7, 0x59, 0xce, 0x5f, 0x03, 0xf6, 0x97, 0x9e, 0x90, 0x8c, 0xe1, 0xf9, 0x2d, 0x8b, 0xb9, 0xe4, + 0x02, 0x35, 0xba, 0x77, 0xf6, 0xf1, 0xe9, 0x03, 0x50, 0xd7, 0x17, 0x55, 0x44, 0x50, 0x87, 0x39, + 0x17, 0x60, 0x2e, 0xbb, 0x64, 0x0f, 0xa0, 0x3b, 0x18, 0x77, 0xbf, 0x5e, 0x87, 0x57, 0xfd, 0xbe, + 0xb9, 0x46, 0x76, 0x61, 0xfb, 0x7f, 0x3d, 0x34, 0x0d, 0xf2, 0x02, 0x76, 0xab, 0x72, 0xd4, 0x0d, + 0x2e, 0x87, 0x37, 0xe6, 0xba, 0xf3, 0x0a, 0xac, 0x7b, 0xc6, 0x82, 0x98, 0xd0, 0xf9, 0x95, 0x49, + 0x7d, 0xe1, 0x4e, 0x30, 0x3f, 0xf6, 0x66, 0x70, 0xc4, 0xc5, 0xc3, 0x37, 0xef, 0x99, 0xad, 0xfd, + 0x1a, 0xcd, 0xad, 0x91, 0xf1, 0xad, 0x97, 0x70, 0xf5, 0xa3, 0x88, 0xbc, 0x58, 0xa4, 0x7e, 0x49, + 0xb9, 0x1c, 0xa5, 0xca, 0x8b, 0x94, 0x61, 0xf9, 0xea, 0x7e, 0x13, 0xe8, 0x96, 0x1b, 0x9e, 0x30, + 0x74, 0x93, 0x66, 0xd1, 0xa3, 0x4d, 0x2d, 0xbf, 0xfb, 0x17, 0x00, 0x00, 0xff, 0xff, 0x13, 0xe2, + 0xd9, 0x56, 0x0c, 0x04, 0x00, 0x00, +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/.gitignore b/vendor/github.com/cloudflare/cloudflare-go/.gitignore new file mode 100644 index 000000000..4045fd670 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/.gitignore @@ -0,0 +1,2 @@ +.idea +.vscode/ diff --git a/vendor/github.com/cloudflare/cloudflare-go/.travis.yml b/vendor/github.com/cloudflare/cloudflare-go/.travis.yml new file mode 100644 index 000000000..fce3ee17d --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/.travis.yml @@ -0,0 +1,52 @@ +language: go +sudo: false + +cache: + directories: + - $GOPATH/pkg/mod + +env: + global: + - MOD_VENDOR="-mod=vendor" + - GO111MODULE=on + - GOPROXY=https://proxy.golang.org + +matrix: + fast_finish: true + include: + - go: 1.11.x + - go: 1.12.x + - go: 1.x + env: LATEST=true + - go: tip + allow_failures: + - go: tip + +before_install: + - cd $(mktemp -d); go mod init tmp; go get -u github.com/mitchellh/gox; cd - + - cd $(mktemp -d); go mod init tmp; go get -u golang.org/x/lint/golint; cd - + +install: + - # skip + +script: + - if [ "$GO111MODULE" != "on" ]; then go get -t -v ./... ; else true; fi + - golint -set_exit_status . cmd/flarectl + - go vet $MOD_VENDOR $(go list $MOD_VENDOR ./... | grep -v /vendor/) + - go test -v -race $MOD_VENDOR ./... + # Only build binaries from the latest Go release. + - if [ "${LATEST}" = "true" ]; then gox -os="linux darwin windows" -arch="amd64" -output="flarectl.{{.OS}}.{{.Arch}}" -ldflags "-X main.Rev=`git rev-parse --short HEAD`" -verbose ./...; fi + +# deploy: +# provider: releases +# skip_cleanup: true +# api_key: +# secure: TODO +# file: +# - flarectl.windows.amd64.exe +# - flarectl.darwin.amd64 +# - flarectl.linux.amd64 +# on: +# repo: cloudflare/cloudflare-go +# tags: true +# condition: $LATEST = true diff --git a/vendor/github.com/cloudflare/cloudflare-go/CODE_OF_CONDUCT.md b/vendor/github.com/cloudflare/cloudflare-go/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..bfbc69d22 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/CODE_OF_CONDUCT.md @@ -0,0 +1,77 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at ggalow@cloudflare.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq + diff --git a/vendor/github.com/cloudflare/cloudflare-go/LICENSE b/vendor/github.com/cloudflare/cloudflare-go/LICENSE new file mode 100644 index 000000000..33865c30f --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2015-2019, Cloudflare. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/cloudflare/cloudflare-go/README.md b/vendor/github.com/cloudflare/cloudflare-go/README.md new file mode 100644 index 000000000..8f5d77b74 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/README.md @@ -0,0 +1,107 @@ +# cloudflare-go + +[![GoDoc](https://img.shields.io/badge/godoc-reference-5673AF.svg?style=flat-square)](https://godoc.org/github.com/cloudflare/cloudflare-go) +[![Build Status](https://img.shields.io/travis/cloudflare/cloudflare-go/master.svg?style=flat-square)](https://travis-ci.org/cloudflare/cloudflare-go) +[![Go Report Card](https://goreportcard.com/badge/github.com/cloudflare/cloudflare-go?style=flat-square)](https://goreportcard.com/report/github.com/cloudflare/cloudflare-go) + +> **Note**: This library is under active development as we expand it to cover +> our (expanding!) API. Consider the public API of this package a little +> unstable as we work towards a v1.0. + +A Go library for interacting with +[Cloudflare's API v4](https://api.cloudflare.com/). This library allows you to: + +* Manage and automate changes to your DNS records within Cloudflare +* Manage and automate changes to your zones (domains) on Cloudflare, including + adding new zones to your account +* List and modify the status of WAF (Web Application Firewall) rules for your + zones +* Fetch Cloudflare's IP ranges for automating your firewall whitelisting + +A command-line client, [flarectl](cmd/flarectl), is also available as part of +this project. + +## Features + +The current feature list includes: + +* [x] Cache purging +* [x] Cloudflare IPs +* [x] Custom hostnames +* [x] DNS Records +* [x] Firewall (partial) +* [ ] [Keyless SSL](https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/) +* [x] [Load Balancing](https://blog.cloudflare.com/introducing-load-balancing-intelligent-failover-with-cloudflare/) +* [x] [Logpush Jobs](https://developers.cloudflare.com/logs/logpush/) +* [ ] Organization Administration +* [x] [Origin CA](https://blog.cloudflare.com/universal-ssl-encryption-all-the-way-to-the-origin-for-free/) +* [x] [Railgun](https://www.cloudflare.com/railgun/) administration +* [x] Rate Limiting +* [x] User Administration (partial) +* [x] Virtual DNS Management +* [x] Web Application Firewall (WAF) +* [x] Zone Lockdown and User-Agent Block rules +* [x] Zones + +Pull Requests are welcome, but please open an issue (or comment in an existing +issue) to discuss any non-trivial changes before submitting code. + +## Installation + +You need a working Go environment. + +``` +go get github.com/cloudflare/cloudflare-go +``` + +## Getting Started + +```go +package main + +import ( + "fmt" + "log" + "os" + + "github.com/cloudflare/cloudflare-go" +) + +func main() { + // Construct a new API object + api, err := cloudflare.New(os.Getenv("CF_API_KEY"), os.Getenv("CF_API_EMAIL")) + if err != nil { + log.Fatal(err) + } + + // Fetch user details on the account + u, err := api.UserDetails() + if err != nil { + log.Fatal(err) + } + // Print user details + fmt.Println(u) + + // Fetch the zone ID + id, err := api.ZoneIDByName("example.com") // Assuming example.com exists in your Cloudflare account already + if err != nil { + log.Fatal(err) + } + + // Fetch zone details + zone, err := api.ZoneDetails(id) + if err != nil { + log.Fatal(err) + } + // Print zone details + fmt.Println(zone) +} +``` + +Also refer to the +[API documentation](https://godoc.org/github.com/cloudflare/cloudflare-go) for +how to use this package in-depth. + +# License + +BSD licensed. See the [LICENSE](LICENSE) file for details. diff --git a/vendor/github.com/cloudflare/cloudflare-go/access_application.go b/vendor/github.com/cloudflare/cloudflare-go/access_application.go new file mode 100644 index 000000000..0893c5681 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/access_application.go @@ -0,0 +1,180 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "net/url" + "strconv" + "time" + + "github.com/pkg/errors" +) + +// AccessApplication represents an Access application. +type AccessApplication struct { + ID string `json:"id,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + AUD string `json:"aud,omitempty"` + Name string `json:"name"` + Domain string `json:"domain"` + SessionDuration string `json:"session_duration,omitempty"` +} + +// AccessApplicationListResponse represents the response from the list +// access applications endpoint. +type AccessApplicationListResponse struct { + Result []AccessApplication `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// AccessApplicationDetailResponse is the API response, containing a single +// access application. +type AccessApplicationDetailResponse struct { + Success bool `json:"success"` + Errors []string `json:"errors"` + Messages []string `json:"messages"` + Result AccessApplication `json:"result"` +} + +// AccessApplications returns all applications within a zone. +// +// API reference: https://api.cloudflare.com/#access-applications-list-access-applications +func (api *API) AccessApplications(zoneID string, pageOpts PaginationOptions) ([]AccessApplication, ResultInfo, error) { + v := url.Values{} + if pageOpts.PerPage > 0 { + v.Set("per_page", strconv.Itoa(pageOpts.PerPage)) + } + if pageOpts.Page > 0 { + v.Set("page", strconv.Itoa(pageOpts.Page)) + } + + uri := "/zones/" + zoneID + "/access/apps" + if len(v) > 0 { + uri = uri + "?" + v.Encode() + } + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []AccessApplication{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError) + } + + var accessApplicationListResponse AccessApplicationListResponse + err = json.Unmarshal(res, &accessApplicationListResponse) + if err != nil { + return []AccessApplication{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError) + } + + return accessApplicationListResponse.Result, accessApplicationListResponse.ResultInfo, nil +} + +// AccessApplication returns a single application based on the +// application ID. +// +// API reference: https://api.cloudflare.com/#access-applications-access-applications-details +func (api *API) AccessApplication(zoneID, applicationID string) (AccessApplication, error) { + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s", + zoneID, + applicationID, + ) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return AccessApplication{}, errors.Wrap(err, errMakeRequestError) + } + + var accessApplicationDetailResponse AccessApplicationDetailResponse + err = json.Unmarshal(res, &accessApplicationDetailResponse) + if err != nil { + return AccessApplication{}, errors.Wrap(err, errUnmarshalError) + } + + return accessApplicationDetailResponse.Result, nil +} + +// CreateAccessApplication creates a new access application. +// +// API reference: https://api.cloudflare.com/#access-applications-create-access-application +func (api *API) CreateAccessApplication(zoneID string, accessApplication AccessApplication) (AccessApplication, error) { + uri := "/zones/" + zoneID + "/access/apps" + + res, err := api.makeRequest("POST", uri, accessApplication) + if err != nil { + return AccessApplication{}, errors.Wrap(err, errMakeRequestError) + } + + var accessApplicationDetailResponse AccessApplicationDetailResponse + err = json.Unmarshal(res, &accessApplicationDetailResponse) + if err != nil { + return AccessApplication{}, errors.Wrap(err, errUnmarshalError) + } + + return accessApplicationDetailResponse.Result, nil +} + +// UpdateAccessApplication updates an existing access application. +// +// API reference: https://api.cloudflare.com/#access-applications-update-access-application +func (api *API) UpdateAccessApplication(zoneID string, accessApplication AccessApplication) (AccessApplication, error) { + if accessApplication.ID == "" { + return AccessApplication{}, errors.Errorf("access application ID cannot be empty") + } + + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s", + zoneID, + accessApplication.ID, + ) + + res, err := api.makeRequest("PUT", uri, accessApplication) + if err != nil { + return AccessApplication{}, errors.Wrap(err, errMakeRequestError) + } + + var accessApplicationDetailResponse AccessApplicationDetailResponse + err = json.Unmarshal(res, &accessApplicationDetailResponse) + if err != nil { + return AccessApplication{}, errors.Wrap(err, errUnmarshalError) + } + + return accessApplicationDetailResponse.Result, nil +} + +// DeleteAccessApplication deletes an access application. +// +// API reference: https://api.cloudflare.com/#access-applications-delete-access-application +func (api *API) DeleteAccessApplication(zoneID, applicationID string) error { + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s", + zoneID, + applicationID, + ) + + _, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} + +// RevokeAccessApplicationTokens revokes tokens associated with an +// access application. +// +// API reference: https://api.cloudflare.com/#access-applications-revoke-access-tokens +func (api *API) RevokeAccessApplicationTokens(zoneID, applicationID string) error { + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s/revoke-tokens", + zoneID, + applicationID, + ) + + _, err := api.makeRequest("POST", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/access_policy.go b/vendor/github.com/cloudflare/cloudflare-go/access_policy.go new file mode 100644 index 000000000..dbf63e49f --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/access_policy.go @@ -0,0 +1,221 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "net/url" + "strconv" + "time" + + "github.com/pkg/errors" +) + +// AccessPolicy defines a policy for allowing or disallowing access to +// one or more Access applications. +type AccessPolicy struct { + ID string `json:"id,omitempty"` + Precedence int `json:"precedence"` + Decision string `json:"decision"` + CreatedAt *time.Time `json:"created_at"` + UpdatedAt *time.Time `json:"updated_at"` + Name string `json:"name"` + + // The include policy works like an OR logical operator. The user must + // satisfy one of the rules. + Include []interface{} `json:"include"` + + // The exclude policy works like a NOT logical operator. The user must + // not satisfy all of the rules in exclude. + Exclude []interface{} `json:"exclude"` + + // The require policy works like a AND logical operator. The user must + // satisfy all of the rules in require. + Require []interface{} `json:"require"` +} + +// AccessPolicyEmail is used for managing access based on the email. +// For example, restrict access to users with the email addresses +// `test@example.com` or `someone@example.com`. +type AccessPolicyEmail struct { + Email struct { + Email string `json:"email"` + } `json:"email"` +} + +// AccessPolicyEmailDomain is used for managing access based on an email +// domain domain such as `example.com` instead of individual addresses. +type AccessPolicyEmailDomain struct { + EmailDomain struct { + Domain string `json:"domain"` + } `json:"email_domain"` +} + +// AccessPolicyIP is used for managing access based in the IP. It +// accepts individual IPs or CIDRs. +type AccessPolicyIP struct { + IP struct { + IP string `json:"ip"` + } `json:"ip"` +} + +// AccessPolicyEveryone is used for managing access to everyone. +type AccessPolicyEveryone struct { + Everyone struct{} `json:"everyone"` +} + +// AccessPolicyAccessGroup is used for managing access based on an +// access group. +type AccessPolicyAccessGroup struct { + Group struct { + ID string `json:"id"` + } `json:"group"` +} + +// AccessPolicyListResponse represents the response from the list +// access polciies endpoint. +type AccessPolicyListResponse struct { + Result []AccessPolicy `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// AccessPolicyDetailResponse is the API response, containing a single +// access policy. +type AccessPolicyDetailResponse struct { + Success bool `json:"success"` + Errors []string `json:"errors"` + Messages []string `json:"messages"` + Result AccessPolicy `json:"result"` +} + +// AccessPolicies returns all access policies for an access application. +// +// API reference: https://api.cloudflare.com/#access-policy-list-access-policies +func (api *API) AccessPolicies(zoneID, applicationID string, pageOpts PaginationOptions) ([]AccessPolicy, ResultInfo, error) { + v := url.Values{} + if pageOpts.PerPage > 0 { + v.Set("per_page", strconv.Itoa(pageOpts.PerPage)) + } + if pageOpts.Page > 0 { + v.Set("page", strconv.Itoa(pageOpts.Page)) + } + + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s/policies", + zoneID, + applicationID, + ) + + if len(v) > 0 { + uri = uri + "?" + v.Encode() + } + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []AccessPolicy{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError) + } + + var accessPolicyListResponse AccessPolicyListResponse + err = json.Unmarshal(res, &accessPolicyListResponse) + if err != nil { + return []AccessPolicy{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError) + } + + return accessPolicyListResponse.Result, accessPolicyListResponse.ResultInfo, nil +} + +// AccessPolicy returns a single policy based on the policy ID. +// +// API reference: https://api.cloudflare.com/#access-policy-access-policy-details +func (api *API) AccessPolicy(zoneID, applicationID, policyID string) (AccessPolicy, error) { + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s/policies/%s", + zoneID, + applicationID, + policyID, + ) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return AccessPolicy{}, errors.Wrap(err, errMakeRequestError) + } + + var accessPolicyDetailResponse AccessPolicyDetailResponse + err = json.Unmarshal(res, &accessPolicyDetailResponse) + if err != nil { + return AccessPolicy{}, errors.Wrap(err, errUnmarshalError) + } + + return accessPolicyDetailResponse.Result, nil +} + +// CreateAccessPolicy creates a new access policy. +// +// API reference: https://api.cloudflare.com/#access-policy-create-access-policy +func (api *API) CreateAccessPolicy(zoneID, applicationID string, accessPolicy AccessPolicy) (AccessPolicy, error) { + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s/policies", + zoneID, + applicationID, + ) + + res, err := api.makeRequest("POST", uri, accessPolicy) + if err != nil { + return AccessPolicy{}, errors.Wrap(err, errMakeRequestError) + } + + var accessPolicyDetailResponse AccessPolicyDetailResponse + err = json.Unmarshal(res, &accessPolicyDetailResponse) + if err != nil { + return AccessPolicy{}, errors.Wrap(err, errUnmarshalError) + } + + return accessPolicyDetailResponse.Result, nil +} + +// UpdateAccessPolicy updates an existing access policy. +// +// API reference: https://api.cloudflare.com/#access-policy-update-access-policy +func (api *API) UpdateAccessPolicy(zoneID, applicationID string, accessPolicy AccessPolicy) (AccessPolicy, error) { + if accessPolicy.ID == "" { + return AccessPolicy{}, errors.Errorf("access policy ID cannot be empty") + } + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s/policies/%s", + zoneID, + applicationID, + accessPolicy.ID, + ) + + res, err := api.makeRequest("PUT", uri, accessPolicy) + if err != nil { + return AccessPolicy{}, errors.Wrap(err, errMakeRequestError) + } + + var accessPolicyDetailResponse AccessPolicyDetailResponse + err = json.Unmarshal(res, &accessPolicyDetailResponse) + if err != nil { + return AccessPolicy{}, errors.Wrap(err, errUnmarshalError) + } + + return accessPolicyDetailResponse.Result, nil +} + +// DeleteAccessPolicy deletes an access policy. +// +// API reference: https://api.cloudflare.com/#access-policy-update-access-policy +func (api *API) DeleteAccessPolicy(zoneID, applicationID, accessPolicyID string) error { + uri := fmt.Sprintf( + "/zones/%s/access/apps/%s/policies/%s", + zoneID, + applicationID, + accessPolicyID, + ) + + _, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/account_members.go b/vendor/github.com/cloudflare/cloudflare-go/account_members.go new file mode 100644 index 000000000..42166e922 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/account_members.go @@ -0,0 +1,186 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "net/url" + "strconv" + + "github.com/pkg/errors" +) + +// AccountMember is the definition of a member of an account. +type AccountMember struct { + ID string `json:"id"` + Code string `json:"code"` + User AccountMemberUserDetails `json:"user"` + Status string `json:"status"` + Roles []AccountRole `json:"roles"` +} + +// AccountMemberUserDetails outlines all the personal information about +// a member. +type AccountMemberUserDetails struct { + ID string `json:"id"` + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + Email string `json:"email"` + TwoFactorAuthenticationEnabled bool +} + +// AccountMembersListResponse represents the response from the list +// account members endpoint. +type AccountMembersListResponse struct { + Result []AccountMember `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// AccountMemberDetailResponse is the API response, containing a single +// account member. +type AccountMemberDetailResponse struct { + Success bool `json:"success"` + Errors []string `json:"errors"` + Messages []string `json:"messages"` + Result AccountMember `json:"result"` +} + +// AccountMemberInvitation represents the invitation for a new member to +// the account. +type AccountMemberInvitation struct { + Email string `json:"email"` + Roles []string `json:"roles"` +} + +// AccountMembers returns all members of an account. +// +// API reference: https://api.cloudflare.com/#accounts-list-accounts +func (api *API) AccountMembers(accountID string, pageOpts PaginationOptions) ([]AccountMember, ResultInfo, error) { + if accountID == "" { + return []AccountMember{}, ResultInfo{}, errors.New(errMissingAccountID) + } + + v := url.Values{} + if pageOpts.PerPage > 0 { + v.Set("per_page", strconv.Itoa(pageOpts.PerPage)) + } + if pageOpts.Page > 0 { + v.Set("page", strconv.Itoa(pageOpts.Page)) + } + + uri := "/accounts/" + accountID + "/members" + if len(v) > 0 { + uri = uri + "?" + v.Encode() + } + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []AccountMember{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError) + } + + var accountMemberListresponse AccountMembersListResponse + err = json.Unmarshal(res, &accountMemberListresponse) + if err != nil { + return []AccountMember{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError) + } + + return accountMemberListresponse.Result, accountMemberListresponse.ResultInfo, nil +} + +// CreateAccountMember invites a new member to join an account. +// +// API reference: https://api.cloudflare.com/#account-members-add-member +func (api *API) CreateAccountMember(accountID string, emailAddress string, roles []string) (AccountMember, error) { + if accountID == "" { + return AccountMember{}, errors.New(errMissingAccountID) + } + + uri := "/accounts/" + accountID + "/members" + + var newMember = AccountMemberInvitation{ + Email: emailAddress, + Roles: roles, + } + res, err := api.makeRequest("POST", uri, newMember) + if err != nil { + return AccountMember{}, errors.Wrap(err, errMakeRequestError) + } + + var accountMemberListResponse AccountMemberDetailResponse + err = json.Unmarshal(res, &accountMemberListResponse) + if err != nil { + return AccountMember{}, errors.Wrap(err, errUnmarshalError) + } + + return accountMemberListResponse.Result, nil +} + +// DeleteAccountMember removes a member from an account. +// +// API reference: https://api.cloudflare.com/#account-members-remove-member +func (api *API) DeleteAccountMember(accountID string, userID string) error { + if accountID == "" { + return errors.New(errMissingAccountID) + } + + uri := fmt.Sprintf("/accounts/%s/members/%s", accountID, userID) + + _, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} + +// UpdateAccountMember modifies an existing account member. +// +// API reference: https://api.cloudflare.com/#account-members-update-member +func (api *API) UpdateAccountMember(accountID string, userID string, member AccountMember) (AccountMember, error) { + if accountID == "" { + return AccountMember{}, errors.New(errMissingAccountID) + } + + uri := fmt.Sprintf("/accounts/%s/members/%s", accountID, userID) + + res, err := api.makeRequest("PUT", uri, member) + if err != nil { + return AccountMember{}, errors.Wrap(err, errMakeRequestError) + } + + var accountMemberListResponse AccountMemberDetailResponse + err = json.Unmarshal(res, &accountMemberListResponse) + if err != nil { + return AccountMember{}, errors.Wrap(err, errUnmarshalError) + } + + return accountMemberListResponse.Result, nil +} + +// AccountMember returns details of a single account member. +// +// API reference: https://api.cloudflare.com/#account-members-member-details +func (api *API) AccountMember(accountID string, memberID string) (AccountMember, error) { + if accountID == "" { + return AccountMember{}, errors.New(errMissingAccountID) + } + + uri := fmt.Sprintf( + "/accounts/%s/members/%s", + accountID, + memberID, + ) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return AccountMember{}, errors.Wrap(err, errMakeRequestError) + } + + var accountMemberResponse AccountMemberDetailResponse + err = json.Unmarshal(res, &accountMemberResponse) + if err != nil { + return AccountMember{}, errors.Wrap(err, errUnmarshalError) + } + + return accountMemberResponse.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/account_roles.go b/vendor/github.com/cloudflare/cloudflare-go/account_roles.go new file mode 100644 index 000000000..3704313b5 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/account_roles.go @@ -0,0 +1,80 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + + "github.com/pkg/errors" +) + +// AccountRole defines the roles that a member can have attached. +type AccountRole struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Permissions map[string]AccountRolePermission `json:"permissions"` +} + +// AccountRolePermission is the shared structure for all permissions +// that can be assigned to a member. +type AccountRolePermission struct { + Read bool `json:"read"` + Edit bool `json:"edit"` +} + +// AccountRolesListResponse represents the list response from the +// account roles. +type AccountRolesListResponse struct { + Result []AccountRole `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// AccountRoleDetailResponse is the API response, containing a single +// account role. +type AccountRoleDetailResponse struct { + Success bool `json:"success"` + Errors []string `json:"errors"` + Messages []string `json:"messages"` + Result AccountRole `json:"result"` +} + +// AccountRoles returns all roles of an account. +// +// API reference: https://api.cloudflare.com/#account-roles-list-roles +func (api *API) AccountRoles(accountID string) ([]AccountRole, error) { + uri := "/accounts/" + accountID + "/roles" + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []AccountRole{}, errors.Wrap(err, errMakeRequestError) + } + + var accountRolesListResponse AccountRolesListResponse + err = json.Unmarshal(res, &accountRolesListResponse) + if err != nil { + return []AccountRole{}, errors.Wrap(err, errUnmarshalError) + } + + return accountRolesListResponse.Result, nil +} + +// AccountRole returns the details of a single account role. +// +// API reference: https://api.cloudflare.com/#account-roles-role-details +func (api *API) AccountRole(accountID string, roleID string) (AccountRole, error) { + uri := fmt.Sprintf("/accounts/%s/roles/%s", accountID, roleID) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return AccountRole{}, errors.Wrap(err, errMakeRequestError) + } + + var accountRole AccountRoleDetailResponse + err = json.Unmarshal(res, &accountRole) + if err != nil { + return AccountRole{}, errors.Wrap(err, errUnmarshalError) + } + + return accountRole.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/accounts.go b/vendor/github.com/cloudflare/cloudflare-go/accounts.go new file mode 100644 index 000000000..7d34b7b8f --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/accounts.go @@ -0,0 +1,114 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "strconv" + + "github.com/pkg/errors" +) + +// AccountSettings outlines the available options for an account. +type AccountSettings struct { + EnforceTwoFactor bool `json:"enforce_twofactor"` +} + +// Account represents the root object that owns resources. +type Account struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Settings *AccountSettings `json:"settings"` +} + +// AccountResponse represents the response from the accounts endpoint for a +// single account ID. +type AccountResponse struct { + Result Account `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// AccountListResponse represents the response from the list accounts endpoint. +type AccountListResponse struct { + Result []Account `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// AccountDetailResponse is the API response, containing a single Account. +type AccountDetailResponse struct { + Success bool `json:"success"` + Errors []string `json:"errors"` + Messages []string `json:"messages"` + Result Account `json:"result"` +} + +// Accounts returns all accounts the logged in user has access to. +// +// API reference: https://api.cloudflare.com/#accounts-list-accounts +func (api *API) Accounts(pageOpts PaginationOptions) ([]Account, ResultInfo, error) { + v := url.Values{} + if pageOpts.PerPage > 0 { + v.Set("per_page", strconv.Itoa(pageOpts.PerPage)) + } + if pageOpts.Page > 0 { + v.Set("page", strconv.Itoa(pageOpts.Page)) + } + + uri := "/accounts" + if len(v) > 0 { + uri = uri + "?" + v.Encode() + } + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []Account{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError) + } + + var accListResponse AccountListResponse + err = json.Unmarshal(res, &accListResponse) + if err != nil { + return []Account{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError) + } + return accListResponse.Result, accListResponse.ResultInfo, nil +} + +// Account returns a single account based on the ID. +// +// API reference: https://api.cloudflare.com/#accounts-account-details +func (api *API) Account(accountID string) (Account, ResultInfo, error) { + uri := "/accounts/" + accountID + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return Account{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError) + } + + var accResponse AccountResponse + err = json.Unmarshal(res, &accResponse) + if err != nil { + return Account{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError) + } + + return accResponse.Result, accResponse.ResultInfo, nil +} + +// UpdateAccount allows management of an account using the account ID. +// +// API reference: https://api.cloudflare.com/#accounts-update-account +func (api *API) UpdateAccount(accountID string, account Account) (Account, error) { + uri := "/accounts/" + accountID + + res, err := api.makeRequest("PUT", uri, account) + if err != nil { + return Account{}, errors.Wrap(err, errMakeRequestError) + } + + var a AccountDetailResponse + err = json.Unmarshal(res, &a) + if err != nil { + return Account{}, errors.Wrap(err, errUnmarshalError) + } + + return a.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/argo.go b/vendor/github.com/cloudflare/cloudflare-go/argo.go new file mode 100644 index 000000000..320c7fc25 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/argo.go @@ -0,0 +1,120 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/pkg/errors" +) + +var validSettingValues = []string{"on", "off"} + +// ArgoFeatureSetting is the structure of the API object for the +// argo smart routing and tiered caching settings. +type ArgoFeatureSetting struct { + Editable bool `json:"editable,omitempty"` + ID string `json:"id,omitempty"` + ModifiedOn time.Time `json:"modified_on,omitempty"` + Value string `json:"value"` +} + +// ArgoDetailsResponse is the API response for the argo smart routing +// and tiered caching response. +type ArgoDetailsResponse struct { + Result ArgoFeatureSetting `json:"result"` + Response +} + +// ArgoSmartRouting returns the current settings for smart routing. +// +// API reference: https://api.cloudflare.com/#argo-smart-routing-get-argo-smart-routing-setting +func (api *API) ArgoSmartRouting(zoneID string) (ArgoFeatureSetting, error) { + uri := "/zones/" + zoneID + "/argo/smart_routing" + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return ArgoFeatureSetting{}, errors.Wrap(err, errMakeRequestError) + } + + var argoDetailsResponse ArgoDetailsResponse + err = json.Unmarshal(res, &argoDetailsResponse) + if err != nil { + return ArgoFeatureSetting{}, errors.Wrap(err, errUnmarshalError) + } + return argoDetailsResponse.Result, nil +} + +// UpdateArgoSmartRouting updates the setting for smart routing. +// +// API reference: https://api.cloudflare.com/#argo-smart-routing-patch-argo-smart-routing-setting +func (api *API) UpdateArgoSmartRouting(zoneID, settingValue string) (ArgoFeatureSetting, error) { + if !contains(validSettingValues, settingValue) { + return ArgoFeatureSetting{}, errors.New(fmt.Sprintf("invalid setting value '%s'. must be 'on' or 'off'", settingValue)) + } + + uri := "/zones/" + zoneID + "/argo/smart_routing" + + res, err := api.makeRequest("PATCH", uri, ArgoFeatureSetting{Value: settingValue}) + if err != nil { + return ArgoFeatureSetting{}, errors.Wrap(err, errMakeRequestError) + } + + var argoDetailsResponse ArgoDetailsResponse + err = json.Unmarshal(res, &argoDetailsResponse) + if err != nil { + return ArgoFeatureSetting{}, errors.Wrap(err, errUnmarshalError) + } + return argoDetailsResponse.Result, nil +} + +// ArgoTieredCaching returns the current settings for tiered caching. +// +// API reference: TBA +func (api *API) ArgoTieredCaching(zoneID string) (ArgoFeatureSetting, error) { + uri := "/zones/" + zoneID + "/argo/tiered_caching" + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return ArgoFeatureSetting{}, errors.Wrap(err, errMakeRequestError) + } + + var argoDetailsResponse ArgoDetailsResponse + err = json.Unmarshal(res, &argoDetailsResponse) + if err != nil { + return ArgoFeatureSetting{}, errors.Wrap(err, errUnmarshalError) + } + return argoDetailsResponse.Result, nil +} + +// UpdateArgoTieredCaching updates the setting for tiered caching. +// +// API reference: TBA +func (api *API) UpdateArgoTieredCaching(zoneID, settingValue string) (ArgoFeatureSetting, error) { + if !contains(validSettingValues, settingValue) { + return ArgoFeatureSetting{}, errors.New(fmt.Sprintf("invalid setting value '%s'. must be 'on' or 'off'", settingValue)) + } + + uri := "/zones/" + zoneID + "/argo/tiered_caching" + + res, err := api.makeRequest("PATCH", uri, ArgoFeatureSetting{Value: settingValue}) + if err != nil { + return ArgoFeatureSetting{}, errors.Wrap(err, errMakeRequestError) + } + + var argoDetailsResponse ArgoDetailsResponse + err = json.Unmarshal(res, &argoDetailsResponse) + if err != nil { + return ArgoFeatureSetting{}, errors.Wrap(err, errUnmarshalError) + } + return argoDetailsResponse.Result, nil +} + +func contains(s []string, e string) bool { + for _, a := range s { + if a == e { + return true + } + } + return false +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/auditlogs.go b/vendor/github.com/cloudflare/cloudflare-go/auditlogs.go new file mode 100644 index 000000000..8cb8eab69 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/auditlogs.go @@ -0,0 +1,143 @@ +package cloudflare + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "time" +) + +// AuditLogAction is a member of AuditLog, the action that was taken. +type AuditLogAction struct { + Result bool `json:"result"` + Type string `json:"type"` +} + +// AuditLogActor is a member of AuditLog, who performed the action. +type AuditLogActor struct { + Email string `json:"email"` + ID string `json:"id"` + IP string `json:"ip"` + Type string `json:"type"` +} + +// AuditLogOwner is a member of AuditLog, who owns this audit log. +type AuditLogOwner struct { + ID string `json:"id"` +} + +// AuditLogResource is a member of AuditLog, what was the action performed on. +type AuditLogResource struct { + ID string `json:"id"` + Type string `json:"type"` +} + +// AuditLog is an resource that represents an update in the cloudflare dash +type AuditLog struct { + Action AuditLogAction `json:"action"` + Actor AuditLogActor `json:"actor"` + ID string `json:"id"` + Metadata map[string]interface{} `json:"metadata"` + NewValue string `json:"newValue"` + OldValue string `json:"oldValue"` + Owner AuditLogOwner `json:"owner"` + Resource AuditLogResource `json:"resource"` + When time.Time `json:"when"` +} + +// AuditLogResponse is the response returned from the cloudflare v4 api +type AuditLogResponse struct { + Response Response + Result []AuditLog `json:"result"` + ResultInfo `json:"result_info"` +} + +// AuditLogFilter is an object for filtering the audit log response from the api. +type AuditLogFilter struct { + ID string + ActorIP string + ActorEmail string + Direction string + ZoneName string + Since string + Before string + PerPage int + Page int +} + +// String turns an audit log filter in to an HTTP Query Param +// list. It will not inclue empty members of the struct in the +// query parameters. +func (a AuditLogFilter) String() string { + params := "?" + if a.ID != "" { + params += "&id=" + a.ID + } + if a.ActorIP != "" { + params += "&actor.ip=" + a.ActorIP + } + if a.ActorEmail != "" { + params += "&actor.email=" + a.ActorEmail + } + if a.ZoneName != "" { + params += "&zone.name=" + a.ZoneName + } + if a.Direction != "" { + params += "&direction=" + a.Direction + } + if a.Since != "" { + params += "&since=" + a.Since + } + if a.Before != "" { + params += "&before=" + a.Before + } + if a.PerPage > 0 { + params += "&per_page=" + fmt.Sprintf("%d", a.PerPage) + } + if a.Page > 0 { + params += "&page=" + fmt.Sprintf("%d", a.Page) + } + return params +} + +// GetOrganizationAuditLogs will return the audit logs of a specific +// organization, based on the ID passed in. The audit logs can be +// filtered based on any argument in the AuditLogFilter +// +// API Reference: https://api.cloudflare.com/#audit-logs-list-organization-audit-logs +func (api *API) GetOrganizationAuditLogs(organizationID string, a AuditLogFilter) (AuditLogResponse, error) { + uri := "/organizations/" + organizationID + "/audit_logs" + fmt.Sprintf("%s", a) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return AuditLogResponse{}, err + } + buf, err := base64.RawStdEncoding.DecodeString(string(res)) + if err != nil { + return AuditLogResponse{}, err + } + return unmarshalReturn(buf) +} + +// unmarshalReturn will unmarshal bytes and return an auditlogresponse +func unmarshalReturn(res []byte) (AuditLogResponse, error) { + var auditResponse AuditLogResponse + err := json.Unmarshal(res, &auditResponse) + if err != nil { + return auditResponse, err + } + return auditResponse, nil +} + +// GetUserAuditLogs will return your user's audit logs. The audit logs can be +// filtered based on any argument in the AuditLogFilter +// +// API Reference: https://api.cloudflare.com/#audit-logs-list-user-audit-logs +func (api *API) GetUserAuditLogs(a AuditLogFilter) (AuditLogResponse, error) { + uri := "/user/audit_logs" + fmt.Sprintf("%s", a) + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return AuditLogResponse{}, err + } + return unmarshalReturn(res) +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/cloudflare.go b/vendor/github.com/cloudflare/cloudflare-go/cloudflare.go new file mode 100644 index 000000000..498b9f468 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/cloudflare.go @@ -0,0 +1,435 @@ +// Package cloudflare implements the Cloudflare v4 API. +package cloudflare + +import ( + "bytes" + "context" + "encoding/json" + "io" + "io/ioutil" + "log" + "math" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "github.com/pkg/errors" + "golang.org/x/time/rate" +) + +const apiURL = "https://api.cloudflare.com/client/v4" + +const ( + // AuthKeyEmail specifies that we should authenticate with API key and email address + AuthKeyEmail = 1 << iota + // AuthUserService specifies that we should authenticate with a User-Service key + AuthUserService + // AuthToken specifies that we should authenticate with an API Token + AuthToken +) + +// API holds the configuration for the current API client. A client should not +// be modified concurrently. +type API struct { + APIKey string + APIEmail string + APIUserServiceKey string + APIToken string + BaseURL string + AccountID string + UserAgent string + headers http.Header + httpClient *http.Client + authType int + rateLimiter *rate.Limiter + retryPolicy RetryPolicy + logger Logger +} + +// newClient provides shared logic for New and NewWithUserServiceKey +func newClient(opts ...Option) (*API, error) { + silentLogger := log.New(ioutil.Discard, "", log.LstdFlags) + + api := &API{ + BaseURL: apiURL, + headers: make(http.Header), + rateLimiter: rate.NewLimiter(rate.Limit(4), 1), // 4rps equates to default api limit (1200 req/5 min) + retryPolicy: RetryPolicy{ + MaxRetries: 3, + MinRetryDelay: time.Duration(1) * time.Second, + MaxRetryDelay: time.Duration(30) * time.Second, + }, + logger: silentLogger, + } + + err := api.parseOptions(opts...) + if err != nil { + return nil, errors.Wrap(err, "options parsing failed") + } + + // Fall back to http.DefaultClient if the package user does not provide + // their own. + if api.httpClient == nil { + api.httpClient = http.DefaultClient + } + + return api, nil +} + +// New creates a new Cloudflare v4 API client. +func New(key, email string, opts ...Option) (*API, error) { + if key == "" || email == "" { + return nil, errors.New(errEmptyCredentials) + } + + api, err := newClient(opts...) + if err != nil { + return nil, err + } + + api.APIKey = key + api.APIEmail = email + api.authType = AuthKeyEmail + + return api, nil +} + +// NewWithAPIToken creates a new Cloudflare v4 API client using API Tokens +func NewWithAPIToken(token string, opts ...Option) (*API, error) { + if token == "" { + return nil, errors.New(errEmptyAPIToken) + } + + api, err := newClient(opts...) + if err != nil { + return nil, err + } + + api.APIToken = token + api.authType = AuthToken + + return api, nil +} + +// NewWithUserServiceKey creates a new Cloudflare v4 API client using service key authentication. +func NewWithUserServiceKey(key string, opts ...Option) (*API, error) { + if key == "" { + return nil, errors.New(errEmptyCredentials) + } + + api, err := newClient(opts...) + if err != nil { + return nil, err + } + + api.APIUserServiceKey = key + api.authType = AuthUserService + + return api, nil +} + +// SetAuthType sets the authentication method (AuthKeyEmail, AuthToken, or AuthUserService). +func (api *API) SetAuthType(authType int) { + api.authType = authType +} + +// ZoneIDByName retrieves a zone's ID from the name. +func (api *API) ZoneIDByName(zoneName string) (string, error) { + res, err := api.ListZonesContext(context.TODO(), WithZoneFilter(zoneName)) + if err != nil { + return "", errors.Wrap(err, "ListZonesContext command failed") + } + + if len(res.Result) > 1 && api.AccountID == "" { + return "", errors.New("ambiguous zone name used without an account ID") + } + + for _, zone := range res.Result { + if api.AccountID != "" { + if zone.Name == zoneName && api.AccountID == zone.Account.ID { + return zone.ID, nil + } + } else { + if zone.Name == zoneName { + return zone.ID, nil + } + } + } + + return "", errors.New("Zone could not be found") +} + +// makeRequest makes a HTTP request and returns the body as a byte slice, +// closing it before returning. params will be serialized to JSON. +func (api *API) makeRequest(method, uri string, params interface{}) ([]byte, error) { + return api.makeRequestWithAuthType(context.TODO(), method, uri, params, api.authType) +} + +func (api *API) makeRequestContext(ctx context.Context, method, uri string, params interface{}) ([]byte, error) { + return api.makeRequestWithAuthType(ctx, method, uri, params, api.authType) +} + +func (api *API) makeRequestWithHeaders(method, uri string, params interface{}, headers http.Header) ([]byte, error) { + return api.makeRequestWithAuthTypeAndHeaders(context.TODO(), method, uri, params, api.authType, headers) +} + +func (api *API) makeRequestWithAuthType(ctx context.Context, method, uri string, params interface{}, authType int) ([]byte, error) { + return api.makeRequestWithAuthTypeAndHeaders(ctx, method, uri, params, authType, nil) +} + +func (api *API) makeRequestWithAuthTypeAndHeaders(ctx context.Context, method, uri string, params interface{}, authType int, headers http.Header) ([]byte, error) { + // Replace nil with a JSON object if needed + var jsonBody []byte + var err error + + if params != nil { + if paramBytes, ok := params.([]byte); ok { + jsonBody = paramBytes + } else { + jsonBody, err = json.Marshal(params) + if err != nil { + return nil, errors.Wrap(err, "error marshalling params to JSON") + } + } + } else { + jsonBody = nil + } + + var resp *http.Response + var respErr error + var reqBody io.Reader + var respBody []byte + for i := 0; i <= api.retryPolicy.MaxRetries; i++ { + if jsonBody != nil { + reqBody = bytes.NewReader(jsonBody) + } + if i > 0 { + // expect the backoff introduced here on errored requests to dominate the effect of rate limiting + // don't need a random component here as the rate limiter should do something similar + // nb time duration could truncate an arbitrary float. Since our inputs are all ints, we should be ok + sleepDuration := time.Duration(math.Pow(2, float64(i-1)) * float64(api.retryPolicy.MinRetryDelay)) + + if sleepDuration > api.retryPolicy.MaxRetryDelay { + sleepDuration = api.retryPolicy.MaxRetryDelay + } + // useful to do some simple logging here, maybe introduce levels later + api.logger.Printf("Sleeping %s before retry attempt number %d for request %s %s", sleepDuration.String(), i, method, uri) + time.Sleep(sleepDuration) + + } + err = api.rateLimiter.Wait(context.TODO()) + if err != nil { + return nil, errors.Wrap(err, "Error caused by request rate limiting") + } + resp, respErr = api.request(ctx, method, uri, reqBody, authType, headers) + + // retry if the server is rate limiting us or if it failed + // assumes server operations are rolled back on failure + if respErr != nil || resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= 500 { + // if we got a valid http response, try to read body so we can reuse the connection + // see https://golang.org/pkg/net/http/#Client.Do + if respErr == nil { + respBody, err = ioutil.ReadAll(resp.Body) + resp.Body.Close() + + respErr = errors.Wrap(err, "could not read response body") + + api.logger.Printf("Request: %s %s got an error response %d: %s\n", method, uri, resp.StatusCode, + strings.Replace(strings.Replace(string(respBody), "\n", "", -1), "\t", "", -1)) + } else { + api.logger.Printf("Error performing request: %s %s : %s \n", method, uri, respErr.Error()) + } + continue + } else { + respBody, err = ioutil.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + return nil, errors.Wrap(err, "could not read response body") + } + break + } + } + if respErr != nil { + return nil, respErr + } + + switch { + case resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusMultipleChoices: + case resp.StatusCode == http.StatusUnauthorized: + return nil, errors.Errorf("HTTP status %d: invalid credentials", resp.StatusCode) + case resp.StatusCode == http.StatusForbidden: + return nil, errors.Errorf("HTTP status %d: insufficient permissions", resp.StatusCode) + case resp.StatusCode == http.StatusServiceUnavailable, + resp.StatusCode == http.StatusBadGateway, + resp.StatusCode == http.StatusGatewayTimeout, + resp.StatusCode == 522, + resp.StatusCode == 523, + resp.StatusCode == 524: + return nil, errors.Errorf("HTTP status %d: service failure", resp.StatusCode) + // This isn't a great solution due to the way the `default` case is + // a catch all and that the `filters/validate-expr` returns a HTTP 400 + // yet the clients need to use the HTTP body as a JSON string. + case resp.StatusCode == 400 && strings.HasSuffix(resp.Request.URL.Path, "/filters/validate-expr"): + return nil, errors.Errorf("%s", respBody) + default: + var s string + if respBody != nil { + s = string(respBody) + } + return nil, errors.Errorf("HTTP status %d: content %q", resp.StatusCode, s) + } + + return respBody, nil +} + +// request makes a HTTP request to the given API endpoint, returning the raw +// *http.Response, or an error if one occurred. The caller is responsible for +// closing the response body. +func (api *API) request(ctx context.Context, method, uri string, reqBody io.Reader, authType int, headers http.Header) (*http.Response, error) { + req, err := http.NewRequest(method, api.BaseURL+uri, reqBody) + if err != nil { + return nil, errors.Wrap(err, "HTTP request creation failed") + } + req.WithContext(ctx) + + combinedHeaders := make(http.Header) + copyHeader(combinedHeaders, api.headers) + copyHeader(combinedHeaders, headers) + req.Header = combinedHeaders + + if authType&AuthKeyEmail != 0 { + req.Header.Set("X-Auth-Key", api.APIKey) + req.Header.Set("X-Auth-Email", api.APIEmail) + } + if authType&AuthUserService != 0 { + req.Header.Set("X-Auth-User-Service-Key", api.APIUserServiceKey) + } + if authType&AuthToken != 0 { + req.Header.Set("Authorization", "Bearer "+api.APIToken) + } + + if api.UserAgent != "" { + req.Header.Set("User-Agent", api.UserAgent) + } + + if req.Header.Get("Content-Type") == "" { + req.Header.Set("Content-Type", "application/json") + } + + resp, err := api.httpClient.Do(req) + if err != nil { + return nil, errors.Wrap(err, "HTTP request failed") + } + + return resp, nil +} + +// Returns the base URL to use for API endpoints that exist for accounts. +// If an account option was used when creating the API instance, returns +// the account URL. +// +// accountBase is the base URL for endpoints referring to the current user. +// It exists as a parameter because it is not consistent across APIs. +func (api *API) userBaseURL(accountBase string) string { + if api.AccountID != "" { + return "/accounts/" + api.AccountID + } + return accountBase +} + +// copyHeader copies all headers for `source` and sets them on `target`. +// based on https://godoc.org/github.com/golang/gddo/httputil/header#Copy +func copyHeader(target, source http.Header) { + for k, vs := range source { + target[k] = vs + } +} + +// ResponseInfo contains a code and message returned by the API as errors or +// informational messages inside the response. +type ResponseInfo struct { + Code int `json:"code"` + Message string `json:"message"` +} + +// Response is a template. There will also be a result struct. There will be a +// unique response type for each response, which will include this type. +type Response struct { + Success bool `json:"success"` + Errors []ResponseInfo `json:"errors"` + Messages []ResponseInfo `json:"messages"` +} + +// ResultInfo contains metadata about the Response. +type ResultInfo struct { + Page int `json:"page"` + PerPage int `json:"per_page"` + TotalPages int `json:"total_pages"` + Count int `json:"count"` + Total int `json:"total_count"` +} + +// RawResponse keeps the result as JSON form +type RawResponse struct { + Response + Result json.RawMessage `json:"result"` +} + +// Raw makes a HTTP request with user provided params and returns the +// result as untouched JSON. +func (api *API) Raw(method, endpoint string, data interface{}) (json.RawMessage, error) { + res, err := api.makeRequest(method, endpoint, data) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + var r RawResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// PaginationOptions can be passed to a list request to configure paging +// These values will be defaulted if omitted, and PerPage has min/max limits set by resource +type PaginationOptions struct { + Page int `json:"page,omitempty"` + PerPage int `json:"per_page,omitempty"` +} + +// RetryPolicy specifies number of retries and min/max retry delays +// This config is used when the client exponentially backs off after errored requests +type RetryPolicy struct { + MaxRetries int + MinRetryDelay time.Duration + MaxRetryDelay time.Duration +} + +// Logger defines the interface this library needs to use logging +// This is a subset of the methods implemented in the log package +type Logger interface { + Printf(format string, v ...interface{}) +} + +// ReqOption is a functional option for configuring API requests +type ReqOption func(opt *reqOption) +type reqOption struct { + params url.Values +} + +// WithZoneFilter applies a filter based on zone name. +func WithZoneFilter(zone string) ReqOption { + return func(opt *reqOption) { + opt.params.Set("name", zone) + } +} + +// WithPagination configures the pagination for a response. +func WithPagination(opts PaginationOptions) ReqOption { + return func(opt *reqOption) { + opt.params.Set("page", strconv.Itoa(opts.Page)) + opt.params.Set("per_page", strconv.Itoa(opts.PerPage)) + } +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/custom_hostname.go b/vendor/github.com/cloudflare/cloudflare-go/custom_hostname.go new file mode 100644 index 000000000..03216938b --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/custom_hostname.go @@ -0,0 +1,160 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "strconv" + + "github.com/pkg/errors" +) + +// CustomHostnameSSLSettings represents the SSL settings for a custom hostname. +type CustomHostnameSSLSettings struct { + HTTP2 string `json:"http2,omitempty"` + TLS13 string `json:"tls_1_3,omitempty"` + MinTLSVersion string `json:"min_tls_version,omitempty"` + Ciphers []string `json:"ciphers,omitempty"` +} + +// CustomHostnameSSL represents the SSL section in a given custom hostname. +type CustomHostnameSSL struct { + Status string `json:"status,omitempty"` + Method string `json:"method,omitempty"` + Type string `json:"type,omitempty"` + CnameTarget string `json:"cname_target,omitempty"` + CnameName string `json:"cname,omitempty"` + Settings CustomHostnameSSLSettings `json:"settings,omitempty"` +} + +// CustomMetadata defines custom metadata for the hostname. This requires logic to be implemented by Cloudflare to act on the data provided. +type CustomMetadata map[string]interface{} + +// CustomHostname represents a custom hostname in a zone. +type CustomHostname struct { + ID string `json:"id,omitempty"` + Hostname string `json:"hostname,omitempty"` + SSL CustomHostnameSSL `json:"ssl,omitempty"` + CustomMetadata CustomMetadata `json:"custom_metadata,omitempty"` +} + +// CustomHostnameResponse represents a response from the Custom Hostnames endpoints. +type CustomHostnameResponse struct { + Result CustomHostname `json:"result"` + Response +} + +// CustomHostnameListResponse represents a response from the Custom Hostnames endpoints. +type CustomHostnameListResponse struct { + Result []CustomHostname `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// UpdateCustomHostnameSSL modifies SSL configuration for the given custom +// hostname in the given zone. +// +// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-update-custom-hostname-configuration +func (api *API) UpdateCustomHostnameSSL(zoneID string, customHostnameID string, ssl CustomHostnameSSL) (CustomHostname, error) { + return CustomHostname{}, errors.New("Not implemented") +} + +// DeleteCustomHostname deletes a custom hostname (and any issued SSL +// certificates). +// +// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-delete-a-custom-hostname-and-any-issued-ssl-certificates- +func (api *API) DeleteCustomHostname(zoneID string, customHostnameID string) error { + uri := "/zones/" + zoneID + "/custom_hostnames/" + customHostnameID + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + var response *CustomHostnameResponse + err = json.Unmarshal(res, &response) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + + return nil +} + +// CreateCustomHostname creates a new custom hostname and requests that an SSL certificate be issued for it. +// +// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-create-custom-hostname +func (api *API) CreateCustomHostname(zoneID string, ch CustomHostname) (*CustomHostnameResponse, error) { + uri := "/zones/" + zoneID + "/custom_hostnames" + res, err := api.makeRequest("POST", uri, ch) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + var response *CustomHostnameResponse + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// CustomHostnames fetches custom hostnames for the given zone, +// by applying filter.Hostname if not empty and scoping the result to page'th 50 items. +// +// The returned ResultInfo can be used to implement pagination. +// +// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-list-custom-hostnames +func (api *API) CustomHostnames(zoneID string, page int, filter CustomHostname) ([]CustomHostname, ResultInfo, error) { + v := url.Values{} + v.Set("per_page", "50") + v.Set("page", strconv.Itoa(page)) + if filter.Hostname != "" { + v.Set("hostname", filter.Hostname) + } + query := "?" + v.Encode() + + uri := "/zones/" + zoneID + "/custom_hostnames" + query + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []CustomHostname{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError) + } + var customHostnameListResponse CustomHostnameListResponse + err = json.Unmarshal(res, &customHostnameListResponse) + if err != nil { + return []CustomHostname{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError) + } + + return customHostnameListResponse.Result, customHostnameListResponse.ResultInfo, nil +} + +// CustomHostname inspects the given custom hostname in the given zone. +// +// API reference: https://api.cloudflare.com/#custom-hostname-for-a-zone-custom-hostname-configuration-details +func (api *API) CustomHostname(zoneID string, customHostnameID string) (CustomHostname, error) { + uri := "/zones/" + zoneID + "/custom_hostnames/" + customHostnameID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return CustomHostname{}, errors.Wrap(err, errMakeRequestError) + } + + var response CustomHostnameResponse + err = json.Unmarshal(res, &response) + if err != nil { + return CustomHostname{}, errors.Wrap(err, errUnmarshalError) + } + + return response.Result, nil +} + +// CustomHostnameIDByName retrieves the ID for the given hostname in the given zone. +func (api *API) CustomHostnameIDByName(zoneID string, hostname string) (string, error) { + customHostnames, _, err := api.CustomHostnames(zoneID, 1, CustomHostname{Hostname: hostname}) + if err != nil { + return "", errors.Wrap(err, "CustomHostnames command failed") + } + for _, ch := range customHostnames { + if ch.Hostname == hostname { + return ch.ID, nil + } + } + return "", errors.New("CustomHostname could not be found") +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/custom_pages.go b/vendor/github.com/cloudflare/cloudflare-go/custom_pages.go new file mode 100644 index 000000000..d96788fc8 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/custom_pages.go @@ -0,0 +1,176 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/pkg/errors" +) + +// CustomPage represents a custom page configuration. +type CustomPage struct { + CreatedOn time.Time `json:"created_on"` + ModifiedOn time.Time `json:"modified_on"` + URL interface{} `json:"url"` + State string `json:"state"` + RequiredTokens []string `json:"required_tokens"` + PreviewTarget string `json:"preview_target"` + Description string `json:"description"` + ID string `json:"id"` +} + +// CustomPageResponse represents the response from the custom pages endpoint. +type CustomPageResponse struct { + Response + Result []CustomPage `json:"result"` +} + +// CustomPageDetailResponse represents the response from the custom page endpoint. +type CustomPageDetailResponse struct { + Response + Result CustomPage `json:"result"` +} + +// CustomPageOptions is used to determine whether or not the operation +// should take place on an account or zone level based on which is +// provided to the function. +// +// A non-empty value denotes desired use. +type CustomPageOptions struct { + AccountID string + ZoneID string +} + +// CustomPageParameters is used to update a particular custom page with +// the values provided. +type CustomPageParameters struct { + URL interface{} `json:"url"` + State string `json:"state"` +} + +// CustomPages lists custom pages for a zone or account. +// +// Zone API reference: https://api.cloudflare.com/#custom-pages-for-a-zone-list-available-custom-pages +// Account API reference: https://api.cloudflare.com/#custom-pages-account--list-custom-pages +func (api *API) CustomPages(options *CustomPageOptions) ([]CustomPage, error) { + var ( + pageType, identifier string + ) + + if options.AccountID == "" && options.ZoneID == "" { + return nil, errors.New("either account ID or zone ID must be provided") + } + + if options.AccountID != "" && options.ZoneID != "" { + return nil, errors.New("account ID and zone ID are mutually exclusive") + } + + // Should the account ID be defined, treat this as an account level operation. + if options.AccountID != "" { + pageType = "accounts" + identifier = options.AccountID + } else { + pageType = "zones" + identifier = options.ZoneID + } + + uri := fmt.Sprintf("/%s/%s/custom_pages", pageType, identifier) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + var customPageResponse CustomPageResponse + err = json.Unmarshal(res, &customPageResponse) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return customPageResponse.Result, nil +} + +// CustomPage lists a single custom page based on the ID. +// +// Zone API reference: https://api.cloudflare.com/#custom-pages-for-a-zone-custom-page-details +// Account API reference: https://api.cloudflare.com/#custom-pages-account--custom-page-details +func (api *API) CustomPage(options *CustomPageOptions, customPageID string) (CustomPage, error) { + var ( + pageType, identifier string + ) + + if options.AccountID == "" && options.ZoneID == "" { + return CustomPage{}, errors.New("either account ID or zone ID must be provided") + } + + if options.AccountID != "" && options.ZoneID != "" { + return CustomPage{}, errors.New("account ID and zone ID are mutually exclusive") + } + + // Should the account ID be defined, treat this as an account level operation. + if options.AccountID != "" { + pageType = "accounts" + identifier = options.AccountID + } else { + pageType = "zones" + identifier = options.ZoneID + } + + uri := fmt.Sprintf("/%s/%s/custom_pages/%s", pageType, identifier, customPageID) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return CustomPage{}, errors.Wrap(err, errMakeRequestError) + } + + var customPageResponse CustomPageDetailResponse + err = json.Unmarshal(res, &customPageResponse) + if err != nil { + return CustomPage{}, errors.Wrap(err, errUnmarshalError) + } + + return customPageResponse.Result, nil +} + +// UpdateCustomPage updates a single custom page setting. +// +// Zone API reference: https://api.cloudflare.com/#custom-pages-for-a-zone-update-custom-page-url +// Account API reference: https://api.cloudflare.com/#custom-pages-account--update-custom-page +func (api *API) UpdateCustomPage(options *CustomPageOptions, customPageID string, pageParameters CustomPageParameters) (CustomPage, error) { + var ( + pageType, identifier string + ) + + if options.AccountID == "" && options.ZoneID == "" { + return CustomPage{}, errors.New("either account ID or zone ID must be provided") + } + + if options.AccountID != "" && options.ZoneID != "" { + return CustomPage{}, errors.New("account ID and zone ID are mutually exclusive") + } + + // Should the account ID be defined, treat this as an account level operation. + if options.AccountID != "" { + pageType = "accounts" + identifier = options.AccountID + } else { + pageType = "zones" + identifier = options.ZoneID + } + + uri := fmt.Sprintf("/%s/%s/custom_pages/%s", pageType, identifier, customPageID) + + res, err := api.makeRequest("PUT", uri, pageParameters) + if err != nil { + return CustomPage{}, errors.Wrap(err, errMakeRequestError) + } + + var customPageResponse CustomPageDetailResponse + err = json.Unmarshal(res, &customPageResponse) + if err != nil { + return CustomPage{}, errors.Wrap(err, errUnmarshalError) + } + + return customPageResponse.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/dns.go b/vendor/github.com/cloudflare/cloudflare-go/dns.go new file mode 100644 index 000000000..6bcac2480 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/dns.go @@ -0,0 +1,174 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "strconv" + "time" + + "github.com/pkg/errors" +) + +// DNSRecord represents a DNS record in a zone. +type DNSRecord struct { + ID string `json:"id,omitempty"` + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + Content string `json:"content,omitempty"` + Proxiable bool `json:"proxiable,omitempty"` + Proxied bool `json:"proxied"` + TTL int `json:"ttl,omitempty"` + Locked bool `json:"locked,omitempty"` + ZoneID string `json:"zone_id,omitempty"` + ZoneName string `json:"zone_name,omitempty"` + CreatedOn time.Time `json:"created_on,omitempty"` + ModifiedOn time.Time `json:"modified_on,omitempty"` + Data interface{} `json:"data,omitempty"` // data returned by: SRV, LOC + Meta interface{} `json:"meta,omitempty"` + Priority int `json:"priority"` +} + +// DNSRecordResponse represents the response from the DNS endpoint. +type DNSRecordResponse struct { + Result DNSRecord `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// DNSListResponse represents the response from the list DNS records endpoint. +type DNSListResponse struct { + Result []DNSRecord `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// CreateDNSRecord creates a DNS record for the zone identifier. +// +// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-create-dns-record +func (api *API) CreateDNSRecord(zoneID string, rr DNSRecord) (*DNSRecordResponse, error) { + uri := "/zones/" + zoneID + "/dns_records" + res, err := api.makeRequest("POST", uri, rr) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + var recordResp *DNSRecordResponse + err = json.Unmarshal(res, &recordResp) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return recordResp, nil +} + +// DNSRecords returns a slice of DNS records for the given zone identifier. +// +// This takes a DNSRecord to allow filtering of the results returned. +// +// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-list-dns-records +func (api *API) DNSRecords(zoneID string, rr DNSRecord) ([]DNSRecord, error) { + // Construct a query string + v := url.Values{} + // Request as many records as possible per page - API max is 50 + v.Set("per_page", "50") + if rr.Name != "" { + v.Set("name", rr.Name) + } + if rr.Type != "" { + v.Set("type", rr.Type) + } + if rr.Content != "" { + v.Set("content", rr.Content) + } + + var query string + var records []DNSRecord + page := 1 + + // Loop over makeRequest until what we've fetched all records + for { + v.Set("page", strconv.Itoa(page)) + query = "?" + v.Encode() + uri := "/zones/" + zoneID + "/dns_records" + query + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []DNSRecord{}, errors.Wrap(err, errMakeRequestError) + } + var r DNSListResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []DNSRecord{}, errors.Wrap(err, errUnmarshalError) + } + records = append(records, r.Result...) + if r.ResultInfo.Page >= r.ResultInfo.TotalPages { + break + } + // Loop around and fetch the next page + page++ + } + return records, nil +} + +// DNSRecord returns a single DNS record for the given zone & record +// identifiers. +// +// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-dns-record-details +func (api *API) DNSRecord(zoneID, recordID string) (DNSRecord, error) { + uri := "/zones/" + zoneID + "/dns_records/" + recordID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return DNSRecord{}, errors.Wrap(err, errMakeRequestError) + } + var r DNSRecordResponse + err = json.Unmarshal(res, &r) + if err != nil { + return DNSRecord{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// UpdateDNSRecord updates a single DNS record for the given zone & record +// identifiers. +// +// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record +func (api *API) UpdateDNSRecord(zoneID, recordID string, rr DNSRecord) error { + rec, err := api.DNSRecord(zoneID, recordID) + if err != nil { + return err + } + // Populate the record name from the existing one if the update didn't + // specify it. + if rr.Name == "" { + rr.Name = rec.Name + } + rr.Type = rec.Type + uri := "/zones/" + zoneID + "/dns_records/" + recordID + res, err := api.makeRequest("PATCH", uri, rr) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + var r DNSRecordResponse + err = json.Unmarshal(res, &r) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + return nil +} + +// DeleteDNSRecord deletes a single DNS record for the given zone & record +// identifiers. +// +// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-delete-dns-record +func (api *API) DeleteDNSRecord(zoneID, recordID string) error { + uri := "/zones/" + zoneID + "/dns_records/" + recordID + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + var r DNSRecordResponse + err = json.Unmarshal(res, &r) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/duration.go b/vendor/github.com/cloudflare/cloudflare-go/duration.go new file mode 100644 index 000000000..ba2418acd --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/duration.go @@ -0,0 +1,40 @@ +package cloudflare + +import ( + "encoding/json" + "time" +) + +// Duration implements json.Marshaler and json.Unmarshaler for time.Duration +// using the fmt.Stringer interface of time.Duration and time.ParseDuration. +type Duration struct { + time.Duration +} + +// MarshalJSON encodes a Duration as a JSON string formatted using String. +func (d Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(d.Duration.String()) +} + +// UnmarshalJSON decodes a Duration from a JSON string parsed using time.ParseDuration. +func (d *Duration) UnmarshalJSON(buf []byte) error { + var str string + + err := json.Unmarshal(buf, &str) + if err != nil { + return err + } + + dur, err := time.ParseDuration(str) + if err != nil { + return err + } + + d.Duration = dur + return nil +} + +var ( + _ = json.Marshaler((*Duration)(nil)) + _ = json.Unmarshaler((*Duration)(nil)) +) diff --git a/vendor/github.com/cloudflare/cloudflare-go/errors.go b/vendor/github.com/cloudflare/cloudflare-go/errors.go new file mode 100644 index 000000000..21c38b168 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/errors.go @@ -0,0 +1,50 @@ +package cloudflare + +// Error messages +const ( + errEmptyCredentials = "invalid credentials: key & email must not be empty" + errEmptyAPIToken = "invalid credentials: API Token must not be empty" + errMakeRequestError = "error from makeRequest" + errUnmarshalError = "error unmarshalling the JSON response" + errRequestNotSuccessful = "error reported by API" + errMissingAccountID = "account ID is empty and must be provided" +) + +var _ Error = &UserError{} + +// Error represents an error returned from this library. +type Error interface { + error + // Raised when user credentials or configuration is invalid. + User() bool + // Raised when a parsing error (e.g. JSON) occurs. + Parse() bool + // Raised when a network error occurs. + Network() bool + // Contains the most recent error. +} + +// UserError represents a user-generated error. +type UserError struct { + Err error +} + +// User is a user-caused error. +func (e *UserError) User() bool { + return true +} + +// Network error. +func (e *UserError) Network() bool { + return false +} + +// Parse error. +func (e *UserError) Parse() bool { + return true +} + +// Error wraps the underlying error. +func (e *UserError) Error() string { + return e.Err.Error() +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/filter.go b/vendor/github.com/cloudflare/cloudflare-go/filter.go new file mode 100644 index 000000000..cf3ef1c20 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/filter.go @@ -0,0 +1,241 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "net/url" + "strconv" + "strings" + + "github.com/pkg/errors" +) + +// Filter holds the structure of the filter type. +type Filter struct { + ID string `json:"id,omitempty"` + Expression string `json:"expression"` + Paused bool `json:"paused"` + Description string `json:"description"` + + // Property is mentioned in documentation however isn't populated in + // any of the API requests. For now, let's just omit it unless it's + // provided. + Ref string `json:"ref,omitempty"` +} + +// FiltersDetailResponse is the API response that is returned +// for requesting all filters on a zone. +type FiltersDetailResponse struct { + Result []Filter `json:"result"` + ResultInfo `json:"result_info"` + Response +} + +// FilterDetailResponse is the API response that is returned +// for requesting a single filter on a zone. +type FilterDetailResponse struct { + Result Filter `json:"result"` + ResultInfo `json:"result_info"` + Response +} + +// FilterValidateExpression represents the JSON payload for checking +// an expression. +type FilterValidateExpression struct { + Expression string `json:"expression"` +} + +// FilterValidateExpressionResponse represents the API response for +// checking the expression. It conforms to the JSON API approach however +// we don't need all of the fields exposed. +type FilterValidateExpressionResponse struct { + Success bool `json:"success"` + Errors []FilterValidationExpressionMessage `json:"errors"` +} + +// FilterValidationExpressionMessage represents the API error message. +type FilterValidationExpressionMessage struct { + Message string `json:"message"` +} + +// Filter returns a single filter in a zone based on the filter ID. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-filters/get/#get-by-filter-id +func (api *API) Filter(zoneID, filterID string) (Filter, error) { + uri := fmt.Sprintf("/zones/%s/filters/%s", zoneID, filterID) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return Filter{}, errors.Wrap(err, errMakeRequestError) + } + + var filterResponse FilterDetailResponse + err = json.Unmarshal(res, &filterResponse) + if err != nil { + return Filter{}, errors.Wrap(err, errUnmarshalError) + } + + return filterResponse.Result, nil +} + +// Filters returns all filters for a zone. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-filters/get/#get-all-filters +func (api *API) Filters(zoneID string, pageOpts PaginationOptions) ([]Filter, error) { + uri := "/zones/" + zoneID + "/filters" + v := url.Values{} + + if pageOpts.PerPage > 0 { + v.Set("per_page", strconv.Itoa(pageOpts.PerPage)) + } + + if pageOpts.Page > 0 { + v.Set("page", strconv.Itoa(pageOpts.Page)) + } + + if len(v) > 0 { + uri = uri + "?" + v.Encode() + } + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []Filter{}, errors.Wrap(err, errMakeRequestError) + } + + var filtersResponse FiltersDetailResponse + err = json.Unmarshal(res, &filtersResponse) + if err != nil { + return []Filter{}, errors.Wrap(err, errUnmarshalError) + } + + return filtersResponse.Result, nil +} + +// CreateFilters creates new filters. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-filters/post/ +func (api *API) CreateFilters(zoneID string, filters []Filter) ([]Filter, error) { + uri := "/zones/" + zoneID + "/filters" + + res, err := api.makeRequest("POST", uri, filters) + if err != nil { + return []Filter{}, errors.Wrap(err, errMakeRequestError) + } + + var filtersResponse FiltersDetailResponse + err = json.Unmarshal(res, &filtersResponse) + if err != nil { + return []Filter{}, errors.Wrap(err, errUnmarshalError) + } + + return filtersResponse.Result, nil +} + +// UpdateFilter updates a single filter. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-filters/put/#update-a-single-filter +func (api *API) UpdateFilter(zoneID string, filter Filter) (Filter, error) { + if filter.ID == "" { + return Filter{}, errors.Errorf("filter ID cannot be empty") + } + + uri := fmt.Sprintf("/zones/%s/filters/%s", zoneID, filter.ID) + + res, err := api.makeRequest("PUT", uri, filter) + if err != nil { + return Filter{}, errors.Wrap(err, errMakeRequestError) + } + + var filterResponse FilterDetailResponse + err = json.Unmarshal(res, &filterResponse) + if err != nil { + return Filter{}, errors.Wrap(err, errUnmarshalError) + } + + return filterResponse.Result, nil +} + +// UpdateFilters updates many filters at once. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-filters/put/#update-multiple-filters +func (api *API) UpdateFilters(zoneID string, filters []Filter) ([]Filter, error) { + for _, filter := range filters { + if filter.ID == "" { + return []Filter{}, errors.Errorf("filter ID cannot be empty") + } + } + + uri := "/zones/" + zoneID + "/filters" + + res, err := api.makeRequest("PUT", uri, filters) + if err != nil { + return []Filter{}, errors.Wrap(err, errMakeRequestError) + } + + var filtersResponse FiltersDetailResponse + err = json.Unmarshal(res, &filtersResponse) + if err != nil { + return []Filter{}, errors.Wrap(err, errUnmarshalError) + } + + return filtersResponse.Result, nil +} + +// DeleteFilter deletes a single filter. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-filters/delete/#delete-a-single-filter +func (api *API) DeleteFilter(zoneID, filterID string) error { + if filterID == "" { + return errors.Errorf("filter ID cannot be empty") + } + + uri := fmt.Sprintf("/zones/%s/filters/%s", zoneID, filterID) + + _, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} + +// DeleteFilters deletes multiple filters. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-filters/delete/#delete-multiple-filters +func (api *API) DeleteFilters(zoneID string, filterIDs []string) error { + ids := strings.Join(filterIDs, ",") + uri := fmt.Sprintf("/zones/%s/filters?id=%s", zoneID, ids) + + _, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} + +// ValidateFilterExpression checks correctness of a filter expression. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-filters/validation/ +func (api *API) ValidateFilterExpression(expression string) error { + uri := fmt.Sprintf("/filters/validate-expr") + expressionPayload := FilterValidateExpression{Expression: expression} + + _, err := api.makeRequest("POST", uri, expressionPayload) + if err != nil { + var filterValidationResponse FilterValidateExpressionResponse + + jsonErr := json.Unmarshal([]byte(err.Error()), &filterValidationResponse) + if jsonErr != nil { + return errors.Wrap(jsonErr, errUnmarshalError) + } + + if filterValidationResponse.Success != true { + // Unsure why but the API returns `errors` as an array but it only + // ever shows the issue with one problem at a time ¯\_(ツ)_/¯ + return errors.Errorf(filterValidationResponse.Errors[0].Message) + } + } + + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/firewall.go b/vendor/github.com/cloudflare/cloudflare-go/firewall.go new file mode 100644 index 000000000..4b61a7ca5 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/firewall.go @@ -0,0 +1,280 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "strconv" + "time" + + "github.com/pkg/errors" +) + +// AccessRule represents a firewall access rule. +type AccessRule struct { + ID string `json:"id,omitempty"` + Notes string `json:"notes,omitempty"` + AllowedModes []string `json:"allowed_modes,omitempty"` + Mode string `json:"mode,omitempty"` + Configuration AccessRuleConfiguration `json:"configuration,omitempty"` + Scope AccessRuleScope `json:"scope,omitempty"` + CreatedOn time.Time `json:"created_on,omitempty"` + ModifiedOn time.Time `json:"modified_on,omitempty"` +} + +// AccessRuleConfiguration represents the configuration of a firewall +// access rule. +type AccessRuleConfiguration struct { + Target string `json:"target,omitempty"` + Value string `json:"value,omitempty"` +} + +// AccessRuleScope represents the scope of a firewall access rule. +type AccessRuleScope struct { + ID string `json:"id,omitempty"` + Email string `json:"email,omitempty"` + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` +} + +// AccessRuleResponse represents the response from the firewall access +// rule endpoint. +type AccessRuleResponse struct { + Result AccessRule `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// AccessRuleListResponse represents the response from the list access rules +// endpoint. +type AccessRuleListResponse struct { + Result []AccessRule `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// ListUserAccessRules returns a slice of access rules for the logged-in user. +// +// This takes an AccessRule to allow filtering of the results returned. +// +// API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-list-access-rules +func (api *API) ListUserAccessRules(accessRule AccessRule, page int) (*AccessRuleListResponse, error) { + return api.listAccessRules("/user", accessRule, page) +} + +// CreateUserAccessRule creates a firewall access rule for the logged-in user. +// +// API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-create-access-rule +func (api *API) CreateUserAccessRule(accessRule AccessRule) (*AccessRuleResponse, error) { + return api.createAccessRule("/user", accessRule) +} + +// UserAccessRule returns the details of a user's account access rule. +// +// API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-list-access-rules +func (api *API) UserAccessRule(accessRuleID string) (*AccessRuleResponse, error) { + return api.retrieveAccessRule("/user", accessRuleID) +} + +// UpdateUserAccessRule updates a single access rule for the logged-in user & +// given access rule identifier. +// +// API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-update-access-rule +func (api *API) UpdateUserAccessRule(accessRuleID string, accessRule AccessRule) (*AccessRuleResponse, error) { + return api.updateAccessRule("/user", accessRuleID, accessRule) +} + +// DeleteUserAccessRule deletes a single access rule for the logged-in user and +// access rule identifiers. +// +// API reference: https://api.cloudflare.com/#user-level-firewall-access-rule-update-access-rule +func (api *API) DeleteUserAccessRule(accessRuleID string) (*AccessRuleResponse, error) { + return api.deleteAccessRule("/user", accessRuleID) +} + +// ListZoneAccessRules returns a slice of access rules for the given zone +// identifier. +// +// This takes an AccessRule to allow filtering of the results returned. +// +// API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-list-access-rules +func (api *API) ListZoneAccessRules(zoneID string, accessRule AccessRule, page int) (*AccessRuleListResponse, error) { + return api.listAccessRules("/zones/"+zoneID, accessRule, page) +} + +// CreateZoneAccessRule creates a firewall access rule for the given zone +// identifier. +// +// API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-create-access-rule +func (api *API) CreateZoneAccessRule(zoneID string, accessRule AccessRule) (*AccessRuleResponse, error) { + return api.createAccessRule("/zones/"+zoneID, accessRule) +} + +// ZoneAccessRule returns the details of a zone's access rule. +// +// API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-list-access-rules +func (api *API) ZoneAccessRule(zoneID string, accessRuleID string) (*AccessRuleResponse, error) { + return api.retrieveAccessRule("/zones/"+zoneID, accessRuleID) +} + +// UpdateZoneAccessRule updates a single access rule for the given zone & +// access rule identifiers. +// +// API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-update-access-rule +func (api *API) UpdateZoneAccessRule(zoneID, accessRuleID string, accessRule AccessRule) (*AccessRuleResponse, error) { + return api.updateAccessRule("/zones/"+zoneID, accessRuleID, accessRule) +} + +// DeleteZoneAccessRule deletes a single access rule for the given zone and +// access rule identifiers. +// +// API reference: https://api.cloudflare.com/#firewall-access-rule-for-a-zone-delete-access-rule +func (api *API) DeleteZoneAccessRule(zoneID, accessRuleID string) (*AccessRuleResponse, error) { + return api.deleteAccessRule("/zones/"+zoneID, accessRuleID) +} + +// ListAccountAccessRules returns a slice of access rules for the given +// account identifier. +// +// This takes an AccessRule to allow filtering of the results returned. +// +// API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-list-access-rules +func (api *API) ListAccountAccessRules(accountID string, accessRule AccessRule, page int) (*AccessRuleListResponse, error) { + return api.listAccessRules("/accounts/"+accountID, accessRule, page) +} + +// CreateAccountAccessRule creates a firewall access rule for the given +// account identifier. +// +// API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-create-access-rule +func (api *API) CreateAccountAccessRule(accountID string, accessRule AccessRule) (*AccessRuleResponse, error) { + return api.createAccessRule("/accounts/"+accountID, accessRule) +} + +// AccountAccessRule returns the details of an account's access rule. +// +// API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-access-rule-details +func (api *API) AccountAccessRule(accountID string, accessRuleID string) (*AccessRuleResponse, error) { + return api.retrieveAccessRule("/accounts/"+accountID, accessRuleID) +} + +// UpdateAccountAccessRule updates a single access rule for the given +// account & access rule identifiers. +// +// API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-update-access-rule +func (api *API) UpdateAccountAccessRule(accountID, accessRuleID string, accessRule AccessRule) (*AccessRuleResponse, error) { + return api.updateAccessRule("/accounts/"+accountID, accessRuleID, accessRule) +} + +// DeleteAccountAccessRule deletes a single access rule for the given +// account and access rule identifiers. +// +// API reference: https://api.cloudflare.com/#account-level-firewall-access-rule-delete-access-rule +func (api *API) DeleteAccountAccessRule(accountID, accessRuleID string) (*AccessRuleResponse, error) { + return api.deleteAccessRule("/accounts/"+accountID, accessRuleID) +} + +func (api *API) listAccessRules(prefix string, accessRule AccessRule, page int) (*AccessRuleListResponse, error) { + // Construct a query string + v := url.Values{} + if page <= 0 { + page = 1 + } + v.Set("page", strconv.Itoa(page)) + // Request as many rules as possible per page - API max is 100 + v.Set("per_page", "100") + if accessRule.Notes != "" { + v.Set("notes", accessRule.Notes) + } + if accessRule.Mode != "" { + v.Set("mode", accessRule.Mode) + } + if accessRule.Scope.Type != "" { + v.Set("scope_type", accessRule.Scope.Type) + } + if accessRule.Configuration.Value != "" { + v.Set("configuration_value", accessRule.Configuration.Value) + } + if accessRule.Configuration.Target != "" { + v.Set("configuration_target", accessRule.Configuration.Target) + } + v.Set("page", strconv.Itoa(page)) + query := "?" + v.Encode() + + uri := prefix + "/firewall/access_rules/rules" + query + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &AccessRuleListResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return response, nil +} + +func (api *API) createAccessRule(prefix string, accessRule AccessRule) (*AccessRuleResponse, error) { + uri := prefix + "/firewall/access_rules/rules" + res, err := api.makeRequest("POST", uri, accessRule) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &AccessRuleResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +func (api *API) retrieveAccessRule(prefix, accessRuleID string) (*AccessRuleResponse, error) { + uri := prefix + "/firewall/access_rules/rules/" + accessRuleID + + res, err := api.makeRequest("GET", uri, nil) + + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &AccessRuleResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +func (api *API) updateAccessRule(prefix, accessRuleID string, accessRule AccessRule) (*AccessRuleResponse, error) { + uri := prefix + "/firewall/access_rules/rules/" + accessRuleID + res, err := api.makeRequest("PATCH", uri, accessRule) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &AccessRuleResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return response, nil +} + +func (api *API) deleteAccessRule(prefix, accessRuleID string) (*AccessRuleResponse, error) { + uri := prefix + "/firewall/access_rules/rules/" + accessRuleID + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &AccessRuleResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/firewall_rules.go b/vendor/github.com/cloudflare/cloudflare-go/firewall_rules.go new file mode 100644 index 000000000..7a6ce5c70 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/firewall_rules.go @@ -0,0 +1,196 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "net/url" + "strconv" + "strings" + "time" + + "github.com/pkg/errors" +) + +// FirewallRule is the struct of the firewall rule. +type FirewallRule struct { + ID string `json:"id,omitempty"` + Paused bool `json:"paused"` + Description string `json:"description"` + Action string `json:"action"` + Priority interface{} `json:"priority"` + Filter Filter `json:"filter"` + CreatedOn time.Time `json:"created_on,omitempty"` + ModifiedOn time.Time `json:"modified_on,omitempty"` +} + +// FirewallRulesDetailResponse is the API response for the firewall +// rules. +type FirewallRulesDetailResponse struct { + Result []FirewallRule `json:"result"` + ResultInfo `json:"result_info"` + Response +} + +// FirewallRuleResponse is the API response that is returned +// for requesting a single firewall rule on a zone. +type FirewallRuleResponse struct { + Result FirewallRule `json:"result"` + ResultInfo `json:"result_info"` + Response +} + +// FirewallRules returns all firewall rules. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/get/#get-all-rules +func (api *API) FirewallRules(zoneID string, pageOpts PaginationOptions) ([]FirewallRule, error) { + uri := fmt.Sprintf("/zones/%s/firewall/rules", zoneID) + v := url.Values{} + + if pageOpts.PerPage > 0 { + v.Set("per_page", strconv.Itoa(pageOpts.PerPage)) + } + + if pageOpts.Page > 0 { + v.Set("page", strconv.Itoa(pageOpts.Page)) + } + + if len(v) > 0 { + uri = uri + "?" + v.Encode() + } + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []FirewallRule{}, errors.Wrap(err, errMakeRequestError) + } + + var firewallDetailResponse FirewallRulesDetailResponse + err = json.Unmarshal(res, &firewallDetailResponse) + if err != nil { + return []FirewallRule{}, errors.Wrap(err, errUnmarshalError) + } + + return firewallDetailResponse.Result, nil +} + +// FirewallRule returns a single firewall rule based on the ID. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/get/#get-by-rule-id +func (api *API) FirewallRule(zoneID, firewallRuleID string) (FirewallRule, error) { + uri := fmt.Sprintf("/zones/%s/firewall/rules/%s", zoneID, firewallRuleID) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return FirewallRule{}, errors.Wrap(err, errMakeRequestError) + } + + var firewallRuleResponse FirewallRuleResponse + err = json.Unmarshal(res, &firewallRuleResponse) + if err != nil { + return FirewallRule{}, errors.Wrap(err, errUnmarshalError) + } + + return firewallRuleResponse.Result, nil +} + +// CreateFirewallRules creates new firewall rules. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/post/ +func (api *API) CreateFirewallRules(zoneID string, firewallRules []FirewallRule) ([]FirewallRule, error) { + uri := fmt.Sprintf("/zones/%s/firewall/rules", zoneID) + + res, err := api.makeRequest("POST", uri, firewallRules) + if err != nil { + return []FirewallRule{}, errors.Wrap(err, errMakeRequestError) + } + + var firewallRulesDetailResponse FirewallRulesDetailResponse + err = json.Unmarshal(res, &firewallRulesDetailResponse) + if err != nil { + return []FirewallRule{}, errors.Wrap(err, errUnmarshalError) + } + + return firewallRulesDetailResponse.Result, nil +} + +// UpdateFirewallRule updates a single firewall rule. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/put/#update-a-single-rule +func (api *API) UpdateFirewallRule(zoneID string, firewallRule FirewallRule) (FirewallRule, error) { + if firewallRule.ID == "" { + return FirewallRule{}, errors.Errorf("firewall rule ID cannot be empty") + } + + uri := fmt.Sprintf("/zones/%s/firewall/rules/%s", zoneID, firewallRule.ID) + + res, err := api.makeRequest("PUT", uri, firewallRule) + if err != nil { + return FirewallRule{}, errors.Wrap(err, errMakeRequestError) + } + + var firewallRuleResponse FirewallRuleResponse + err = json.Unmarshal(res, &firewallRuleResponse) + if err != nil { + return FirewallRule{}, errors.Wrap(err, errUnmarshalError) + } + + return firewallRuleResponse.Result, nil +} + +// UpdateFirewallRules updates a single firewall rule. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/put/#update-multiple-rules +func (api *API) UpdateFirewallRules(zoneID string, firewallRules []FirewallRule) ([]FirewallRule, error) { + for _, firewallRule := range firewallRules { + if firewallRule.ID == "" { + return []FirewallRule{}, errors.Errorf("firewall ID cannot be empty") + } + } + + uri := fmt.Sprintf("/zones/%s/firewall/rules", zoneID) + + res, err := api.makeRequest("PUT", uri, firewallRules) + if err != nil { + return []FirewallRule{}, errors.Wrap(err, errMakeRequestError) + } + + var firewallRulesDetailResponse FirewallRulesDetailResponse + err = json.Unmarshal(res, &firewallRulesDetailResponse) + if err != nil { + return []FirewallRule{}, errors.Wrap(err, errUnmarshalError) + } + + return firewallRulesDetailResponse.Result, nil +} + +// DeleteFirewallRule updates a single firewall rule. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/delete/#delete-a-single-rule +func (api *API) DeleteFirewallRule(zoneID, firewallRuleID string) error { + if firewallRuleID == "" { + return errors.Errorf("firewall rule ID cannot be empty") + } + + uri := fmt.Sprintf("/zones/%s/firewall/rules/%s", zoneID, firewallRuleID) + + _, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} + +// DeleteFirewallRules updates a single firewall rule. +// +// API reference: https://developers.cloudflare.com/firewall/api/cf-firewall-rules/delete/#delete-multiple-rules +func (api *API) DeleteFirewallRules(zoneID string, firewallRuleIDs []string) error { + ids := strings.Join(firewallRuleIDs, ",") + uri := fmt.Sprintf("/zones/%s/firewall/rules?id=%s", zoneID, ids) + + _, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/go.mod b/vendor/github.com/cloudflare/cloudflare-go/go.mod new file mode 100644 index 000000000..e458cc93b --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/go.mod @@ -0,0 +1,13 @@ +module github.com/cloudflare/cloudflare-go + +go 1.11 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/mattn/go-runewidth v0.0.4 // indirect + github.com/olekukonko/tablewriter v0.0.1 + github.com/pkg/errors v0.8.1 + github.com/stretchr/testify v1.3.0 + github.com/urfave/cli v1.21.0 + golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 +) diff --git a/vendor/github.com/cloudflare/cloudflare-go/go.sum b/vendor/github.com/cloudflare/cloudflare-go/go.sum new file mode 100644 index 000000000..0e0bd1238 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/go.sum @@ -0,0 +1,21 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/urfave/cli v1.21.0 h1:wYSSj06510qPIzGSua9ZqsncMmWE3Zr55KBERygyrxE= +github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/cloudflare/cloudflare-go/ips.go b/vendor/github.com/cloudflare/cloudflare-go/ips.go new file mode 100644 index 000000000..72b5fcfbc --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/ips.go @@ -0,0 +1,44 @@ +package cloudflare + +import ( + "encoding/json" + "io/ioutil" + "net/http" + + "github.com/pkg/errors" +) + +// IPRanges contains lists of IPv4 and IPv6 CIDRs. +type IPRanges struct { + IPv4CIDRs []string `json:"ipv4_cidrs"` + IPv6CIDRs []string `json:"ipv6_cidrs"` +} + +// IPsResponse is the API response containing a list of IPs. +type IPsResponse struct { + Response + Result IPRanges `json:"result"` +} + +// IPs gets a list of Cloudflare's IP ranges. +// +// This does not require logging in to the API. +// +// API reference: https://api.cloudflare.com/#cloudflare-ips +func IPs() (IPRanges, error) { + resp, err := http.Get(apiURL + "/ips") + if err != nil { + return IPRanges{}, errors.Wrap(err, "HTTP request failed") + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return IPRanges{}, errors.Wrap(err, "Response body could not be read") + } + var r IPsResponse + err = json.Unmarshal(body, &r) + if err != nil { + return IPRanges{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/keyless.go b/vendor/github.com/cloudflare/cloudflare-go/keyless.go new file mode 100644 index 000000000..c5cc83914 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/keyless.go @@ -0,0 +1,52 @@ +package cloudflare + +import "time" + +// KeylessSSL represents Keyless SSL configuration. +type KeylessSSL struct { + ID string `json:"id"` + Name string `json:"name"` + Host string `json:"host"` + Port int `json:"port"` + Status string `json:"success"` + Enabled bool `json:"enabled"` + Permissions []string `json:"permissions"` + CreatedOn time.Time `json:"created_on"` + ModifiedOn time.Time `json:"modifed_on"` +} + +// KeylessSSLResponse represents the response from the Keyless SSL endpoint. +type KeylessSSLResponse struct { + Response + Result []KeylessSSL `json:"result"` +} + +// CreateKeyless creates a new Keyless SSL configuration for the zone. +// +// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-create-a-keyless-ssl-configuration +func (api *API) CreateKeyless() { +} + +// ListKeyless lists Keyless SSL configurations for a zone. +// +// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-list-keyless-ssls +func (api *API) ListKeyless() { +} + +// Keyless provides the configuration for a given Keyless SSL identifier. +// +// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-keyless-ssl-details +func (api *API) Keyless() { +} + +// UpdateKeyless updates an existing Keyless SSL configuration. +// +// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-update-keyless-configuration +func (api *API) UpdateKeyless() { +} + +// DeleteKeyless deletes an existing Keyless SSL configuration. +// +// API reference: https://api.cloudflare.com/#keyless-ssl-for-a-zone-delete-keyless-configuration +func (api *API) DeleteKeyless() { +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/load_balancing.go b/vendor/github.com/cloudflare/cloudflare-go/load_balancing.go new file mode 100644 index 000000000..8b2f89a65 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/load_balancing.go @@ -0,0 +1,387 @@ +package cloudflare + +import ( + "encoding/json" + "time" + + "github.com/pkg/errors" +) + +// LoadBalancerPool represents a load balancer pool's properties. +type LoadBalancerPool struct { + ID string `json:"id,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + ModifiedOn *time.Time `json:"modified_on,omitempty"` + Description string `json:"description"` + Name string `json:"name"` + Enabled bool `json:"enabled"` + MinimumOrigins int `json:"minimum_origins,omitempty"` + Monitor string `json:"monitor,omitempty"` + Origins []LoadBalancerOrigin `json:"origins"` + NotificationEmail string `json:"notification_email,omitempty"` + + // CheckRegions defines the geographic region(s) from where to run health-checks from - e.g. "WNAM", "WEU", "SAF", "SAM". + // Providing a null/empty value means "all regions", which may not be available to all plan types. + CheckRegions []string `json:"check_regions"` +} + +// LoadBalancerOrigin represents a Load Balancer origin's properties. +type LoadBalancerOrigin struct { + Name string `json:"name"` + Address string `json:"address"` + Enabled bool `json:"enabled"` + Weight float64 `json:"weight"` +} + +// LoadBalancerMonitor represents a load balancer monitor's properties. +type LoadBalancerMonitor struct { + ID string `json:"id,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + ModifiedOn *time.Time `json:"modified_on,omitempty"` + Type string `json:"type"` + Description string `json:"description"` + Method string `json:"method"` + Path string `json:"path"` + Header map[string][]string `json:"header"` + Timeout int `json:"timeout"` + Retries int `json:"retries"` + Interval int `json:"interval"` + Port uint16 `json:"port,omitempty"` + ExpectedBody string `json:"expected_body"` + ExpectedCodes string `json:"expected_codes"` + FollowRedirects bool `json:"follow_redirects"` + AllowInsecure bool `json:"allow_insecure"` + ProbeZone string `json:"probe_zone"` +} + +// LoadBalancer represents a load balancer's properties. +type LoadBalancer struct { + ID string `json:"id,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + ModifiedOn *time.Time `json:"modified_on,omitempty"` + Description string `json:"description"` + Name string `json:"name"` + TTL int `json:"ttl,omitempty"` + FallbackPool string `json:"fallback_pool"` + DefaultPools []string `json:"default_pools"` + RegionPools map[string][]string `json:"region_pools"` + PopPools map[string][]string `json:"pop_pools"` + Proxied bool `json:"proxied"` + Enabled *bool `json:"enabled,omitempty"` + Persistence string `json:"session_affinity,omitempty"` + PersistenceTTL int `json:"session_affinity_ttl,omitempty"` + + // SteeringPolicy controls pool selection logic. + // "off" select pools in DefaultPools order + // "geo" select pools based on RegionPools/PopPools + // "dynamic_latency" select pools based on RTT (requires health checks) + // "random" selects pools in a random order + // "" maps to "geo" if RegionPools or PopPools have entries otherwise "off" + SteeringPolicy string `json:"steering_policy,omitempty"` +} + +// LoadBalancerOriginHealth represents the health of the origin. +type LoadBalancerOriginHealth struct { + Healthy bool `json:"healthy,omitempty"` + RTT Duration `json:"rtt,omitempty"` + FailureReason string `json:"failure_reason,omitempty"` + ResponseCode int `json:"response_code,omitempty"` +} + +// LoadBalancerPoolPopHealth represents the health of the pool for given PoP. +type LoadBalancerPoolPopHealth struct { + Healthy bool `json:"healthy,omitempty"` + Origins []map[string]LoadBalancerOriginHealth `json:"origins,omitempty"` +} + +// LoadBalancerPoolHealth represents the healthchecks from different PoPs for a pool. +type LoadBalancerPoolHealth struct { + ID string `json:"pool_id,omitempty"` + PopHealth map[string]LoadBalancerPoolPopHealth `json:"pop_health,omitempty"` +} + +// loadBalancerPoolResponse represents the response from the load balancer pool endpoints. +type loadBalancerPoolResponse struct { + Response + Result LoadBalancerPool `json:"result"` +} + +// loadBalancerPoolListResponse represents the response from the List Pools endpoint. +type loadBalancerPoolListResponse struct { + Response + Result []LoadBalancerPool `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// loadBalancerMonitorResponse represents the response from the load balancer monitor endpoints. +type loadBalancerMonitorResponse struct { + Response + Result LoadBalancerMonitor `json:"result"` +} + +// loadBalancerMonitorListResponse represents the response from the List Monitors endpoint. +type loadBalancerMonitorListResponse struct { + Response + Result []LoadBalancerMonitor `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// loadBalancerResponse represents the response from the load balancer endpoints. +type loadBalancerResponse struct { + Response + Result LoadBalancer `json:"result"` +} + +// loadBalancerListResponse represents the response from the List Load Balancers endpoint. +type loadBalancerListResponse struct { + Response + Result []LoadBalancer `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// loadBalancerPoolHealthResponse represents the response from the Pool Health Details endpoint. +type loadBalancerPoolHealthResponse struct { + Response + Result LoadBalancerPoolHealth `json:"result"` +} + +// CreateLoadBalancerPool creates a new load balancer pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-create-a-pool +func (api *API) CreateLoadBalancerPool(pool LoadBalancerPool) (LoadBalancerPool, error) { + uri := api.userBaseURL("/user") + "/load_balancers/pools" + res, err := api.makeRequest("POST", uri, pool) + if err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListLoadBalancerPools lists load balancer pools connected to an account. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-list-pools +func (api *API) ListLoadBalancerPools() ([]LoadBalancerPool, error) { + uri := api.userBaseURL("/user") + "/load_balancers/pools" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolListResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// LoadBalancerPoolDetails returns the details for a load balancer pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-pool-details +func (api *API) LoadBalancerPoolDetails(poolID string) (LoadBalancerPool, error) { + uri := api.userBaseURL("/user") + "/load_balancers/pools/" + poolID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// DeleteLoadBalancerPool disables and deletes a load balancer pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-delete-a-pool +func (api *API) DeleteLoadBalancerPool(poolID string) error { + uri := api.userBaseURL("/user") + "/load_balancers/pools/" + poolID + if _, err := api.makeRequest("DELETE", uri, nil); err != nil { + return errors.Wrap(err, errMakeRequestError) + } + return nil +} + +// ModifyLoadBalancerPool modifies a configured load balancer pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-modify-a-pool +func (api *API) ModifyLoadBalancerPool(pool LoadBalancerPool) (LoadBalancerPool, error) { + uri := api.userBaseURL("/user") + "/load_balancers/pools/" + pool.ID + res, err := api.makeRequest("PUT", uri, pool) + if err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerPool{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// CreateLoadBalancerMonitor creates a new load balancer monitor. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-create-a-monitor +func (api *API) CreateLoadBalancerMonitor(monitor LoadBalancerMonitor) (LoadBalancerMonitor, error) { + uri := api.userBaseURL("/user") + "/load_balancers/monitors" + res, err := api.makeRequest("POST", uri, monitor) + if err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerMonitorResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListLoadBalancerMonitors lists load balancer monitors connected to an account. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-list-monitors +func (api *API) ListLoadBalancerMonitors() ([]LoadBalancerMonitor, error) { + uri := api.userBaseURL("/user") + "/load_balancers/monitors" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerMonitorListResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// LoadBalancerMonitorDetails returns the details for a load balancer monitor. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-monitor-details +func (api *API) LoadBalancerMonitorDetails(monitorID string) (LoadBalancerMonitor, error) { + uri := api.userBaseURL("/user") + "/load_balancers/monitors/" + monitorID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerMonitorResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// DeleteLoadBalancerMonitor disables and deletes a load balancer monitor. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-delete-a-monitor +func (api *API) DeleteLoadBalancerMonitor(monitorID string) error { + uri := api.userBaseURL("/user") + "/load_balancers/monitors/" + monitorID + if _, err := api.makeRequest("DELETE", uri, nil); err != nil { + return errors.Wrap(err, errMakeRequestError) + } + return nil +} + +// ModifyLoadBalancerMonitor modifies a configured load balancer monitor. +// +// API reference: https://api.cloudflare.com/#load-balancer-monitors-modify-a-monitor +func (api *API) ModifyLoadBalancerMonitor(monitor LoadBalancerMonitor) (LoadBalancerMonitor, error) { + uri := api.userBaseURL("/user") + "/load_balancers/monitors/" + monitor.ID + res, err := api.makeRequest("PUT", uri, monitor) + if err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerMonitorResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerMonitor{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// CreateLoadBalancer creates a new load balancer. +// +// API reference: https://api.cloudflare.com/#load-balancers-create-a-load-balancer +func (api *API) CreateLoadBalancer(zoneID string, lb LoadBalancer) (LoadBalancer, error) { + uri := "/zones/" + zoneID + "/load_balancers" + res, err := api.makeRequest("POST", uri, lb) + if err != nil { + return LoadBalancer{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancer{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListLoadBalancers lists load balancers configured on a zone. +// +// API reference: https://api.cloudflare.com/#load-balancers-list-load-balancers +func (api *API) ListLoadBalancers(zoneID string) ([]LoadBalancer, error) { + uri := "/zones/" + zoneID + "/load_balancers" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerListResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// LoadBalancerDetails returns the details for a load balancer. +// +// API reference: https://api.cloudflare.com/#load-balancers-load-balancer-details +func (api *API) LoadBalancerDetails(zoneID, lbID string) (LoadBalancer, error) { + uri := "/zones/" + zoneID + "/load_balancers/" + lbID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return LoadBalancer{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancer{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// DeleteLoadBalancer disables and deletes a load balancer. +// +// API reference: https://api.cloudflare.com/#load-balancers-delete-a-load-balancer +func (api *API) DeleteLoadBalancer(zoneID, lbID string) error { + uri := "/zones/" + zoneID + "/load_balancers/" + lbID + if _, err := api.makeRequest("DELETE", uri, nil); err != nil { + return errors.Wrap(err, errMakeRequestError) + } + return nil +} + +// ModifyLoadBalancer modifies a configured load balancer. +// +// API reference: https://api.cloudflare.com/#load-balancers-modify-a-load-balancer +func (api *API) ModifyLoadBalancer(zoneID string, lb LoadBalancer) (LoadBalancer, error) { + uri := "/zones/" + zoneID + "/load_balancers/" + lb.ID + res, err := api.makeRequest("PUT", uri, lb) + if err != nil { + return LoadBalancer{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancer{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// PoolHealthDetails fetches the latest healtcheck details for a single pool. +// +// API reference: https://api.cloudflare.com/#load-balancer-pools-pool-health-details +func (api *API) PoolHealthDetails(poolID string) (LoadBalancerPoolHealth, error) { + uri := api.userBaseURL("/user") + "/load_balancers/pools/" + poolID + "/health" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return LoadBalancerPoolHealth{}, errors.Wrap(err, errMakeRequestError) + } + var r loadBalancerPoolHealthResponse + if err := json.Unmarshal(res, &r); err != nil { + return LoadBalancerPoolHealth{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/lockdown.go b/vendor/github.com/cloudflare/cloudflare-go/lockdown.go new file mode 100644 index 000000000..164129bc5 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/lockdown.go @@ -0,0 +1,151 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "strconv" + + "github.com/pkg/errors" +) + +// ZoneLockdown represents a Zone Lockdown rule. A rule only permits access to +// the provided URL pattern(s) from the given IP address(es) or subnet(s). +type ZoneLockdown struct { + ID string `json:"id"` + Description string `json:"description"` + URLs []string `json:"urls"` + Configurations []ZoneLockdownConfig `json:"configurations"` + Paused bool `json:"paused"` + Priority int `json:"priority,omitempty"` +} + +// ZoneLockdownConfig represents a Zone Lockdown config, which comprises +// a Target ("ip" or "ip_range") and a Value (an IP address or IP+mask, +// respectively.) +type ZoneLockdownConfig struct { + Target string `json:"target"` + Value string `json:"value"` +} + +// ZoneLockdownResponse represents a response from the Zone Lockdown endpoint. +type ZoneLockdownResponse struct { + Result ZoneLockdown `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// ZoneLockdownListResponse represents a response from the List Zone Lockdown +// endpoint. +type ZoneLockdownListResponse struct { + Result []ZoneLockdown `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// CreateZoneLockdown creates a Zone ZoneLockdown rule for the given zone ID. +// +// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-create-a-ZoneLockdown-rule +func (api *API) CreateZoneLockdown(zoneID string, ld ZoneLockdown) (*ZoneLockdownResponse, error) { + uri := "/zones/" + zoneID + "/firewall/lockdowns" + res, err := api.makeRequest("POST", uri, ld) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &ZoneLockdownResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// UpdateZoneLockdown updates a Zone ZoneLockdown rule (based on the ID) for the +// given zone ID. +// +// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-update-ZoneLockdown-rule +func (api *API) UpdateZoneLockdown(zoneID string, id string, ld ZoneLockdown) (*ZoneLockdownResponse, error) { + uri := "/zones/" + zoneID + "/firewall/lockdowns/" + id + res, err := api.makeRequest("PUT", uri, ld) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &ZoneLockdownResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// DeleteZoneLockdown deletes a Zone ZoneLockdown rule (based on the ID) for the +// given zone ID. +// +// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-delete-ZoneLockdown-rule +func (api *API) DeleteZoneLockdown(zoneID string, id string) (*ZoneLockdownResponse, error) { + uri := "/zones/" + zoneID + "/firewall/lockdowns/" + id + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &ZoneLockdownResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// ZoneLockdown retrieves a Zone ZoneLockdown rule (based on the ID) for the +// given zone ID. +// +// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-ZoneLockdown-rule-details +func (api *API) ZoneLockdown(zoneID string, id string) (*ZoneLockdownResponse, error) { + uri := "/zones/" + zoneID + "/firewall/lockdowns/" + id + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &ZoneLockdownResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// ListZoneLockdowns retrieves a list of Zone ZoneLockdown rules for a given +// zone ID by page number. +// +// API reference: https://api.cloudflare.com/#zone-ZoneLockdown-list-ZoneLockdown-rules +func (api *API) ListZoneLockdowns(zoneID string, page int) (*ZoneLockdownListResponse, error) { + v := url.Values{} + if page <= 0 { + page = 1 + } + + v.Set("page", strconv.Itoa(page)) + v.Set("per_page", strconv.Itoa(100)) + query := "?" + v.Encode() + + uri := "/zones/" + zoneID + "/firewall/lockdowns" + query + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &ZoneLockdownListResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/logpush.go b/vendor/github.com/cloudflare/cloudflare-go/logpush.go new file mode 100644 index 000000000..a0134aded --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/logpush.go @@ -0,0 +1,224 @@ +package cloudflare + +import ( + "encoding/json" + "strconv" + "time" + + "github.com/pkg/errors" +) + +// LogpushJob describes a Logpush job. +type LogpushJob struct { + ID int `json:"id,omitempty"` + Enabled bool `json:"enabled"` + Name string `json:"name"` + LogpullOptions string `json:"logpull_options"` + DestinationConf string `json:"destination_conf"` + OwnershipChallenge string `json:"ownership_challenge,omitempty"` + LastComplete *time.Time `json:"last_complete,omitempty"` + LastError *time.Time `json:"last_error,omitempty"` + ErrorMessage string `json:"error_message,omitempty"` +} + +// LogpushJobsResponse is the API response, containing an array of Logpush Jobs. +type LogpushJobsResponse struct { + Response + Result []LogpushJob `json:"result"` +} + +// LogpushJobDetailsResponse is the API response, containing a single Logpush Job. +type LogpushJobDetailsResponse struct { + Response + Result LogpushJob `json:"result"` +} + +// LogpushGetOwnershipChallenge describes a ownership validation. +type LogpushGetOwnershipChallenge struct { + Filename string `json:"filename"` + Valid bool `json:"valid"` + Message string `json:"message"` +} + +// LogpushGetOwnershipChallengeResponse is the API response, containing a ownership challenge. +type LogpushGetOwnershipChallengeResponse struct { + Response + Result LogpushGetOwnershipChallenge `json:"result"` +} + +// LogpushGetOwnershipChallengeRequest is the API request for get ownership challenge. +type LogpushGetOwnershipChallengeRequest struct { + DestinationConf string `json:"destination_conf"` +} + +// LogpushOwnershipChallangeValidationResponse is the API response, +// containing a ownership challenge validation result. +type LogpushOwnershipChallangeValidationResponse struct { + Response + Result struct { + Valid bool `json:"valid"` + } +} + +// LogpushValidateOwnershipChallengeRequest is the API request for validate ownership challenge. +type LogpushValidateOwnershipChallengeRequest struct { + DestinationConf string `json:"destination_conf"` + OwnershipChallenge string `json:"ownership_challenge"` +} + +// LogpushDestinationExistsResponse is the API response, +// containing a destination exists check result. +type LogpushDestinationExistsResponse struct { + Response + Result struct { + Exists bool `json:"exists"` + } +} + +// LogpushDestinationExistsRequest is the API request for check destination exists. +type LogpushDestinationExistsRequest struct { + DestinationConf string `json:"destination_conf"` +} + +// CreateLogpushJob creates a new LogpushJob for a zone. +// +// API reference: https://api.cloudflare.com/#logpush-jobs-create-logpush-job +func (api *API) CreateLogpushJob(zoneID string, job LogpushJob) (*LogpushJob, error) { + uri := "/zones/" + zoneID + "/logpush/jobs" + res, err := api.makeRequest("POST", uri, job) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r LogpushJobDetailsResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return &r.Result, nil +} + +// LogpushJobs returns all Logpush Jobs for a zone. +// +// API reference: https://api.cloudflare.com/#logpush-jobs-list-logpush-jobs +func (api *API) LogpushJobs(zoneID string) ([]LogpushJob, error) { + uri := "/zones/" + zoneID + "/logpush/jobs" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []LogpushJob{}, errors.Wrap(err, errMakeRequestError) + } + var r LogpushJobsResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []LogpushJob{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// LogpushJob fetches detail about one Logpush Job for a zone. +// +// API reference: https://api.cloudflare.com/#logpush-jobs-logpush-job-details +func (api *API) LogpushJob(zoneID string, jobID int) (LogpushJob, error) { + uri := "/zones/" + zoneID + "/logpush/jobs/" + strconv.Itoa(jobID) + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return LogpushJob{}, errors.Wrap(err, errMakeRequestError) + } + var r LogpushJobDetailsResponse + err = json.Unmarshal(res, &r) + if err != nil { + return LogpushJob{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// UpdateLogpushJob lets you update a Logpush Job. +// +// API reference: https://api.cloudflare.com/#logpush-jobs-update-logpush-job +func (api *API) UpdateLogpushJob(zoneID string, jobID int, job LogpushJob) error { + uri := "/zones/" + zoneID + "/logpush/jobs/" + strconv.Itoa(jobID) + res, err := api.makeRequest("PUT", uri, job) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + var r LogpushJobDetailsResponse + err = json.Unmarshal(res, &r) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + return nil +} + +// DeleteLogpushJob deletes a Logpush Job for a zone. +// +// API reference: https://api.cloudflare.com/#logpush-jobs-delete-logpush-job +func (api *API) DeleteLogpushJob(zoneID string, jobID int) error { + uri := "/zones/" + zoneID + "/logpush/jobs/" + strconv.Itoa(jobID) + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + var r LogpushJobDetailsResponse + err = json.Unmarshal(res, &r) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + return nil +} + +// GetLogpushOwnershipChallenge returns ownership challenge. +// +// API reference: https://api.cloudflare.com/#logpush-jobs-get-ownership-challenge +func (api *API) GetLogpushOwnershipChallenge(zoneID, destinationConf string) (*LogpushGetOwnershipChallenge, error) { + uri := "/zones/" + zoneID + "/logpush/ownership" + res, err := api.makeRequest("POST", uri, LogpushGetOwnershipChallengeRequest{ + DestinationConf: destinationConf, + }) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r LogpushGetOwnershipChallengeResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return &r.Result, nil +} + +// ValidateLogpushOwnershipChallenge returns ownership challenge validation result. +// +// API reference: https://api.cloudflare.com/#logpush-jobs-validate-ownership-challenge +func (api *API) ValidateLogpushOwnershipChallenge(zoneID, destinationConf, ownershipChallenge string) (bool, error) { + uri := "/zones/" + zoneID + "/logpush/ownership/validate" + res, err := api.makeRequest("POST", uri, LogpushValidateOwnershipChallengeRequest{ + DestinationConf: destinationConf, + OwnershipChallenge: ownershipChallenge, + }) + if err != nil { + return false, errors.Wrap(err, errMakeRequestError) + } + var r LogpushGetOwnershipChallengeResponse + err = json.Unmarshal(res, &r) + if err != nil { + return false, errors.Wrap(err, errUnmarshalError) + } + return r.Result.Valid, nil +} + +// CheckLogpushDestinationExists returns destination exists check result. +// +// API reference: https://api.cloudflare.com/#logpush-jobs-check-destination-exists +func (api *API) CheckLogpushDestinationExists(zoneID, destinationConf string) (bool, error) { + uri := "/zones/" + zoneID + "/logpush/validate/destination/exists" + res, err := api.makeRequest("POST", uri, LogpushDestinationExistsRequest{ + DestinationConf: destinationConf, + }) + if err != nil { + return false, errors.Wrap(err, errMakeRequestError) + } + var r LogpushDestinationExistsResponse + err = json.Unmarshal(res, &r) + if err != nil { + return false, errors.Wrap(err, errUnmarshalError) + } + return r.Result.Exists, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/options.go b/vendor/github.com/cloudflare/cloudflare-go/options.go new file mode 100644 index 000000000..1bf4f60bd --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/options.go @@ -0,0 +1,101 @@ +package cloudflare + +import ( + "net/http" + + "time" + + "golang.org/x/time/rate" +) + +// Option is a functional option for configuring the API client. +type Option func(*API) error + +// HTTPClient accepts a custom *http.Client for making API calls. +func HTTPClient(client *http.Client) Option { + return func(api *API) error { + api.httpClient = client + return nil + } +} + +// Headers allows you to set custom HTTP headers when making API calls (e.g. for +// satisfying HTTP proxies, or for debugging). +func Headers(headers http.Header) Option { + return func(api *API) error { + api.headers = headers + return nil + } +} + +// UsingAccount allows you to apply account-level changes (Load Balancing, +// Railguns) to an account instead. +func UsingAccount(accountID string) Option { + return func(api *API) error { + api.AccountID = accountID + return nil + } +} + +// UsingRateLimit applies a non-default rate limit to client API requests +// If not specified the default of 4rps will be applied +func UsingRateLimit(rps float64) Option { + return func(api *API) error { + // because ratelimiter doesnt do any windowing + // setting burst makes it difficult to enforce a fixed rate + // so setting it equal to 1 this effectively disables bursting + // this doesn't check for sensible values, ultimately the api will enforce that the value is ok + api.rateLimiter = rate.NewLimiter(rate.Limit(rps), 1) + return nil + } +} + +// UsingRetryPolicy applies a non-default number of retries and min/max retry delays +// This will be used when the client exponentially backs off after errored requests +func UsingRetryPolicy(maxRetries int, minRetryDelaySecs int, maxRetryDelaySecs int) Option { + // seconds is very granular for a minimum delay - but this is only in case of failure + return func(api *API) error { + api.retryPolicy = RetryPolicy{ + MaxRetries: maxRetries, + MinRetryDelay: time.Duration(minRetryDelaySecs) * time.Second, + MaxRetryDelay: time.Duration(maxRetryDelaySecs) * time.Second, + } + return nil + } +} + +// UsingLogger can be set if you want to get log output from this API instance +// By default no log output is emitted +func UsingLogger(logger Logger) Option { + return func(api *API) error { + api.logger = logger + return nil + } +} + +// UserAgent can be set if you want to send a software name and version for HTTP access logs. +// It is recommended to set it in order to help future Customer Support diagnostics +// and prevent collateral damage by sharing generic User-Agent string with abusive users. +// E.g. "my-software/1.2.3". By default generic Go User-Agent is used. +func UserAgent(userAgent string) Option { + return func(api *API) error { + api.UserAgent = userAgent + return nil + } +} + +// parseOptions parses the supplied options functions and returns a configured +// *API instance. +func (api *API) parseOptions(opts ...Option) error { + // Range over each options function and apply it to our API type to + // configure it. Options functions are applied in order, with any + // conflicting options overriding earlier calls. + for _, option := range opts { + err := option(api) + if err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/origin_ca.go b/vendor/github.com/cloudflare/cloudflare-go/origin_ca.go new file mode 100644 index 000000000..fdd8c4273 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/origin_ca.go @@ -0,0 +1,169 @@ +package cloudflare + +import ( + "context" + "encoding/json" + "net/url" + "time" + + "github.com/pkg/errors" +) + +// OriginCACertificate represents a Cloudflare-issued certificate. +// +// API reference: https://api.cloudflare.com/#cloudflare-ca +type OriginCACertificate struct { + ID string `json:"id"` + Certificate string `json:"certificate"` + Hostnames []string `json:"hostnames"` + ExpiresOn time.Time `json:"expires_on"` + RequestType string `json:"request_type"` + RequestValidity int `json:"requested_validity"` + CSR string `json:"csr"` +} + +// OriginCACertificateListOptions represents the parameters used to list Cloudflare-issued certificates. +type OriginCACertificateListOptions struct { + ZoneID string +} + +// OriginCACertificateID represents the ID of the revoked certificate from the Revoke Certificate endpoint. +type OriginCACertificateID struct { + ID string `json:"id"` +} + +// originCACertificateResponse represents the response from the Create Certificate and the Certificate Details endpoints. +type originCACertificateResponse struct { + Response + Result OriginCACertificate `json:"result"` +} + +// originCACertificateResponseList represents the response from the List Certificates endpoint. +type originCACertificateResponseList struct { + Response + Result []OriginCACertificate `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// originCACertificateResponseRevoke represents the response from the Revoke Certificate endpoint. +type originCACertificateResponseRevoke struct { + Response + Result OriginCACertificateID `json:"result"` +} + +// CreateOriginCertificate creates a Cloudflare-signed certificate. +// +// This function requires api.APIUserServiceKey be set to your Certificates API key. +// +// API reference: https://api.cloudflare.com/#cloudflare-ca-create-certificate +func (api *API) CreateOriginCertificate(certificate OriginCACertificate) (*OriginCACertificate, error) { + uri := "/certificates" + res, err := api.makeRequestWithAuthType(context.TODO(), "POST", uri, certificate, AuthUserService) + + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + var originResponse *originCACertificateResponse + + err = json.Unmarshal(res, &originResponse) + + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + if !originResponse.Success { + return nil, errors.New(errRequestNotSuccessful) + } + + return &originResponse.Result, nil +} + +// OriginCertificates lists all Cloudflare-issued certificates. +// +// This function requires api.APIUserServiceKey be set to your Certificates API key. +// +// API reference: https://api.cloudflare.com/#cloudflare-ca-list-certificates +func (api *API) OriginCertificates(options OriginCACertificateListOptions) ([]OriginCACertificate, error) { + v := url.Values{} + if options.ZoneID != "" { + v.Set("zone_id", options.ZoneID) + } + uri := "/certificates" + "?" + v.Encode() + res, err := api.makeRequestWithAuthType(context.TODO(), "GET", uri, nil, AuthUserService) + + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + var originResponse *originCACertificateResponseList + + err = json.Unmarshal(res, &originResponse) + + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + if !originResponse.Success { + return nil, errors.New(errRequestNotSuccessful) + } + + return originResponse.Result, nil +} + +// OriginCertificate returns the details for a Cloudflare-issued certificate. +// +// This function requires api.APIUserServiceKey be set to your Certificates API key. +// +// API reference: https://api.cloudflare.com/#cloudflare-ca-certificate-details +func (api *API) OriginCertificate(certificateID string) (*OriginCACertificate, error) { + uri := "/certificates/" + certificateID + res, err := api.makeRequestWithAuthType(context.TODO(), "GET", uri, nil, AuthUserService) + + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + var originResponse *originCACertificateResponse + + err = json.Unmarshal(res, &originResponse) + + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + if !originResponse.Success { + return nil, errors.New(errRequestNotSuccessful) + } + + return &originResponse.Result, nil +} + +// RevokeOriginCertificate revokes a created certificate for a zone. +// +// This function requires api.APIUserServiceKey be set to your Certificates API key. +// +// API reference: https://api.cloudflare.com/#cloudflare-ca-revoke-certificate +func (api *API) RevokeOriginCertificate(certificateID string) (*OriginCACertificateID, error) { + uri := "/certificates/" + certificateID + res, err := api.makeRequestWithAuthType(context.TODO(), "DELETE", uri, nil, AuthUserService) + + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + var originResponse *originCACertificateResponseRevoke + + err = json.Unmarshal(res, &originResponse) + + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + if !originResponse.Success { + return nil, errors.New(errRequestNotSuccessful) + } + + return &originResponse.Result, nil + +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/page_rules.go b/vendor/github.com/cloudflare/cloudflare-go/page_rules.go new file mode 100644 index 000000000..36f62e62f --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/page_rules.go @@ -0,0 +1,235 @@ +package cloudflare + +import ( + "encoding/json" + "time" + + "github.com/pkg/errors" +) + +// PageRuleTarget is the target to evaluate on a request. +// +// Currently Target must always be "url" and Operator must be "matches". Value +// is the URL pattern to match against. +type PageRuleTarget struct { + Target string `json:"target"` + Constraint struct { + Operator string `json:"operator"` + Value string `json:"value"` + } `json:"constraint"` +} + +/* +PageRuleAction is the action to take when the target is matched. + +Valid IDs are: + always_online + always_use_https + automatic_https_rewrites + browser_cache_ttl + browser_check + bypass_cache_on_cookie + cache_by_device_type + cache_deception_armor + cache_level + cache_on_cookie + disable_apps + disable_performance + disable_railgun + disable_security + edge_cache_ttl + email_obfuscation + explicit_cache_control + forwarding_url + host_header_override + ip_geolocation + minify + mirage + opportunistic_encryption + origin_error_page_pass_thru + polish + resolve_override + respect_strong_etag + response_buffering + rocket_loader + security_level + server_side_exclude + sort_query_string_for_cache + ssl + true_client_ip_header + waf +*/ +type PageRuleAction struct { + ID string `json:"id"` + Value interface{} `json:"value"` +} + +// PageRuleActions maps API action IDs to human-readable strings. +var PageRuleActions = map[string]string{ + "always_online": "Always Online", // Value of type string + "always_use_https": "Always Use HTTPS", // Value of type interface{} + "automatic_https_rewrites": "Automatic HTTPS Rewrites", // Value of type string + "browser_cache_ttl": "Browser Cache TTL", // Value of type int + "browser_check": "Browser Integrity Check", // Value of type string + "bypass_cache_on_cookie": "Bypass Cache on Cookie", // Value of type string + "cache_by_device_type": "Cache By Device Type", // Value of type string + "cache_deception_armor": "Cache Deception Armor", // Value of type string + "cache_level": "Cache Level", // Value of type string + "cache_on_cookie": "Cache On Cookie", // Value of type string + "disable_apps": "Disable Apps", // Value of type interface{} + "disable_performance": "Disable Performance", // Value of type interface{} + "disable_railgun": "Disable Railgun", // Value of type string + "disable_security": "Disable Security", // Value of type interface{} + "edge_cache_ttl": "Edge Cache TTL", // Value of type int + "email_obfuscation": "Email Obfuscation", // Value of type string + "explicit_cache_control": "Origin Cache Control", // Value of type string + "forwarding_url": "Forwarding URL", // Value of type map[string]interface + "host_header_override": "Host Header Override", // Value of type string + "ip_geolocation": "IP Geolocation Header", // Value of type string + "minify": "Minify", // Value of type map[string]interface + "mirage": "Mirage", // Value of type string + "opportunistic_encryption": "Opportunistic Encryption", // Value of type string + "origin_error_page_pass_thru": "Origin Error Page Pass-thru", // Value of type string + "polish": "Polish", // Value of type string + "resolve_override": "Resolve Override", // Value of type string + "respect_strong_etag": "Respect Strong ETags", // Value of type string + "response_buffering": "Response Buffering", // Value of type string + "rocket_loader": "Rocker Loader", // Value of type string + "security_level": "Security Level", // Value of type string + "server_side_exclude": "Server Side Excludes", // Value of type string + "sort_query_string_for_cache": "Query String Sort", // Value of type string + "ssl": "SSL", // Value of type string + "true_client_ip_header": "True Client IP Header", // Value of type string + "waf": "Web Application Firewall", // Value of type string +} + +// PageRule describes a Page Rule. +type PageRule struct { + ID string `json:"id,omitempty"` + Targets []PageRuleTarget `json:"targets"` + Actions []PageRuleAction `json:"actions"` + Priority int `json:"priority"` + Status string `json:"status"` // can be: active, paused + ModifiedOn time.Time `json:"modified_on,omitempty"` + CreatedOn time.Time `json:"created_on,omitempty"` +} + +// PageRuleDetailResponse is the API response, containing a single PageRule. +type PageRuleDetailResponse struct { + Success bool `json:"success"` + Errors []string `json:"errors"` + Messages []string `json:"messages"` + Result PageRule `json:"result"` +} + +// PageRulesResponse is the API response, containing an array of PageRules. +type PageRulesResponse struct { + Success bool `json:"success"` + Errors []string `json:"errors"` + Messages []string `json:"messages"` + Result []PageRule `json:"result"` +} + +// CreatePageRule creates a new Page Rule for a zone. +// +// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-create-a-page-rule +func (api *API) CreatePageRule(zoneID string, rule PageRule) (*PageRule, error) { + uri := "/zones/" + zoneID + "/pagerules" + res, err := api.makeRequest("POST", uri, rule) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r PageRuleDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return &r.Result, nil +} + +// ListPageRules returns all Page Rules for a zone. +// +// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-list-page-rules +func (api *API) ListPageRules(zoneID string) ([]PageRule, error) { + uri := "/zones/" + zoneID + "/pagerules" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []PageRule{}, errors.Wrap(err, errMakeRequestError) + } + var r PageRulesResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []PageRule{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// PageRule fetches detail about one Page Rule for a zone. +// +// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-page-rule-details +func (api *API) PageRule(zoneID, ruleID string) (PageRule, error) { + uri := "/zones/" + zoneID + "/pagerules/" + ruleID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return PageRule{}, errors.Wrap(err, errMakeRequestError) + } + var r PageRuleDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return PageRule{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ChangePageRule lets you change individual settings for a Page Rule. This is +// in contrast to UpdatePageRule which replaces the entire Page Rule. +// +// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-change-a-page-rule +func (api *API) ChangePageRule(zoneID, ruleID string, rule PageRule) error { + uri := "/zones/" + zoneID + "/pagerules/" + ruleID + res, err := api.makeRequest("PATCH", uri, rule) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + var r PageRuleDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + return nil +} + +// UpdatePageRule lets you replace a Page Rule. This is in contrast to +// ChangePageRule which lets you change individual settings. +// +// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-update-a-page-rule +func (api *API) UpdatePageRule(zoneID, ruleID string, rule PageRule) error { + uri := "/zones/" + zoneID + "/pagerules/" + ruleID + res, err := api.makeRequest("PUT", uri, rule) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + var r PageRuleDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + return nil +} + +// DeletePageRule deletes a Page Rule for a zone. +// +// API reference: https://api.cloudflare.com/#page-rules-for-a-zone-delete-a-page-rule +func (api *API) DeletePageRule(zoneID, ruleID string) error { + uri := "/zones/" + zoneID + "/pagerules/" + ruleID + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + var r PageRuleDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/railgun.go b/vendor/github.com/cloudflare/cloudflare-go/railgun.go new file mode 100644 index 000000000..72d228691 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/railgun.go @@ -0,0 +1,297 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "time" + + "github.com/pkg/errors" +) + +// Railgun represents a Railgun's properties. +type Railgun struct { + ID string `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + Enabled bool `json:"enabled"` + ZonesConnected int `json:"zones_connected"` + Build string `json:"build"` + Version string `json:"version"` + Revision string `json:"revision"` + ActivationKey string `json:"activation_key"` + ActivatedOn time.Time `json:"activated_on"` + CreatedOn time.Time `json:"created_on"` + ModifiedOn time.Time `json:"modified_on"` + UpgradeInfo struct { + LatestVersion string `json:"latest_version"` + DownloadLink string `json:"download_link"` + } `json:"upgrade_info"` +} + +// RailgunListOptions represents the parameters used to list railguns. +type RailgunListOptions struct { + Direction string +} + +// railgunResponse represents the response from the Create Railgun and the Railgun Details endpoints. +type railgunResponse struct { + Response + Result Railgun `json:"result"` +} + +// railgunsResponse represents the response from the List Railguns endpoint. +type railgunsResponse struct { + Response + Result []Railgun `json:"result"` +} + +// CreateRailgun creates a new Railgun. +// +// API reference: https://api.cloudflare.com/#railgun-create-railgun +func (api *API) CreateRailgun(name string) (Railgun, error) { + uri := api.userBaseURL("") + "/railguns" + params := struct { + Name string `json:"name"` + }{ + Name: name, + } + res, err := api.makeRequest("POST", uri, params) + if err != nil { + return Railgun{}, errors.Wrap(err, errMakeRequestError) + } + var r railgunResponse + if err := json.Unmarshal(res, &r); err != nil { + return Railgun{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListRailguns lists Railguns connected to an account. +// +// API reference: https://api.cloudflare.com/#railgun-list-railguns +func (api *API) ListRailguns(options RailgunListOptions) ([]Railgun, error) { + v := url.Values{} + if options.Direction != "" { + v.Set("direction", options.Direction) + } + uri := api.userBaseURL("") + "/railguns" + "?" + v.Encode() + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r railgunsResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// RailgunDetails returns the details for a Railgun. +// +// API reference: https://api.cloudflare.com/#railgun-railgun-details +func (api *API) RailgunDetails(railgunID string) (Railgun, error) { + uri := api.userBaseURL("") + "/railguns/" + railgunID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return Railgun{}, errors.Wrap(err, errMakeRequestError) + } + var r railgunResponse + if err := json.Unmarshal(res, &r); err != nil { + return Railgun{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// RailgunZones returns the zones that are currently using a Railgun. +// +// API reference: https://api.cloudflare.com/#railgun-get-zones-connected-to-a-railgun +func (api *API) RailgunZones(railgunID string) ([]Zone, error) { + uri := api.userBaseURL("") + "/railguns/" + railgunID + "/zones" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r ZonesResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// enableRailgun enables (true) or disables (false) a Railgun for all zones connected to it. +// +// API reference: https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun +func (api *API) enableRailgun(railgunID string, enable bool) (Railgun, error) { + uri := api.userBaseURL("") + "/railguns/" + railgunID + params := struct { + Enabled bool `json:"enabled"` + }{ + Enabled: enable, + } + res, err := api.makeRequest("PATCH", uri, params) + if err != nil { + return Railgun{}, errors.Wrap(err, errMakeRequestError) + } + var r railgunResponse + if err := json.Unmarshal(res, &r); err != nil { + return Railgun{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// EnableRailgun enables a Railgun for all zones connected to it. +// +// API reference: https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun +func (api *API) EnableRailgun(railgunID string) (Railgun, error) { + return api.enableRailgun(railgunID, true) +} + +// DisableRailgun enables a Railgun for all zones connected to it. +// +// API reference: https://api.cloudflare.com/#railgun-enable-or-disable-a-railgun +func (api *API) DisableRailgun(railgunID string) (Railgun, error) { + return api.enableRailgun(railgunID, false) +} + +// DeleteRailgun disables and deletes a Railgun. +// +// API reference: https://api.cloudflare.com/#railgun-delete-railgun +func (api *API) DeleteRailgun(railgunID string) error { + uri := api.userBaseURL("") + "/railguns/" + railgunID + if _, err := api.makeRequest("DELETE", uri, nil); err != nil { + return errors.Wrap(err, errMakeRequestError) + } + return nil +} + +// ZoneRailgun represents the status of a Railgun on a zone. +type ZoneRailgun struct { + ID string `json:"id"` + Name string `json:"name"` + Enabled bool `json:"enabled"` + Connected bool `json:"connected"` +} + +// zoneRailgunResponse represents the response from the Zone Railgun Details endpoint. +type zoneRailgunResponse struct { + Response + Result ZoneRailgun `json:"result"` +} + +// zoneRailgunsResponse represents the response from the Zone Railgun endpoint. +type zoneRailgunsResponse struct { + Response + Result []ZoneRailgun `json:"result"` +} + +// RailgunDiagnosis represents the test results from testing railgun connections +// to a zone. +type RailgunDiagnosis struct { + Method string `json:"method"` + HostName string `json:"host_name"` + HTTPStatus int `json:"http_status"` + Railgun string `json:"railgun"` + URL string `json:"url"` + ResponseStatus string `json:"response_status"` + Protocol string `json:"protocol"` + ElapsedTime string `json:"elapsed_time"` + BodySize string `json:"body_size"` + BodyHash string `json:"body_hash"` + MissingHeaders string `json:"missing_headers"` + ConnectionClose bool `json:"connection_close"` + Cloudflare string `json:"cloudflare"` + CFRay string `json:"cf-ray"` + // NOTE: Cloudflare's online API documentation does not yet have definitions + // for the following fields. See: https://api.cloudflare.com/#railgun-connections-for-a-zone-test-railgun-connection/ + CFWANError string `json:"cf-wan-error"` + CFCacheStatus string `json:"cf-cache-status"` +} + +// railgunDiagnosisResponse represents the response from the Test Railgun Connection enpoint. +type railgunDiagnosisResponse struct { + Response + Result RailgunDiagnosis `json:"result"` +} + +// ZoneRailguns returns the available Railguns for a zone. +// +// API reference: https://api.cloudflare.com/#railguns-for-a-zone-get-available-railguns +func (api *API) ZoneRailguns(zoneID string) ([]ZoneRailgun, error) { + uri := "/zones/" + zoneID + "/railguns" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r zoneRailgunsResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ZoneRailgunDetails returns the configuration for a given Railgun. +// +// API reference: https://api.cloudflare.com/#railguns-for-a-zone-get-railgun-details +func (api *API) ZoneRailgunDetails(zoneID, railgunID string) (ZoneRailgun, error) { + uri := "/zones/" + zoneID + "/railguns/" + railgunID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return ZoneRailgun{}, errors.Wrap(err, errMakeRequestError) + } + var r zoneRailgunResponse + if err := json.Unmarshal(res, &r); err != nil { + return ZoneRailgun{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// TestRailgunConnection tests a Railgun connection for a given zone. +// +// API reference: https://api.cloudflare.com/#railgun-connections-for-a-zone-test-railgun-connection +func (api *API) TestRailgunConnection(zoneID, railgunID string) (RailgunDiagnosis, error) { + uri := "/zones/" + zoneID + "/railguns/" + railgunID + "/diagnose" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return RailgunDiagnosis{}, errors.Wrap(err, errMakeRequestError) + } + var r railgunDiagnosisResponse + if err := json.Unmarshal(res, &r); err != nil { + return RailgunDiagnosis{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// connectZoneRailgun connects (true) or disconnects (false) a Railgun for a given zone. +// +// API reference: https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun +func (api *API) connectZoneRailgun(zoneID, railgunID string, connect bool) (ZoneRailgun, error) { + uri := "/zones/" + zoneID + "/railguns/" + railgunID + params := struct { + Connected bool `json:"connected"` + }{ + Connected: connect, + } + res, err := api.makeRequest("PATCH", uri, params) + if err != nil { + return ZoneRailgun{}, errors.Wrap(err, errMakeRequestError) + } + var r zoneRailgunResponse + if err := json.Unmarshal(res, &r); err != nil { + return ZoneRailgun{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ConnectZoneRailgun connects a Railgun for a given zone. +// +// API reference: https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun +func (api *API) ConnectZoneRailgun(zoneID, railgunID string) (ZoneRailgun, error) { + return api.connectZoneRailgun(zoneID, railgunID, true) +} + +// DisconnectZoneRailgun disconnects a Railgun for a given zone. +// +// API reference: https://api.cloudflare.com/#railguns-for-a-zone-connect-or-disconnect-a-railgun +func (api *API) DisconnectZoneRailgun(zoneID, railgunID string) (ZoneRailgun, error) { + return api.connectZoneRailgun(zoneID, railgunID, false) +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/rate_limiting.go b/vendor/github.com/cloudflare/cloudflare-go/rate_limiting.go new file mode 100644 index 000000000..e3eb3e2e7 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/rate_limiting.go @@ -0,0 +1,210 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "strconv" + + "github.com/pkg/errors" +) + +// RateLimit is a policy than can be applied to limit traffic within a customer domain +type RateLimit struct { + ID string `json:"id,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Description string `json:"description,omitempty"` + Match RateLimitTrafficMatcher `json:"match"` + Bypass []RateLimitKeyValue `json:"bypass,omitempty"` + Threshold int `json:"threshold"` + Period int `json:"period"` + Action RateLimitAction `json:"action"` + Correlate *RateLimitCorrelate `json:"correlate,omitempty"` +} + +// RateLimitTrafficMatcher contains the rules that will be used to apply a rate limit to traffic +type RateLimitTrafficMatcher struct { + Request RateLimitRequestMatcher `json:"request"` + Response RateLimitResponseMatcher `json:"response"` +} + +// RateLimitRequestMatcher contains the matching rules pertaining to requests +type RateLimitRequestMatcher struct { + Methods []string `json:"methods,omitempty"` + Schemes []string `json:"schemes,omitempty"` + URLPattern string `json:"url,omitempty"` +} + +// RateLimitResponseMatcher contains the matching rules pertaining to responses +type RateLimitResponseMatcher struct { + Statuses []int `json:"status,omitempty"` + OriginTraffic *bool `json:"origin_traffic,omitempty"` // api defaults to true so we need an explicit empty value + Headers []RateLimitResponseMatcherHeader `json:"headers,omitempty"` +} + +// RateLimitResponseMatcherHeader contains the structure of the origin +// HTTP headers used in request matcher checks. +type RateLimitResponseMatcherHeader struct { + Name string `json:"name"` + Op string `json:"op"` + Value string `json:"value"` +} + +// RateLimitKeyValue is k-v formatted as expected in the rate limit description +type RateLimitKeyValue struct { + Name string `json:"name"` + Value string `json:"value"` +} + +// RateLimitAction is the action that will be taken when the rate limit threshold is reached +type RateLimitAction struct { + Mode string `json:"mode"` + Timeout int `json:"timeout"` + Response *RateLimitActionResponse `json:"response"` +} + +// RateLimitActionResponse is the response that will be returned when rate limit action is triggered +type RateLimitActionResponse struct { + ContentType string `json:"content_type"` + Body string `json:"body"` +} + +// RateLimitCorrelate pertainings to NAT support +type RateLimitCorrelate struct { + By string `json:"by"` +} + +type rateLimitResponse struct { + Response + Result RateLimit `json:"result"` +} + +type rateLimitListResponse struct { + Response + Result []RateLimit `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// CreateRateLimit creates a new rate limit for a zone. +// +// API reference: https://api.cloudflare.com/#rate-limits-for-a-zone-create-a-ratelimit +func (api *API) CreateRateLimit(zoneID string, limit RateLimit) (RateLimit, error) { + uri := "/zones/" + zoneID + "/rate_limits" + res, err := api.makeRequest("POST", uri, limit) + if err != nil { + return RateLimit{}, errors.Wrap(err, errMakeRequestError) + } + var r rateLimitResponse + if err := json.Unmarshal(res, &r); err != nil { + return RateLimit{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListRateLimits returns Rate Limits for a zone, paginated according to the provided options +// +// API reference: https://api.cloudflare.com/#rate-limits-for-a-zone-list-rate-limits +func (api *API) ListRateLimits(zoneID string, pageOpts PaginationOptions) ([]RateLimit, ResultInfo, error) { + v := url.Values{} + if pageOpts.PerPage > 0 { + v.Set("per_page", strconv.Itoa(pageOpts.PerPage)) + } + if pageOpts.Page > 0 { + v.Set("page", strconv.Itoa(pageOpts.Page)) + } + + uri := "/zones/" + zoneID + "/rate_limits" + if len(v) > 0 { + uri = uri + "?" + v.Encode() + } + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []RateLimit{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError) + } + + var r rateLimitListResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []RateLimit{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, r.ResultInfo, nil +} + +// ListAllRateLimits returns all Rate Limits for a zone. +// +// API reference: https://api.cloudflare.com/#rate-limits-for-a-zone-list-rate-limits +func (api *API) ListAllRateLimits(zoneID string) ([]RateLimit, error) { + pageOpts := PaginationOptions{ + PerPage: 100, // this is the max page size allowed + Page: 1, + } + + allRateLimits := make([]RateLimit, 0) + for { + rateLimits, resultInfo, err := api.ListRateLimits(zoneID, pageOpts) + if err != nil { + return []RateLimit{}, err + } + allRateLimits = append(allRateLimits, rateLimits...) + // total pages is not returned on this call + // if number of records is less than the max, this must be the last page + // in case TotalCount % PerPage = 0, the last request will return an empty list + if resultInfo.Count < resultInfo.PerPage { + break + } + // continue with the next page + pageOpts.Page = pageOpts.Page + 1 + } + + return allRateLimits, nil +} + +// RateLimit fetches detail about one Rate Limit for a zone. +// +// API reference: https://api.cloudflare.com/#rate-limits-for-a-zone-rate-limit-details +func (api *API) RateLimit(zoneID, limitID string) (RateLimit, error) { + uri := "/zones/" + zoneID + "/rate_limits/" + limitID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return RateLimit{}, errors.Wrap(err, errMakeRequestError) + } + var r rateLimitResponse + err = json.Unmarshal(res, &r) + if err != nil { + return RateLimit{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// UpdateRateLimit lets you replace a Rate Limit for a zone. +// +// API reference: https://api.cloudflare.com/#rate-limits-for-a-zone-update-rate-limit +func (api *API) UpdateRateLimit(zoneID, limitID string, limit RateLimit) (RateLimit, error) { + uri := "/zones/" + zoneID + "/rate_limits/" + limitID + res, err := api.makeRequest("PUT", uri, limit) + if err != nil { + return RateLimit{}, errors.Wrap(err, errMakeRequestError) + } + var r rateLimitResponse + if err := json.Unmarshal(res, &r); err != nil { + return RateLimit{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// DeleteRateLimit deletes a Rate Limit for a zone. +// +// API reference: https://api.cloudflare.com/#rate-limits-for-a-zone-delete-rate-limit +func (api *API) DeleteRateLimit(zoneID, limitID string) error { + uri := "/zones/" + zoneID + "/rate_limits/" + limitID + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + var r rateLimitResponse + err = json.Unmarshal(res, &r) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/registrar.go b/vendor/github.com/cloudflare/cloudflare-go/registrar.go new file mode 100644 index 000000000..e26d8a4f4 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/registrar.go @@ -0,0 +1,175 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/pkg/errors" +) + +// RegistrarDomain is the structure of the API response for a new +// Cloudflare Registrar domain. +type RegistrarDomain struct { + ID string `json:"id"` + Available bool `json:"available"` + SupportedTLD bool `json:"supported_tld"` + CanRegister bool `json:"can_register"` + TransferIn RegistrarTransferIn `json:"transfer_in"` + CurrentRegistrar string `json:"current_registrar"` + ExpiresAt time.Time `json:"expires_at"` + RegistryStatuses string `json:"registry_statuses"` + Locked bool `json:"locked"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + RegistrantContact RegistrantContact `json:"registrant_contact"` +} + +// RegistrarTransferIn contains the structure for a domain transfer in +// request. +type RegistrarTransferIn struct { + UnlockDomain string `json:"unlock_domain"` + DisablePrivacy string `json:"disable_privacy"` + EnterAuthCode string `json:"enter_auth_code"` + ApproveTransfer string `json:"approve_transfer"` + AcceptFoa string `json:"accept_foa"` + CanCancelTransfer bool `json:"can_cancel_transfer"` +} + +// RegistrantContact is the contact details for the domain registration. +type RegistrantContact struct { + ID string `json:"id"` + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + Organization string `json:"organization"` + Address string `json:"address"` + Address2 string `json:"address2"` + City string `json:"city"` + State string `json:"state"` + Zip string `json:"zip"` + Country string `json:"country"` + Phone string `json:"phone"` + Email string `json:"email"` + Fax string `json:"fax"` +} + +// RegistrarDomainConfiguration is the structure for making updates to +// and existing domain. +type RegistrarDomainConfiguration struct { + NameServers []string `json:"name_servers"` + Privacy bool `json:"privacy"` + Locked bool `json:"locked"` + AutoRenew bool `json:"auto_renew"` +} + +// RegistrarDomainDetailResponse is the structure of the detailed +// response from the API for a single domain. +type RegistrarDomainDetailResponse struct { + Response + Result RegistrarDomain `json:"result"` +} + +// RegistrarDomainsDetailResponse is the structure of the detailed +// response from the API. +type RegistrarDomainsDetailResponse struct { + Response + Result []RegistrarDomain `json:"result"` +} + +// RegistrarDomain returns a single domain based on the account ID and +// domain name. +// +// API reference: https://api.cloudflare.com/#registrar-domains-get-domain +func (api *API) RegistrarDomain(accountID, domainName string) (RegistrarDomain, error) { + uri := fmt.Sprintf("/accounts/%s/registrar/domains/%s", accountID, domainName) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return RegistrarDomain{}, errors.Wrap(err, errMakeRequestError) + } + + var r RegistrarDomainDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return RegistrarDomain{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// RegistrarDomains returns all registrar domains based on the account +// ID. +// +// API reference: https://api.cloudflare.com/#registrar-domains-list-domains +func (api *API) RegistrarDomains(accountID string) ([]RegistrarDomain, error) { + uri := "/accounts/" + accountID + "/registrar/domains" + + res, err := api.makeRequest("POST", uri, nil) + if err != nil { + return []RegistrarDomain{}, errors.Wrap(err, errMakeRequestError) + } + + var r RegistrarDomainsDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []RegistrarDomain{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// TransferRegistrarDomain initiates the transfer from another registrar +// to Cloudflare Registrar. +// +// API reference: https://api.cloudflare.com/#registrar-domains-transfer-domain +func (api *API) TransferRegistrarDomain(accountID, domainName string) ([]RegistrarDomain, error) { + uri := fmt.Sprintf("/accounts/%s/registrar/domains/%s/transfer", accountID, domainName) + + res, err := api.makeRequest("POST", uri, nil) + if err != nil { + return []RegistrarDomain{}, errors.Wrap(err, errMakeRequestError) + } + + var r RegistrarDomainsDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []RegistrarDomain{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// CancelRegistrarDomainTransfer cancels a pending domain transfer. +// +// API reference: https://api.cloudflare.com/#registrar-domains-cancel-transfer +func (api *API) CancelRegistrarDomainTransfer(accountID, domainName string) ([]RegistrarDomain, error) { + uri := fmt.Sprintf("/accounts/%s/registrar/domains/%s/cancel_transfer", accountID, domainName) + + res, err := api.makeRequest("POST", uri, nil) + if err != nil { + return []RegistrarDomain{}, errors.Wrap(err, errMakeRequestError) + } + + var r RegistrarDomainsDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []RegistrarDomain{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// UpdateRegistrarDomain updates an existing Registrar Domain configuration. +// +// API reference: https://api.cloudflare.com/#registrar-domains-update-domain +func (api *API) UpdateRegistrarDomain(accountID, domainName string, domainConfiguration RegistrarDomainConfiguration) (RegistrarDomain, error) { + uri := fmt.Sprintf("/accounts/%s/registrar/domains/%s", accountID, domainName) + + res, err := api.makeRequest("PUT", uri, domainConfiguration) + if err != nil { + return RegistrarDomain{}, errors.Wrap(err, errMakeRequestError) + } + + var r RegistrarDomainDetailResponse + err = json.Unmarshal(res, &r) + if err != nil { + return RegistrarDomain{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/renovate.json b/vendor/github.com/cloudflare/cloudflare-go/renovate.json new file mode 100644 index 000000000..f45d8f110 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/renovate.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "config:base" + ] +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/spectrum.go b/vendor/github.com/cloudflare/cloudflare-go/spectrum.go new file mode 100644 index 000000000..a95a2cd7f --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/spectrum.go @@ -0,0 +1,158 @@ +package cloudflare + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/pkg/errors" +) + +// SpectrumApplication defines a single Spectrum Application. +type SpectrumApplication struct { + ID string `json:"id,omitempty"` + Protocol string `json:"protocol,omitempty"` + IPv4 bool `json:"ipv4,omitempty"` + DNS SpectrumApplicationDNS `json:"dns,omitempty"` + OriginDirect []string `json:"origin_direct,omitempty"` + OriginPort int `json:"origin_port,omitempty"` + OriginDNS *SpectrumApplicationOriginDNS `json:"origin_dns,omitempty"` + IPFirewall bool `json:"ip_firewall,omitempty"` + ProxyProtocol bool `json:"proxy_protocol,omitempty"` + TLS string `json:"tls,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + ModifiedOn *time.Time `json:"modified_on,omitempty"` +} + +// SpectrumApplicationDNS holds the external DNS configuration for a Spectrum +// Application. +type SpectrumApplicationDNS struct { + Type string `json:"type"` + Name string `json:"name"` +} + +// SpectrumApplicationOriginDNS holds the origin DNS configuration for a Spectrum +// Application. +type SpectrumApplicationOriginDNS struct { + Name string `json:"name"` +} + +// SpectrumApplicationDetailResponse is the structure of the detailed response +// from the API. +type SpectrumApplicationDetailResponse struct { + Response + Result SpectrumApplication `json:"result"` +} + +// SpectrumApplicationsDetailResponse is the structure of the detailed response +// from the API. +type SpectrumApplicationsDetailResponse struct { + Response + Result []SpectrumApplication `json:"result"` +} + +// SpectrumApplications fetches all of the Spectrum applications for a zone. +// +// API reference: https://developers.cloudflare.com/spectrum/api-reference/#list-spectrum-applications +func (api *API) SpectrumApplications(zoneID string) ([]SpectrumApplication, error) { + uri := "/zones/" + zoneID + "/spectrum/apps" + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []SpectrumApplication{}, errors.Wrap(err, errMakeRequestError) + } + + var spectrumApplications SpectrumApplicationsDetailResponse + err = json.Unmarshal(res, &spectrumApplications) + if err != nil { + return []SpectrumApplication{}, errors.Wrap(err, errUnmarshalError) + } + + return spectrumApplications.Result, nil +} + +// SpectrumApplication fetches a single Spectrum application based on the ID. +// +// API reference: https://developers.cloudflare.com/spectrum/api-reference/#list-spectrum-applications +func (api *API) SpectrumApplication(zoneID string, applicationID string) (SpectrumApplication, error) { + uri := fmt.Sprintf( + "/zones/%s/spectrum/apps/%s", + zoneID, + applicationID, + ) + + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return SpectrumApplication{}, errors.Wrap(err, errMakeRequestError) + } + + var spectrumApplication SpectrumApplicationDetailResponse + err = json.Unmarshal(res, &spectrumApplication) + if err != nil { + return SpectrumApplication{}, errors.Wrap(err, errUnmarshalError) + } + + return spectrumApplication.Result, nil +} + +// CreateSpectrumApplication creates a new Spectrum application. +// +// API reference: https://developers.cloudflare.com/spectrum/api-reference/#create-a-spectrum-application +func (api *API) CreateSpectrumApplication(zoneID string, appDetails SpectrumApplication) (SpectrumApplication, error) { + uri := "/zones/" + zoneID + "/spectrum/apps" + + res, err := api.makeRequest("POST", uri, appDetails) + if err != nil { + return SpectrumApplication{}, errors.Wrap(err, errMakeRequestError) + } + + var spectrumApplication SpectrumApplicationDetailResponse + err = json.Unmarshal(res, &spectrumApplication) + if err != nil { + return SpectrumApplication{}, errors.Wrap(err, errUnmarshalError) + } + + return spectrumApplication.Result, nil +} + +// UpdateSpectrumApplication updates an existing Spectrum application. +// +// API reference: https://developers.cloudflare.com/spectrum/api-reference/#update-a-spectrum-application +func (api *API) UpdateSpectrumApplication(zoneID, appID string, appDetails SpectrumApplication) (SpectrumApplication, error) { + uri := fmt.Sprintf( + "/zones/%s/spectrum/apps/%s", + zoneID, + appID, + ) + + res, err := api.makeRequest("PUT", uri, appDetails) + if err != nil { + return SpectrumApplication{}, errors.Wrap(err, errMakeRequestError) + } + + var spectrumApplication SpectrumApplicationDetailResponse + err = json.Unmarshal(res, &spectrumApplication) + if err != nil { + return SpectrumApplication{}, errors.Wrap(err, errUnmarshalError) + } + + return spectrumApplication.Result, nil +} + +// DeleteSpectrumApplication removes a Spectrum application based on the ID. +// +// API reference: https://developers.cloudflare.com/spectrum/api-reference/#delete-a-spectrum-application +func (api *API) DeleteSpectrumApplication(zoneID string, applicationID string) error { + uri := fmt.Sprintf( + "/zones/%s/spectrum/apps/%s", + zoneID, + applicationID, + ) + + _, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/ssl.go b/vendor/github.com/cloudflare/cloudflare-go/ssl.go new file mode 100644 index 000000000..505dfa650 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/ssl.go @@ -0,0 +1,157 @@ +package cloudflare + +import ( + "encoding/json" + "time" + + "github.com/pkg/errors" +) + +// ZoneCustomSSL represents custom SSL certificate metadata. +type ZoneCustomSSL struct { + ID string `json:"id"` + Hosts []string `json:"hosts"` + Issuer string `json:"issuer"` + Signature string `json:"signature"` + Status string `json:"status"` + BundleMethod string `json:"bundle_method"` + GeoRestrictions ZoneCustomSSLGeoRestrictions `json:"geo_restrictions"` + ZoneID string `json:"zone_id"` + UploadedOn time.Time `json:"uploaded_on"` + ModifiedOn time.Time `json:"modified_on"` + ExpiresOn time.Time `json:"expires_on"` + Priority int `json:"priority"` + KeylessServer KeylessSSL `json:"keyless_server"` +} + +// ZoneCustomSSLGeoRestrictions represents the parameter to create or update +// geographic restrictions on a custom ssl certificate. +type ZoneCustomSSLGeoRestrictions struct { + Label string `json:"label"` +} + +// zoneCustomSSLResponse represents the response from the zone SSL details endpoint. +type zoneCustomSSLResponse struct { + Response + Result ZoneCustomSSL `json:"result"` +} + +// zoneCustomSSLsResponse represents the response from the zone SSL list endpoint. +type zoneCustomSSLsResponse struct { + Response + Result []ZoneCustomSSL `json:"result"` +} + +// ZoneCustomSSLOptions represents the parameters to create or update an existing +// custom SSL configuration. +type ZoneCustomSSLOptions struct { + Certificate string `json:"certificate"` + PrivateKey string `json:"private_key"` + BundleMethod string `json:"bundle_method,omitempty"` + GeoRestrictions ZoneCustomSSLGeoRestrictions `json:"geo_restrictions,omitempty"` + Type string `json:"type,omitempty"` +} + +// ZoneCustomSSLPriority represents a certificate's ID and priority. It is a +// subset of ZoneCustomSSL used for patch requests. +type ZoneCustomSSLPriority struct { + ID string `json:"ID"` + Priority int `json:"priority"` +} + +// CreateSSL allows you to add a custom SSL certificate to the given zone. +// +// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-create-ssl-configuration +func (api *API) CreateSSL(zoneID string, options ZoneCustomSSLOptions) (ZoneCustomSSL, error) { + uri := "/zones/" + zoneID + "/custom_certificates" + res, err := api.makeRequest("POST", uri, options) + if err != nil { + return ZoneCustomSSL{}, errors.Wrap(err, errMakeRequestError) + } + var r zoneCustomSSLResponse + if err := json.Unmarshal(res, &r); err != nil { + return ZoneCustomSSL{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListSSL lists the custom certificates for the given zone. +// +// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-list-ssl-configurations +func (api *API) ListSSL(zoneID string) ([]ZoneCustomSSL, error) { + uri := "/zones/" + zoneID + "/custom_certificates" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r zoneCustomSSLsResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// SSLDetails returns the configuration details for a custom SSL certificate. +// +// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-ssl-configuration-details +func (api *API) SSLDetails(zoneID, certificateID string) (ZoneCustomSSL, error) { + uri := "/zones/" + zoneID + "/custom_certificates/" + certificateID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return ZoneCustomSSL{}, errors.Wrap(err, errMakeRequestError) + } + var r zoneCustomSSLResponse + if err := json.Unmarshal(res, &r); err != nil { + return ZoneCustomSSL{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// UpdateSSL updates (replaces) a custom SSL certificate. +// +// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-update-ssl-configuration +func (api *API) UpdateSSL(zoneID, certificateID string, options ZoneCustomSSLOptions) (ZoneCustomSSL, error) { + uri := "/zones/" + zoneID + "/custom_certificates/" + certificateID + res, err := api.makeRequest("PATCH", uri, options) + if err != nil { + return ZoneCustomSSL{}, errors.Wrap(err, errMakeRequestError) + } + var r zoneCustomSSLResponse + if err := json.Unmarshal(res, &r); err != nil { + return ZoneCustomSSL{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ReprioritizeSSL allows you to change the priority (which is served for a given +// request) of custom SSL certificates associated with the given zone. +// +// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-re-prioritize-ssl-certificates +func (api *API) ReprioritizeSSL(zoneID string, p []ZoneCustomSSLPriority) ([]ZoneCustomSSL, error) { + uri := "/zones/" + zoneID + "/custom_certificates/prioritize" + params := struct { + Certificates []ZoneCustomSSLPriority `json:"certificates"` + }{ + Certificates: p, + } + res, err := api.makeRequest("PUT", uri, params) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r zoneCustomSSLsResponse + if err := json.Unmarshal(res, &r); err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// DeleteSSL deletes a custom SSL certificate from the given zone. +// +// API reference: https://api.cloudflare.com/#custom-ssl-for-a-zone-delete-an-ssl-certificate +func (api *API) DeleteSSL(zoneID, certificateID string) error { + uri := "/zones/" + zoneID + "/custom_certificates/" + certificateID + if _, err := api.makeRequest("DELETE", uri, nil); err != nil { + return errors.Wrap(err, errMakeRequestError) + } + return nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/universal_ssl.go b/vendor/github.com/cloudflare/cloudflare-go/universal_ssl.go new file mode 100644 index 000000000..4bf8ffde7 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/universal_ssl.go @@ -0,0 +1,88 @@ +package cloudflare + +import ( + "encoding/json" + + "github.com/pkg/errors" +) + +// UniversalSSLSetting represents a universal ssl setting's properties. +type UniversalSSLSetting struct { + Enabled bool `json:"enabled"` +} + +type universalSSLSettingResponse struct { + Response + Result UniversalSSLSetting `json:"result"` +} + +// UniversalSSLVerificationDetails represents a universal ssl verifcation's properties. +type UniversalSSLVerificationDetails struct { + CertificateStatus string `json:"certificate_status"` + VerificationType string `json:"verification_type"` + ValidationMethod string `json:"validation_method"` + CertPackUUID string `json:"cert_pack_uuid"` + VerificationStatus bool `json:"verification_status"` + BrandCheck bool `json:"brand_check"` + VerificationInfo UniversalSSLVerificationInfo `json:"verification_info"` +} + +// UniversalSSLVerificationInfo represents DCV record. +type UniversalSSLVerificationInfo struct { + RecordName string `json:"record_name"` + RecordTarget string `json:"record_target"` +} + +type universalSSLVerificationResponse struct { + Response + Result []UniversalSSLVerificationDetails `json:"result"` +} + +// UniversalSSLSettingDetails returns the details for a universal ssl setting +// +// API reference: https://api.cloudflare.com/#universal-ssl-settings-for-a-zone-universal-ssl-settings-details +func (api *API) UniversalSSLSettingDetails(zoneID string) (UniversalSSLSetting, error) { + uri := "/zones/" + zoneID + "/ssl/universal/settings" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return UniversalSSLSetting{}, errors.Wrap(err, errMakeRequestError) + } + var r universalSSLSettingResponse + if err := json.Unmarshal(res, &r); err != nil { + return UniversalSSLSetting{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// EditUniversalSSLSetting edits the uniersal ssl setting for a zone +// +// API reference: https://api.cloudflare.com/#universal-ssl-settings-for-a-zone-edit-universal-ssl-settings +func (api *API) EditUniversalSSLSetting(zoneID string, setting UniversalSSLSetting) (UniversalSSLSetting, error) { + uri := "/zones/" + zoneID + "/ssl/universal/settings" + res, err := api.makeRequest("PATCH", uri, setting) + if err != nil { + return UniversalSSLSetting{}, errors.Wrap(err, errMakeRequestError) + } + var r universalSSLSettingResponse + if err := json.Unmarshal(res, &r); err != nil { + return UniversalSSLSetting{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil + +} + +// UniversalSSLVerificationDetails returns the details for a universal ssl verifcation +// +// API reference: https://api.cloudflare.com/#ssl-verification-ssl-verification-details +func (api *API) UniversalSSLVerificationDetails(zoneID string) ([]UniversalSSLVerificationDetails, error) { + uri := "/zones/" + zoneID + "/ssl/verification" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []UniversalSSLVerificationDetails{}, errors.Wrap(err, errMakeRequestError) + } + var r universalSSLVerificationResponse + if err := json.Unmarshal(res, &r); err != nil { + return []UniversalSSLVerificationDetails{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/user.go b/vendor/github.com/cloudflare/cloudflare-go/user.go new file mode 100644 index 000000000..bf2f47a57 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/user.go @@ -0,0 +1,113 @@ +package cloudflare + +import ( + "encoding/json" + "time" + + "github.com/pkg/errors" +) + +// User describes a user account. +type User struct { + ID string `json:"id,omitempty"` + Email string `json:"email,omitempty"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` + Username string `json:"username,omitempty"` + Telephone string `json:"telephone,omitempty"` + Country string `json:"country,omitempty"` + Zipcode string `json:"zipcode,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + ModifiedOn *time.Time `json:"modified_on,omitempty"` + APIKey string `json:"api_key,omitempty"` + TwoFA bool `json:"two_factor_authentication_enabled,omitempty"` + Betas []string `json:"betas,omitempty"` + Accounts []Account `json:"organizations,omitempty"` +} + +// UserResponse wraps a response containing User accounts. +type UserResponse struct { + Response + Result User `json:"result"` +} + +// userBillingProfileResponse wraps a response containing Billing Profile information. +type userBillingProfileResponse struct { + Response + Result UserBillingProfile +} + +// UserBillingProfile contains Billing Profile information. +type UserBillingProfile struct { + ID string `json:"id,omitempty"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` + Address string `json:"address,omitempty"` + Address2 string `json:"address2,omitempty"` + Company string `json:"company,omitempty"` + City string `json:"city,omitempty"` + State string `json:"state,omitempty"` + ZipCode string `json:"zipcode,omitempty"` + Country string `json:"country,omitempty"` + Telephone string `json:"telephone,omitempty"` + CardNumber string `json:"card_number,omitempty"` + CardExpiryYear int `json:"card_expiry_year,omitempty"` + CardExpiryMonth int `json:"card_expiry_month,omitempty"` + VAT string `json:"vat,omitempty"` + CreatedOn *time.Time `json:"created_on,omitempty"` + EditedOn *time.Time `json:"edited_on,omitempty"` +} + +// UserDetails provides information about the logged-in user. +// +// API reference: https://api.cloudflare.com/#user-user-details +func (api *API) UserDetails() (User, error) { + var r UserResponse + res, err := api.makeRequest("GET", "/user", nil) + if err != nil { + return User{}, errors.Wrap(err, errMakeRequestError) + } + + err = json.Unmarshal(res, &r) + if err != nil { + return User{}, errors.Wrap(err, errUnmarshalError) + } + + return r.Result, nil +} + +// UpdateUser updates the properties of the given user. +// +// API reference: https://api.cloudflare.com/#user-update-user +func (api *API) UpdateUser(user *User) (User, error) { + var r UserResponse + res, err := api.makeRequest("PATCH", "/user", user) + if err != nil { + return User{}, errors.Wrap(err, errMakeRequestError) + } + + err = json.Unmarshal(res, &r) + if err != nil { + return User{}, errors.Wrap(err, errUnmarshalError) + } + + return r.Result, nil +} + +// UserBillingProfile returns the billing profile of the user. +// +// API reference: https://api.cloudflare.com/#user-billing-profile +func (api *API) UserBillingProfile() (UserBillingProfile, error) { + var r userBillingProfileResponse + res, err := api.makeRequest("GET", "/user/billing/profile", nil) + if err != nil { + return UserBillingProfile{}, errors.Wrap(err, errMakeRequestError) + } + + err = json.Unmarshal(res, &r) + if err != nil { + return UserBillingProfile{}, errors.Wrap(err, errUnmarshalError) + } + + return r.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/user_agent.go b/vendor/github.com/cloudflare/cloudflare-go/user_agent.go new file mode 100644 index 000000000..6d75f3a1d --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/user_agent.go @@ -0,0 +1,149 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "strconv" + + "github.com/pkg/errors" +) + +// UserAgentRule represents a User-Agent Block. These rules can be used to +// challenge, block or whitelist specific User-Agents for a given zone. +type UserAgentRule struct { + ID string `json:"id"` + Description string `json:"description"` + Mode string `json:"mode"` + Configuration UserAgentRuleConfig `json:"configuration"` + Paused bool `json:"paused"` +} + +// UserAgentRuleConfig represents a Zone Lockdown config, which comprises +// a Target ("ip" or "ip_range") and a Value (an IP address or IP+mask, +// respectively.) +type UserAgentRuleConfig ZoneLockdownConfig + +// UserAgentRuleResponse represents a response from the Zone Lockdown endpoint. +type UserAgentRuleResponse struct { + Result UserAgentRule `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// UserAgentRuleListResponse represents a response from the List Zone Lockdown endpoint. +type UserAgentRuleListResponse struct { + Result []UserAgentRule `json:"result"` + Response + ResultInfo `json:"result_info"` +} + +// CreateUserAgentRule creates a User-Agent Block rule for the given zone ID. +// +// API reference: https://api.cloudflare.com/#user-agent-blocking-rules-create-a-useragent-rule +func (api *API) CreateUserAgentRule(zoneID string, ld UserAgentRule) (*UserAgentRuleResponse, error) { + switch ld.Mode { + case "block", "challenge", "js_challenge", "whitelist": + break + default: + return nil, errors.New(`the User-Agent Block rule mode must be one of "block", "challenge", "js_challenge", "whitelist"`) + } + + uri := "/zones/" + zoneID + "/firewall/ua_rules" + res, err := api.makeRequest("POST", uri, ld) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &UserAgentRuleResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// UpdateUserAgentRule updates a User-Agent Block rule (based on the ID) for the given zone ID. +// +// API reference: https://api.cloudflare.com/#user-agent-blocking-rules-update-useragent-rule +func (api *API) UpdateUserAgentRule(zoneID string, id string, ld UserAgentRule) (*UserAgentRuleResponse, error) { + uri := "/zones/" + zoneID + "/firewall/ua_rules/" + id + res, err := api.makeRequest("PUT", uri, ld) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &UserAgentRuleResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// DeleteUserAgentRule deletes a User-Agent Block rule (based on the ID) for the given zone ID. +// +// API reference: https://api.cloudflare.com/#user-agent-blocking-rules-delete-useragent-rule +func (api *API) DeleteUserAgentRule(zoneID string, id string) (*UserAgentRuleResponse, error) { + uri := "/zones/" + zoneID + "/firewall/ua_rules/" + id + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &UserAgentRuleResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// UserAgentRule retrieves a User-Agent Block rule (based on the ID) for the given zone ID. +// +// API reference: https://api.cloudflare.com/#user-agent-blocking-rules-useragent-rule-details +func (api *API) UserAgentRule(zoneID string, id string) (*UserAgentRuleResponse, error) { + uri := "/zones/" + zoneID + "/firewall/ua_rules/" + id + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &UserAgentRuleResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// ListUserAgentRules retrieves a list of User-Agent Block rules for a given zone ID by page number. +// +// API reference: https://api.cloudflare.com/#user-agent-blocking-rules-list-useragent-rules +func (api *API) ListUserAgentRules(zoneID string, page int) (*UserAgentRuleListResponse, error) { + v := url.Values{} + if page <= 0 { + page = 1 + } + + v.Set("page", strconv.Itoa(page)) + v.Set("per_page", strconv.Itoa(100)) + query := "?" + v.Encode() + + uri := "/zones/" + zoneID + "/firewall/ua_rules" + query + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &UserAgentRuleListResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/virtualdns.go b/vendor/github.com/cloudflare/cloudflare-go/virtualdns.go new file mode 100644 index 000000000..f8082e1f0 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/virtualdns.go @@ -0,0 +1,192 @@ +package cloudflare + +import ( + "encoding/json" + "net/url" + "strings" + "time" + + "github.com/pkg/errors" +) + +// VirtualDNS represents a Virtual DNS configuration. +type VirtualDNS struct { + ID string `json:"id"` + Name string `json:"name"` + OriginIPs []string `json:"origin_ips"` + VirtualDNSIPs []string `json:"virtual_dns_ips"` + MinimumCacheTTL uint `json:"minimum_cache_ttl"` + MaximumCacheTTL uint `json:"maximum_cache_ttl"` + DeprecateAnyRequests bool `json:"deprecate_any_requests"` + ModifiedOn string `json:"modified_on"` +} + +// VirtualDNSAnalyticsMetrics respresents a group of aggregated Virtual DNS metrics. +type VirtualDNSAnalyticsMetrics struct { + QueryCount *int64 `json:"queryCount"` + UncachedCount *int64 `json:"uncachedCount"` + StaleCount *int64 `json:"staleCount"` + ResponseTimeAvg *float64 `json:"responseTimeAvg"` + ResponseTimeMedian *float64 `json:"responseTimeMedian"` + ResponseTime90th *float64 `json:"responseTime90th"` + ResponseTime99th *float64 `json:"responseTime99th"` +} + +// VirtualDNSAnalytics represents a set of aggregated Virtual DNS metrics. +// TODO: Add the queried data and not only the aggregated values. +type VirtualDNSAnalytics struct { + Totals VirtualDNSAnalyticsMetrics `json:"totals"` + Min VirtualDNSAnalyticsMetrics `json:"min"` + Max VirtualDNSAnalyticsMetrics `json:"max"` +} + +// VirtualDNSUserAnalyticsOptions represents range and dimension selection on analytics endpoint +type VirtualDNSUserAnalyticsOptions struct { + Metrics []string + Since *time.Time + Until *time.Time +} + +// VirtualDNSResponse represents a Virtual DNS response. +type VirtualDNSResponse struct { + Response + Result *VirtualDNS `json:"result"` +} + +// VirtualDNSListResponse represents an array of Virtual DNS responses. +type VirtualDNSListResponse struct { + Response + Result []*VirtualDNS `json:"result"` +} + +// VirtualDNSAnalyticsResponse represents a Virtual DNS analytics response. +type VirtualDNSAnalyticsResponse struct { + Response + Result VirtualDNSAnalytics `json:"result"` +} + +// CreateVirtualDNS creates a new Virtual DNS cluster. +// +// API reference: https://api.cloudflare.com/#virtual-dns-users--create-a-virtual-dns-cluster +func (api *API) CreateVirtualDNS(v *VirtualDNS) (*VirtualDNS, error) { + res, err := api.makeRequest("POST", "/user/virtual_dns", v) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &VirtualDNSResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response.Result, nil +} + +// VirtualDNS fetches a single virtual DNS cluster. +// +// API reference: https://api.cloudflare.com/#virtual-dns-users--get-a-virtual-dns-cluster +func (api *API) VirtualDNS(virtualDNSID string) (*VirtualDNS, error) { + uri := "/user/virtual_dns/" + virtualDNSID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &VirtualDNSResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response.Result, nil +} + +// ListVirtualDNS lists the virtual DNS clusters associated with an account. +// +// API reference: https://api.cloudflare.com/#virtual-dns-users--get-virtual-dns-clusters +func (api *API) ListVirtualDNS() ([]*VirtualDNS, error) { + res, err := api.makeRequest("GET", "/user/virtual_dns", nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &VirtualDNSListResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response.Result, nil +} + +// UpdateVirtualDNS updates a Virtual DNS cluster. +// +// API reference: https://api.cloudflare.com/#virtual-dns-users--modify-a-virtual-dns-cluster +func (api *API) UpdateVirtualDNS(virtualDNSID string, vv VirtualDNS) error { + uri := "/user/virtual_dns/" + virtualDNSID + res, err := api.makeRequest("PUT", uri, vv) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + response := &VirtualDNSResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + + return nil +} + +// DeleteVirtualDNS deletes a Virtual DNS cluster. Note that this cannot be +// undone, and will stop all traffic to that cluster. +// +// API reference: https://api.cloudflare.com/#virtual-dns-users--delete-a-virtual-dns-cluster +func (api *API) DeleteVirtualDNS(virtualDNSID string) error { + uri := "/user/virtual_dns/" + virtualDNSID + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return errors.Wrap(err, errMakeRequestError) + } + + response := &VirtualDNSResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return errors.Wrap(err, errUnmarshalError) + } + + return nil +} + +// encode encodes non-nil fields into URL encoded form. +func (o VirtualDNSUserAnalyticsOptions) encode() string { + v := url.Values{} + if o.Since != nil { + v.Set("since", (*o.Since).UTC().Format(time.RFC3339)) + } + if o.Until != nil { + v.Set("until", (*o.Until).UTC().Format(time.RFC3339)) + } + if o.Metrics != nil { + v.Set("metrics", strings.Join(o.Metrics, ",")) + } + return v.Encode() +} + +// VirtualDNSUserAnalytics retrieves analytics report for a specified dimension and time range +func (api *API) VirtualDNSUserAnalytics(virtualDNSID string, o VirtualDNSUserAnalyticsOptions) (VirtualDNSAnalytics, error) { + uri := "/user/virtual_dns/" + virtualDNSID + "/dns_analytics/report?" + o.encode() + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return VirtualDNSAnalytics{}, errors.Wrap(err, errMakeRequestError) + } + + response := VirtualDNSAnalyticsResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return VirtualDNSAnalytics{}, errors.Wrap(err, errUnmarshalError) + } + + return response.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/waf.go b/vendor/github.com/cloudflare/cloudflare-go/waf.go new file mode 100644 index 000000000..71878368e --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/waf.go @@ -0,0 +1,255 @@ +package cloudflare + +import ( + "encoding/json" + + "github.com/pkg/errors" +) + +// WAFPackage represents a WAF package configuration. +type WAFPackage struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + ZoneID string `json:"zone_id"` + DetectionMode string `json:"detection_mode"` + Sensitivity string `json:"sensitivity"` + ActionMode string `json:"action_mode"` +} + +// WAFPackagesResponse represents the response from the WAF packages endpoint. +type WAFPackagesResponse struct { + Response + Result []WAFPackage `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// WAFPackageResponse represents the response from the WAF package endpoint. +type WAFPackageResponse struct { + Response + Result WAFPackage `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// WAFPackageOptions represents options to edit a WAF package. +type WAFPackageOptions struct { + Sensitivity string `json:"sensitivity,omitempty"` + ActionMode string `json:"action_mode,omitempty"` +} + +// WAFGroup represents a WAF rule group. +type WAFGroup struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + RulesCount int `json:"rules_count"` + ModifiedRulesCount int `json:"modified_rules_count"` + PackageID string `json:"package_id"` + Mode string `json:"mode"` + AllowedModes []string `json:"allowed_modes"` +} + +// WAFGroupsResponse represents the response from the WAF groups endpoint. +type WAFGroupsResponse struct { + Response + Result []WAFGroup `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// WAFRule represents a WAF rule. +type WAFRule struct { + ID string `json:"id"` + Description string `json:"description"` + Priority string `json:"priority"` + PackageID string `json:"package_id"` + Group struct { + ID string `json:"id"` + Name string `json:"name"` + } `json:"group"` + Mode string `json:"mode"` + DefaultMode string `json:"default_mode"` + AllowedModes []string `json:"allowed_modes"` +} + +// WAFRulesResponse represents the response from the WAF rules endpoint. +type WAFRulesResponse struct { + Response + Result []WAFRule `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// WAFRuleResponse represents the response from the WAF rule endpoint. +type WAFRuleResponse struct { + Response + Result WAFRule `json:"result"` + ResultInfo ResultInfo `json:"result_info"` +} + +// WAFRuleOptions is a subset of WAFRule, for editable options. +type WAFRuleOptions struct { + Mode string `json:"mode"` +} + +// ListWAFPackages returns a slice of the WAF packages for the given zone. +// +// API Reference: https://api.cloudflare.com/#waf-rule-packages-list-firewall-packages +func (api *API) ListWAFPackages(zoneID string) ([]WAFPackage, error) { + var p WAFPackagesResponse + var packages []WAFPackage + var res []byte + var err error + uri := "/zones/" + zoneID + "/firewall/waf/packages" + res, err = api.makeRequest("GET", uri, nil) + if err != nil { + return []WAFPackage{}, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &p) + if err != nil { + return []WAFPackage{}, errors.Wrap(err, errUnmarshalError) + } + if !p.Success { + // TODO: Provide an actual error message instead of always returning nil + return []WAFPackage{}, err + } + for pi := range p.Result { + packages = append(packages, p.Result[pi]) + } + return packages, nil +} + +// WAFPackage returns a WAF package for the given zone. +// +// API Reference: https://api.cloudflare.com/#waf-rule-packages-firewall-package-details +func (api *API) WAFPackage(zoneID, packageID string) (WAFPackage, error) { + uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return WAFPackage{}, errors.Wrap(err, errMakeRequestError) + } + + var r WAFPackageResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WAFPackage{}, errors.Wrap(err, errUnmarshalError) + } + + return r.Result, nil +} + +// UpdateWAFPackage lets you update the a WAF Package. +// +// API Reference: https://api.cloudflare.com/#waf-rule-packages-edit-firewall-package +func (api *API) UpdateWAFPackage(zoneID, packageID string, opts WAFPackageOptions) (WAFPackage, error) { + uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + res, err := api.makeRequest("PATCH", uri, opts) + if err != nil { + return WAFPackage{}, errors.Wrap(err, errMakeRequestError) + } + + var r WAFPackageResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WAFPackage{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ListWAFGroups returns a slice of the WAF groups for the given WAF package. +// +// API Reference: https://api.cloudflare.com/#waf-rule-groups-list-rule-groups +func (api *API) ListWAFGroups(zoneID, packageID string) ([]WAFGroup, error) { + var groups []WAFGroup + var res []byte + var err error + + uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + "/groups" + res, err = api.makeRequest("GET", uri, nil) + if err != nil { + return []WAFGroup{}, errors.Wrap(err, errMakeRequestError) + } + + var r WAFGroupsResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []WAFGroup{}, errors.Wrap(err, errUnmarshalError) + } + + if !r.Success { + // TODO: Provide an actual error message instead of always returning nil + return []WAFGroup{}, err + } + + for gi := range r.Result { + groups = append(groups, r.Result[gi]) + } + return groups, nil +} + +// ListWAFRules returns a slice of the WAF rules for the given WAF package. +// +// API Reference: https://api.cloudflare.com/#waf-rules-list-rules +func (api *API) ListWAFRules(zoneID, packageID string) ([]WAFRule, error) { + var rules []WAFRule + var res []byte + var err error + + uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + "/rules" + res, err = api.makeRequest("GET", uri, nil) + if err != nil { + return []WAFRule{}, errors.Wrap(err, errMakeRequestError) + } + + var r WAFRulesResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []WAFRule{}, errors.Wrap(err, errUnmarshalError) + } + + if !r.Success { + // TODO: Provide an actual error message instead of always returning nil + return []WAFRule{}, err + } + + for ri := range r.Result { + rules = append(rules, r.Result[ri]) + } + return rules, nil +} + +// WAFRule returns a WAF rule from the given WAF package. +// +// API Reference: https://api.cloudflare.com/#waf-rules-rule-details +func (api *API) WAFRule(zoneID, packageID, ruleID string) (WAFRule, error) { + uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + "/rules/" + ruleID + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return WAFRule{}, errors.Wrap(err, errMakeRequestError) + } + + var r WAFRuleResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WAFRule{}, errors.Wrap(err, errUnmarshalError) + } + + return r.Result, nil +} + +// UpdateWAFRule lets you update the mode of a WAF Rule. +// +// API Reference: https://api.cloudflare.com/#waf-rules-edit-rule +func (api *API) UpdateWAFRule(zoneID, packageID, ruleID, mode string) (WAFRule, error) { + opts := WAFRuleOptions{Mode: mode} + uri := "/zones/" + zoneID + "/firewall/waf/packages/" + packageID + "/rules/" + ruleID + res, err := api.makeRequest("PATCH", uri, opts) + if err != nil { + return WAFRule{}, errors.Wrap(err, errMakeRequestError) + } + + var r WAFRuleResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WAFRule{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/workers.go b/vendor/github.com/cloudflare/cloudflare-go/workers.go new file mode 100644 index 000000000..1ab795ec4 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/workers.go @@ -0,0 +1,314 @@ +package cloudflare + +import ( + "encoding/json" + "net/http" + "time" + + "github.com/pkg/errors" +) + +// WorkerRequestParams provides parameters for worker requests for both enterprise and standard requests +type WorkerRequestParams struct { + ZoneID string + ScriptName string +} + +// WorkerRoute aka filters are patterns used to enable or disable workers that match requests. +// +// API reference: https://api.cloudflare.com/#worker-filters-properties +type WorkerRoute struct { + ID string `json:"id,omitempty"` + Pattern string `json:"pattern"` + Enabled bool `json:"enabled"` + Script string `json:"script,omitempty"` +} + +// WorkerRoutesResponse embeds Response struct and slice of WorkerRoutes +type WorkerRoutesResponse struct { + Response + Routes []WorkerRoute `json:"result"` +} + +// WorkerRouteResponse embeds Response struct and a single WorkerRoute +type WorkerRouteResponse struct { + Response + WorkerRoute `json:"result"` +} + +// WorkerScript Cloudflare Worker struct with metadata +type WorkerScript struct { + WorkerMetaData + Script string `json:"script"` +} + +// WorkerMetaData contains worker script information such as size, creation & modification dates +type WorkerMetaData struct { + ID string `json:"id,omitempty"` + ETAG string `json:"etag,omitempty"` + Size int `json:"size,omitempty"` + CreatedOn time.Time `json:"created_on,omitempty"` + ModifiedOn time.Time `json:"modified_on,omitempty"` +} + +// WorkerListResponse wrapper struct for API response to worker script list API call +type WorkerListResponse struct { + Response + WorkerList []WorkerMetaData `json:"result"` +} + +// WorkerScriptResponse wrapper struct for API response to worker script calls +type WorkerScriptResponse struct { + Response + WorkerScript `json:"result"` +} + +// DeleteWorker deletes worker for a zone. +// +// API reference: https://api.cloudflare.com/#worker-script-delete-worker +func (api *API) DeleteWorker(requestParams *WorkerRequestParams) (WorkerScriptResponse, error) { + // if ScriptName is provided we will treat as org request + if requestParams.ScriptName != "" { + return api.deleteWorkerWithName(requestParams.ScriptName) + } + uri := "/zones/" + requestParams.ZoneID + "/workers/script" + res, err := api.makeRequest("DELETE", uri, nil) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return r, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// DeleteWorkerWithName deletes worker for a zone. +// This is an enterprise only feature https://developers.cloudflare.com/workers/api/config-api-for-enterprise +// account must be specified as api option https://godoc.org/github.com/cloudflare/cloudflare-go#UsingAccount +// +// API reference: https://api.cloudflare.com/#worker-script-delete-worker +func (api *API) deleteWorkerWithName(scriptName string) (WorkerScriptResponse, error) { + if api.AccountID == "" { + return WorkerScriptResponse{}, errors.New("account ID required for enterprise only request") + } + uri := "/accounts/" + api.AccountID + "/workers/scripts/" + scriptName + res, err := api.makeRequest("DELETE", uri, nil) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return r, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// DownloadWorker fetch raw script content for your worker returns []byte containing worker code js +// +// API reference: https://api.cloudflare.com/#worker-script-download-worker +func (api *API) DownloadWorker(requestParams *WorkerRequestParams) (WorkerScriptResponse, error) { + if requestParams.ScriptName != "" { + return api.downloadWorkerWithName(requestParams.ScriptName) + } + uri := "/zones/" + requestParams.ZoneID + "/workers/script" + res, err := api.makeRequest("GET", uri, nil) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + r.Script = string(res) + r.Success = true + return r, nil +} + +// DownloadWorkerWithName fetch raw script content for your worker returns string containing worker code js +// This is an enterprise only feature https://developers.cloudflare.com/workers/api/config-api-for-enterprise/ +// +// API reference: https://api.cloudflare.com/#worker-script-download-worker +func (api *API) downloadWorkerWithName(scriptName string) (WorkerScriptResponse, error) { + if api.AccountID == "" { + return WorkerScriptResponse{}, errors.New("account ID required for enterprise only request") + } + uri := "/accounts/" + api.AccountID + "/workers/scripts/" + scriptName + res, err := api.makeRequest("GET", uri, nil) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + r.Script = string(res) + r.Success = true + return r, nil +} + +// ListWorkerScripts returns list of worker scripts for given account. +// +// This is an enterprise only feature https://developers.cloudflare.com/workers/api/config-api-for-enterprise +// +// API reference: https://developers.cloudflare.com/workers/api/config-api-for-enterprise/ +func (api *API) ListWorkerScripts() (WorkerListResponse, error) { + if api.AccountID == "" { + return WorkerListResponse{}, errors.New("account ID required for enterprise only request") + } + uri := "/accounts/" + api.AccountID + "/workers/scripts" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return WorkerListResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerListResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerListResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// UploadWorker push raw script content for your worker. +// +// API reference: https://api.cloudflare.com/#worker-script-upload-worker +func (api *API) UploadWorker(requestParams *WorkerRequestParams, data string) (WorkerScriptResponse, error) { + if requestParams.ScriptName != "" { + return api.uploadWorkerWithName(requestParams.ScriptName, data) + } + uri := "/zones/" + requestParams.ZoneID + "/workers/script" + headers := make(http.Header) + headers.Set("Content-Type", "application/javascript") + res, err := api.makeRequestWithHeaders("PUT", uri, []byte(data), headers) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return r, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// UploadWorkerWithName push raw script content for your worker. +// +// This is an enterprise only feature https://developers.cloudflare.com/workers/api/config-api-for-enterprise/ +// +// API reference: https://api.cloudflare.com/#worker-script-upload-worker +func (api *API) uploadWorkerWithName(scriptName string, data string) (WorkerScriptResponse, error) { + if api.AccountID == "" { + return WorkerScriptResponse{}, errors.New("account ID required for enterprise only request") + } + uri := "/accounts/" + api.AccountID + "/workers/scripts/" + scriptName + headers := make(http.Header) + headers.Set("Content-Type", "application/javascript") + res, err := api.makeRequestWithHeaders("PUT", uri, []byte(data), headers) + var r WorkerScriptResponse + if err != nil { + return r, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return r, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// CreateWorkerRoute creates worker route for a zone +// +// API reference: https://api.cloudflare.com/#worker-filters-create-filter +func (api *API) CreateWorkerRoute(zoneID string, route WorkerRoute) (WorkerRouteResponse, error) { + // Check whether a script name is defined in order to determine whether + // to use the single-script or multi-script endpoint. + pathComponent := "filters" + if route.Script != "" { + if api.AccountID == "" { + return WorkerRouteResponse{}, errors.New("account ID required for enterprise only request") + } + pathComponent = "routes" + } + + uri := "/zones/" + zoneID + "/workers/" + pathComponent + res, err := api.makeRequest("POST", uri, route) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerRouteResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// DeleteWorkerRoute deletes worker route for a zone +// +// API reference: https://api.cloudflare.com/#worker-filters-delete-filter +func (api *API) DeleteWorkerRoute(zoneID string, routeID string) (WorkerRouteResponse, error) { + // For deleting a route, it doesn't matter whether we use the + // single-script or multi-script endpoint + uri := "/zones/" + zoneID + "/workers/filters/" + routeID + res, err := api.makeRequest("DELETE", uri, nil) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerRouteResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// ListWorkerRoutes returns list of worker routes +// +// API reference: https://api.cloudflare.com/#worker-filters-list-filters +func (api *API) ListWorkerRoutes(zoneID string) (WorkerRoutesResponse, error) { + pathComponent := "filters" + if api.AccountID != "" { + pathComponent = "routes" + } + uri := "/zones/" + zoneID + "/workers/" + pathComponent + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return WorkerRoutesResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerRoutesResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerRoutesResponse{}, errors.Wrap(err, errUnmarshalError) + } + for i := range r.Routes { + route := &r.Routes[i] + // The Enabled flag will not be set in the multi-script API response + // so we manually set it to true if the script name is not empty + // in case any multi-script customers rely on the Enabled field + if route.Script != "" { + route.Enabled = true + } + } + return r, nil +} + +// UpdateWorkerRoute updates worker route for a zone. +// +// API reference: https://api.cloudflare.com/#worker-filters-update-filter +func (api *API) UpdateWorkerRoute(zoneID string, routeID string, route WorkerRoute) (WorkerRouteResponse, error) { + // Check whether a script name is defined in order to determine whether + // to use the single-script or multi-script endpoint. + pathComponent := "filters" + if route.Script != "" { + if api.AccountID == "" { + return WorkerRouteResponse{}, errors.New("account ID required for enterprise only request") + } + pathComponent = "routes" + } + uri := "/zones/" + zoneID + "/workers/" + pathComponent + "/" + routeID + res, err := api.makeRequest("PUT", uri, route) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r WorkerRouteResponse + err = json.Unmarshal(res, &r) + if err != nil { + return WorkerRouteResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/workers_kv.go b/vendor/github.com/cloudflare/cloudflare-go/workers_kv.go new file mode 100644 index 000000000..92197af08 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/workers_kv.go @@ -0,0 +1,192 @@ +package cloudflare + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + + "github.com/pkg/errors" +) + +// WorkersKVNamespaceRequest provides parameters for creating and updating storage namespaces +type WorkersKVNamespaceRequest struct { + Title string `json:"title"` +} + +// WorkersKVNamespaceResponse is the response received when creating storage namespaces +type WorkersKVNamespaceResponse struct { + Response + Result WorkersKVNamespace `json:"result"` +} + +// WorkersKVNamespace contains the unique identifier and title of a storage namespace +type WorkersKVNamespace struct { + ID string `json:"id"` + Title string `json:"title"` +} + +// ListWorkersKVNamespacesResponse contains a slice of storage namespaces associated with an +// account, pagination information, and an embedded response struct +type ListWorkersKVNamespacesResponse struct { + Response + Result []WorkersKVNamespace `json:"result"` + ResultInfo `json:"result_info"` +} + +// StorageKey is a key name used to identify a storage value +type StorageKey struct { + Name string `json:"name"` +} + +// ListStorageKeysResponse contains a slice of keys belonging to a storage namespace, +// pagination information, and an embedded response struct +type ListStorageKeysResponse struct { + Response + Result []StorageKey `json:"result"` + ResultInfo `json:"result_info"` +} + +// CreateWorkersKVNamespace creates a namespace under the given title. +// A 400 is returned if the account already owns a namespace with this title. +// A namespace must be explicitly deleted to be replaced. +// +// API reference: https://api.cloudflare.com/#workers-kv-namespace-create-a-namespace +func (api *API) CreateWorkersKVNamespace(ctx context.Context, req *WorkersKVNamespaceRequest) (WorkersKVNamespaceResponse, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces", api.AccountID) + res, err := api.makeRequestContext(ctx, http.MethodPost, uri, req) + if err != nil { + return WorkersKVNamespaceResponse{}, errors.Wrap(err, errMakeRequestError) + } + + result := WorkersKVNamespaceResponse{} + if err := json.Unmarshal(res, &result); err != nil { + return result, errors.Wrap(err, errUnmarshalError) + } + + return result, err +} + +// ListWorkersKVNamespaces lists storage namespaces +// +// API reference: https://api.cloudflare.com/#workers-kv-namespace-list-namespaces +func (api *API) ListWorkersKVNamespaces(ctx context.Context) (ListWorkersKVNamespacesResponse, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces", api.AccountID) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return ListWorkersKVNamespacesResponse{}, errors.Wrap(err, errMakeRequestError) + } + + result := ListWorkersKVNamespacesResponse{} + if err := json.Unmarshal(res, &result); err != nil { + return result, errors.Wrap(err, errUnmarshalError) + } + + return result, err +} + +// DeleteWorkersKVNamespace deletes the namespace corresponding to the given ID +// +// API reference: https://api.cloudflare.com/#workers-kv-namespace-remove-a-namespace +func (api *API) DeleteWorkersKVNamespace(ctx context.Context, namespaceID string) (Response, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s", api.AccountID, namespaceID) + res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) + if err != nil { + return Response{}, errors.Wrap(err, errMakeRequestError) + } + + result := Response{} + if err := json.Unmarshal(res, &result); err != nil { + return result, errors.Wrap(err, errUnmarshalError) + } + + return result, err +} + +// UpdateWorkersKVNamespace modifies a namespace's title +// +// API reference: https://api.cloudflare.com/#workers-kv-namespace-rename-a-namespace +func (api *API) UpdateWorkersKVNamespace(ctx context.Context, namespaceID string, req *WorkersKVNamespaceRequest) (Response, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s", api.AccountID, namespaceID) + res, err := api.makeRequestContext(ctx, http.MethodPut, uri, req) + if err != nil { + return Response{}, errors.Wrap(err, errMakeRequestError) + } + + result := Response{} + if err := json.Unmarshal(res, &result); err != nil { + return result, errors.Wrap(err, errUnmarshalError) + } + + return result, err +} + +// WriteWorkersKV writes a value identified by a key. +// +// API reference: https://api.cloudflare.com/#workers-kv-namespace-write-key-value-pair +func (api *API) WriteWorkersKV(ctx context.Context, namespaceID, key string, value []byte) (Response, error) { + key = url.PathEscape(key) + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", api.AccountID, namespaceID, key) + res, err := api.makeRequestWithAuthTypeAndHeaders( + ctx, http.MethodPut, uri, value, api.authType, http.Header{"Content-Type": []string{"application/octet-stream"}}, + ) + if err != nil { + return Response{}, errors.Wrap(err, errMakeRequestError) + } + + result := Response{} + if err := json.Unmarshal(res, &result); err != nil { + return result, errors.Wrap(err, errUnmarshalError) + } + + return result, err +} + +// ReadWorkersKV returns the value associated with the given key in the given namespace +// +// API reference: https://api.cloudflare.com/#workers-kv-namespace-read-key-value-pair +func (api API) ReadWorkersKV(ctx context.Context, namespaceID, key string) ([]byte, error) { + key = url.PathEscape(key) + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", api.AccountID, namespaceID, key) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + return res, nil +} + +// DeleteWorkersKV deletes a key and value for a provided storage namespace +// +// API reference: https://api.cloudflare.com/#workers-kv-namespace-delete-key-value-pair +func (api API) DeleteWorkersKV(ctx context.Context, namespaceID, key string) (Response, error) { + key = url.PathEscape(key) + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/values/%s", api.AccountID, namespaceID, key) + res, err := api.makeRequestContext(ctx, http.MethodDelete, uri, nil) + if err != nil { + return Response{}, errors.Wrap(err, errMakeRequestError) + } + + result := Response{} + if err := json.Unmarshal(res, &result); err != nil { + return result, errors.Wrap(err, errUnmarshalError) + } + return result, err +} + +// ListWorkersKVs lists a namespace's keys +// +// API Reference: https://api.cloudflare.com/#workers-kv-namespace-list-a-namespace-s-keys +func (api API) ListWorkersKVs(ctx context.Context, namespaceID string) (ListStorageKeysResponse, error) { + uri := fmt.Sprintf("/accounts/%s/storage/kv/namespaces/%s/keys", api.AccountID, namespaceID) + res, err := api.makeRequestContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return ListStorageKeysResponse{}, errors.Wrap(err, errMakeRequestError) + } + + result := ListStorageKeysResponse{} + if err := json.Unmarshal(res, &result); err != nil { + return result, errors.Wrap(err, errUnmarshalError) + } + return result, err +} diff --git a/vendor/github.com/cloudflare/cloudflare-go/zone.go b/vendor/github.com/cloudflare/cloudflare-go/zone.go new file mode 100644 index 000000000..951ca23d3 --- /dev/null +++ b/vendor/github.com/cloudflare/cloudflare-go/zone.go @@ -0,0 +1,690 @@ +package cloudflare + +import ( + "context" + "encoding/json" + "fmt" + "net/url" + "sync" + "time" + + "github.com/pkg/errors" +) + +// Owner describes the resource owner. +type Owner struct { + ID string `json:"id"` + Email string `json:"email"` + Name string `json:"name"` + OwnerType string `json:"type"` +} + +// Zone describes a Cloudflare zone. +type Zone struct { + ID string `json:"id"` + Name string `json:"name"` + // DevMode contains the time in seconds until development expires (if + // positive) or since it expired (if negative). It will be 0 if never used. + DevMode int `json:"development_mode"` + OriginalNS []string `json:"original_name_servers"` + OriginalRegistrar string `json:"original_registrar"` + OriginalDNSHost string `json:"original_dnshost"` + CreatedOn time.Time `json:"created_on"` + ModifiedOn time.Time `json:"modified_on"` + NameServers []string `json:"name_servers"` + Owner Owner `json:"owner"` + Permissions []string `json:"permissions"` + Plan ZonePlan `json:"plan"` + PlanPending ZonePlan `json:"plan_pending,omitempty"` + Status string `json:"status"` + Paused bool `json:"paused"` + Type string `json:"type"` + Host struct { + Name string + Website string + } `json:"host"` + VanityNS []string `json:"vanity_name_servers"` + Betas []string `json:"betas"` + DeactReason string `json:"deactivation_reason"` + Meta ZoneMeta `json:"meta"` + Account Account `json:"account"` +} + +// ZoneMeta describes metadata about a zone. +type ZoneMeta struct { + // custom_certificate_quota is broken - sometimes it's a string, sometimes a number! + // CustCertQuota int `json:"custom_certificate_quota"` + PageRuleQuota int `json:"page_rule_quota"` + WildcardProxiable bool `json:"wildcard_proxiable"` + PhishingDetected bool `json:"phishing_detected"` +} + +// ZonePlan contains the plan information for a zone. +type ZonePlan struct { + ZonePlanCommon + IsSubscribed bool `json:"is_subscribed"` + CanSubscribe bool `json:"can_subscribe"` + LegacyID string `json:"legacy_id"` + LegacyDiscount bool `json:"legacy_discount"` + ExternallyManaged bool `json:"externally_managed"` +} + +// ZoneRatePlan contains the plan information for a zone. +type ZoneRatePlan struct { + ZonePlanCommon + Components []zoneRatePlanComponents `json:"components,omitempty"` +} + +// ZonePlanCommon contains fields used by various Plan endpoints +type ZonePlanCommon struct { + ID string `json:"id"` + Name string `json:"name,omitempty"` + Price int `json:"price,omitempty"` + Currency string `json:"currency,omitempty"` + Frequency string `json:"frequency,omitempty"` +} + +type zoneRatePlanComponents struct { + Name string `json:"name"` + Default int `json:"Default"` + UnitPrice int `json:"unit_price"` +} + +// ZoneID contains only the zone ID. +type ZoneID struct { + ID string `json:"id"` +} + +// ZoneResponse represents the response from the Zone endpoint containing a single zone. +type ZoneResponse struct { + Response + Result Zone `json:"result"` +} + +// ZonesResponse represents the response from the Zone endpoint containing an array of zones. +type ZonesResponse struct { + Response + Result []Zone `json:"result"` + ResultInfo `json:"result_info"` +} + +// ZoneIDResponse represents the response from the Zone endpoint, containing only a zone ID. +type ZoneIDResponse struct { + Response + Result ZoneID `json:"result"` +} + +// AvailableZoneRatePlansResponse represents the response from the Available Rate Plans endpoint. +type AvailableZoneRatePlansResponse struct { + Response + Result []ZoneRatePlan `json:"result"` + ResultInfo `json:"result_info"` +} + +// AvailableZonePlansResponse represents the response from the Available Plans endpoint. +type AvailableZonePlansResponse struct { + Response + Result []ZonePlan `json:"result"` + ResultInfo +} + +// ZoneRatePlanResponse represents the response from the Plan Details endpoint. +type ZoneRatePlanResponse struct { + Response + Result ZoneRatePlan `json:"result"` +} + +// ZoneSetting contains settings for a zone. +type ZoneSetting struct { + ID string `json:"id"` + Editable bool `json:"editable"` + ModifiedOn string `json:"modified_on"` + Value interface{} `json:"value"` + TimeRemaining int `json:"time_remaining"` +} + +// ZoneSettingResponse represents the response from the Zone Setting endpoint. +type ZoneSettingResponse struct { + Response + Result []ZoneSetting `json:"result"` +} + +// ZoneSSLSetting contains ssl setting for a zone. +type ZoneSSLSetting struct { + ID string `json:"id"` + Editable bool `json:"editable"` + ModifiedOn string `json:"modified_on"` + Value string `json:"value"` + CertificateStatus string `json:"certificate_status"` +} + +// ZoneSSLSettingResponse represents the response from the Zone SSL Setting +// endpoint. +type ZoneSSLSettingResponse struct { + Response + Result ZoneSSLSetting `json:"result"` +} + +// ZoneAnalyticsData contains totals and timeseries analytics data for a zone. +type ZoneAnalyticsData struct { + Totals ZoneAnalytics `json:"totals"` + Timeseries []ZoneAnalytics `json:"timeseries"` +} + +// zoneAnalyticsDataResponse represents the response from the Zone Analytics Dashboard endpoint. +type zoneAnalyticsDataResponse struct { + Response + Result ZoneAnalyticsData `json:"result"` +} + +// ZoneAnalyticsColocation contains analytics data by datacenter. +type ZoneAnalyticsColocation struct { + ColocationID string `json:"colo_id"` + Timeseries []ZoneAnalytics `json:"timeseries"` +} + +// zoneAnalyticsColocationResponse represents the response from the Zone Analytics By Co-location endpoint. +type zoneAnalyticsColocationResponse struct { + Response + Result []ZoneAnalyticsColocation `json:"result"` +} + +// ZoneAnalytics contains analytics data for a zone. +type ZoneAnalytics struct { + Since time.Time `json:"since"` + Until time.Time `json:"until"` + Requests struct { + All int `json:"all"` + Cached int `json:"cached"` + Uncached int `json:"uncached"` + ContentType map[string]int `json:"content_type"` + Country map[string]int `json:"country"` + SSL struct { + Encrypted int `json:"encrypted"` + Unencrypted int `json:"unencrypted"` + } `json:"ssl"` + HTTPStatus map[string]int `json:"http_status"` + } `json:"requests"` + Bandwidth struct { + All int `json:"all"` + Cached int `json:"cached"` + Uncached int `json:"uncached"` + ContentType map[string]int `json:"content_type"` + Country map[string]int `json:"country"` + SSL struct { + Encrypted int `json:"encrypted"` + Unencrypted int `json:"unencrypted"` + } `json:"ssl"` + } `json:"bandwidth"` + Threats struct { + All int `json:"all"` + Country map[string]int `json:"country"` + Type map[string]int `json:"type"` + } `json:"threats"` + Pageviews struct { + All int `json:"all"` + SearchEngines map[string]int `json:"search_engines"` + } `json:"pageviews"` + Uniques struct { + All int `json:"all"` + } +} + +// ZoneAnalyticsOptions represents the optional parameters in Zone Analytics +// endpoint requests. +type ZoneAnalyticsOptions struct { + Since *time.Time + Until *time.Time + Continuous *bool +} + +// PurgeCacheRequest represents the request format made to the purge endpoint. +type PurgeCacheRequest struct { + Everything bool `json:"purge_everything,omitempty"` + // Purge by filepath (exact match). Limit of 30 + Files []string `json:"files,omitempty"` + // Purge by Tag (Enterprise only): + // https://support.cloudflare.com/hc/en-us/articles/206596608-How-to-Purge-Cache-Using-Cache-Tags-Enterprise-only- + Tags []string `json:"tags,omitempty"` + // Purge by hostname - e.g. "assets.example.com" + Hosts []string `json:"hosts,omitempty"` +} + +// PurgeCacheResponse represents the response from the purge endpoint. +type PurgeCacheResponse struct { + Response + Result struct { + ID string `json:"id"` + } `json:"result"` +} + +// newZone describes a new zone. +type newZone struct { + Name string `json:"name"` + JumpStart bool `json:"jump_start"` + Type string `json:"type"` + // We use a pointer to get a nil type when the field is empty. + // This allows us to completely omit this with json.Marshal(). + Account *Account `json:"organization,omitempty"` +} + +// CreateZone creates a zone on an account. +// +// Setting jumpstart to true will attempt to automatically scan for existing +// DNS records. Setting this to false will create the zone with no DNS records. +// +// If account is non-empty, it must have at least the ID field populated. +// This will add the new zone to the specified multi-user account. +// +// API reference: https://api.cloudflare.com/#zone-create-a-zone +func (api *API) CreateZone(name string, jumpstart bool, account Account, zoneType string) (Zone, error) { + var newzone newZone + newzone.Name = name + newzone.JumpStart = jumpstart + if account.ID != "" { + newzone.Account = &account + } + + if zoneType == "partial" { + newzone.Type = "partial" + } else { + newzone.Type = "full" + } + + res, err := api.makeRequest("POST", "/zones", newzone) + if err != nil { + return Zone{}, errors.Wrap(err, errMakeRequestError) + } + + var r ZoneResponse + err = json.Unmarshal(res, &r) + if err != nil { + return Zone{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ZoneActivationCheck initiates another zone activation check for newly-created zones. +// +// API reference: https://api.cloudflare.com/#zone-initiate-another-zone-activation-check +func (api *API) ZoneActivationCheck(zoneID string) (Response, error) { + res, err := api.makeRequest("PUT", "/zones/"+zoneID+"/activation_check", nil) + if err != nil { + return Response{}, errors.Wrap(err, errMakeRequestError) + } + var r Response + err = json.Unmarshal(res, &r) + if err != nil { + return Response{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// ListZones lists zones on an account. Optionally takes a list of zone names +// to filter against. +// +// API reference: https://api.cloudflare.com/#zone-list-zones +func (api *API) ListZones(z ...string) ([]Zone, error) { + v := url.Values{} + var res []byte + var r ZonesResponse + var zones []Zone + var err error + if len(z) > 0 { + for _, zone := range z { + v.Set("name", zone) + res, err = api.makeRequest("GET", "/zones?"+v.Encode(), nil) + if err != nil { + return []Zone{}, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return []Zone{}, errors.Wrap(err, errUnmarshalError) + } + if !r.Success { + // TODO: Provide an actual error message instead of always returning nil + return []Zone{}, err + } + for zi := range r.Result { + zones = append(zones, r.Result[zi]) + } + } + } else { + res, err = api.makeRequest("GET", "/zones?per_page=50", nil) + if err != nil { + return []Zone{}, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return []Zone{}, errors.Wrap(err, errUnmarshalError) + } + + totalPageCount := r.TotalPages + var wg sync.WaitGroup + wg.Add(totalPageCount) + errc := make(chan error) + + for i := 1; i <= totalPageCount; i++ { + go func(pageNumber int) error { + res, err = api.makeRequest("GET", fmt.Sprintf("/zones?per_page=50&page=%d", pageNumber), nil) + if err != nil { + errc <- err + } + + err = json.Unmarshal(res, &r) + if err != nil { + errc <- err + } + + for _, zone := range r.Result { + zones = append(zones, zone) + } + + select { + case err := <-errc: + return err + default: + wg.Done() + } + + return nil + }(i) + } + + wg.Wait() + } + + return zones, nil +} + +// ListZonesContext lists zones on an account. Optionally takes a list of ReqOptions. +func (api *API) ListZonesContext(ctx context.Context, opts ...ReqOption) (r ZonesResponse, err error) { + var res []byte + opt := reqOption{ + params: url.Values{}, + } + for _, of := range opts { + of(&opt) + } + + res, err = api.makeRequestContext(ctx, "GET", "/zones?"+opt.params.Encode(), nil) + if err != nil { + return ZonesResponse{}, errors.Wrap(err, errMakeRequestError) + } + err = json.Unmarshal(res, &r) + if err != nil { + return ZonesResponse{}, errors.Wrap(err, errUnmarshalError) + } + + return r, nil +} + +// ZoneDetails fetches information about a zone. +// +// API reference: https://api.cloudflare.com/#zone-zone-details +func (api *API) ZoneDetails(zoneID string) (Zone, error) { + res, err := api.makeRequest("GET", "/zones/"+zoneID, nil) + if err != nil { + return Zone{}, errors.Wrap(err, errMakeRequestError) + } + var r ZoneResponse + err = json.Unmarshal(res, &r) + if err != nil { + return Zone{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ZoneOptions is a subset of Zone, for editable options. +type ZoneOptions struct { + Paused *bool `json:"paused,omitempty"` + VanityNS []string `json:"vanity_name_servers,omitempty"` + Plan *ZonePlan `json:"plan,omitempty"` +} + +// ZoneSetPaused pauses Cloudflare service for the entire zone, sending all +// traffic direct to the origin. +func (api *API) ZoneSetPaused(zoneID string, paused bool) (Zone, error) { + zoneopts := ZoneOptions{Paused: &paused} + zone, err := api.EditZone(zoneID, zoneopts) + if err != nil { + return Zone{}, err + } + + return zone, nil +} + +// ZoneSetVanityNS sets custom nameservers for the zone. +// These names must be within the same zone. +func (api *API) ZoneSetVanityNS(zoneID string, ns []string) (Zone, error) { + zoneopts := ZoneOptions{VanityNS: ns} + zone, err := api.EditZone(zoneID, zoneopts) + if err != nil { + return Zone{}, err + } + + return zone, nil +} + +// ZoneSetPlan changes the zone plan. +func (api *API) ZoneSetPlan(zoneID string, plan ZonePlan) (Zone, error) { + zoneopts := ZoneOptions{Plan: &plan} + zone, err := api.EditZone(zoneID, zoneopts) + if err != nil { + return Zone{}, err + } + + return zone, nil +} + +// EditZone edits the given zone. +// +// This is usually called by ZoneSetPaused, ZoneSetVanityNS or ZoneSetPlan. +// +// API reference: https://api.cloudflare.com/#zone-edit-zone-properties +func (api *API) EditZone(zoneID string, zoneOpts ZoneOptions) (Zone, error) { + res, err := api.makeRequest("PATCH", "/zones/"+zoneID, zoneOpts) + if err != nil { + return Zone{}, errors.Wrap(err, errMakeRequestError) + } + var r ZoneResponse + err = json.Unmarshal(res, &r) + if err != nil { + return Zone{}, errors.Wrap(err, errUnmarshalError) + } + + return r.Result, nil +} + +// PurgeEverything purges the cache for the given zone. +// +// Note: this will substantially increase load on the origin server for that +// zone if there is a high cached vs. uncached request ratio. +// +// API reference: https://api.cloudflare.com/#zone-purge-all-files +func (api *API) PurgeEverything(zoneID string) (PurgeCacheResponse, error) { + uri := "/zones/" + zoneID + "/purge_cache" + res, err := api.makeRequest("POST", uri, PurgeCacheRequest{true, nil, nil, nil}) + if err != nil { + return PurgeCacheResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r PurgeCacheResponse + err = json.Unmarshal(res, &r) + if err != nil { + return PurgeCacheResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// PurgeCache purges the cache using the given PurgeCacheRequest (zone/url/tag). +// +// API reference: https://api.cloudflare.com/#zone-purge-individual-files-by-url-and-cache-tags +func (api *API) PurgeCache(zoneID string, pcr PurgeCacheRequest) (PurgeCacheResponse, error) { + uri := "/zones/" + zoneID + "/purge_cache" + res, err := api.makeRequest("POST", uri, pcr) + if err != nil { + return PurgeCacheResponse{}, errors.Wrap(err, errMakeRequestError) + } + var r PurgeCacheResponse + err = json.Unmarshal(res, &r) + if err != nil { + return PurgeCacheResponse{}, errors.Wrap(err, errUnmarshalError) + } + return r, nil +} + +// DeleteZone deletes the given zone. +// +// API reference: https://api.cloudflare.com/#zone-delete-a-zone +func (api *API) DeleteZone(zoneID string) (ZoneID, error) { + res, err := api.makeRequest("DELETE", "/zones/"+zoneID, nil) + if err != nil { + return ZoneID{}, errors.Wrap(err, errMakeRequestError) + } + var r ZoneIDResponse + err = json.Unmarshal(res, &r) + if err != nil { + return ZoneID{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// AvailableZoneRatePlans returns information about all plans available to the specified zone. +// +// API reference: https://api.cloudflare.com/#zone-plan-available-plans +func (api *API) AvailableZoneRatePlans(zoneID string) ([]ZoneRatePlan, error) { + uri := "/zones/" + zoneID + "/available_rate_plans" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []ZoneRatePlan{}, errors.Wrap(err, errMakeRequestError) + } + var r AvailableZoneRatePlansResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []ZoneRatePlan{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// AvailableZonePlans returns information about all plans available to the specified zone. +// +// API reference: https://api.cloudflare.com/#zone-rate-plan-list-available-plans +func (api *API) AvailableZonePlans(zoneID string) ([]ZonePlan, error) { + uri := "/zones/" + zoneID + "/available_plans" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return []ZonePlan{}, errors.Wrap(err, errMakeRequestError) + } + var r AvailableZonePlansResponse + err = json.Unmarshal(res, &r) + if err != nil { + return []ZonePlan{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// encode encodes non-nil fields into URL encoded form. +func (o ZoneAnalyticsOptions) encode() string { + v := url.Values{} + if o.Since != nil { + v.Set("since", (*o.Since).Format(time.RFC3339)) + } + if o.Until != nil { + v.Set("until", (*o.Until).Format(time.RFC3339)) + } + if o.Continuous != nil { + v.Set("continuous", fmt.Sprintf("%t", *o.Continuous)) + } + return v.Encode() +} + +// ZoneAnalyticsDashboard returns zone analytics information. +// +// API reference: https://api.cloudflare.com/#zone-analytics-dashboard +func (api *API) ZoneAnalyticsDashboard(zoneID string, options ZoneAnalyticsOptions) (ZoneAnalyticsData, error) { + uri := "/zones/" + zoneID + "/analytics/dashboard" + "?" + options.encode() + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return ZoneAnalyticsData{}, errors.Wrap(err, errMakeRequestError) + } + var r zoneAnalyticsDataResponse + err = json.Unmarshal(res, &r) + if err != nil { + return ZoneAnalyticsData{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ZoneAnalyticsByColocation returns zone analytics information by datacenter. +// +// API reference: https://api.cloudflare.com/#zone-analytics-analytics-by-co-locations +func (api *API) ZoneAnalyticsByColocation(zoneID string, options ZoneAnalyticsOptions) ([]ZoneAnalyticsColocation, error) { + uri := "/zones/" + zoneID + "/analytics/colos" + "?" + options.encode() + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + var r zoneAnalyticsColocationResponse + err = json.Unmarshal(res, &r) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} + +// ZoneSettings returns all of the settings for a given zone. +// +// API reference: https://api.cloudflare.com/#zone-settings-get-all-zone-settings +func (api *API) ZoneSettings(zoneID string) (*ZoneSettingResponse, error) { + uri := "/zones/" + zoneID + "/settings" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &ZoneSettingResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// UpdateZoneSettings updates the settings for a given zone. +// +// API reference: https://api.cloudflare.com/#zone-settings-edit-zone-settings-info +func (api *API) UpdateZoneSettings(zoneID string, settings []ZoneSetting) (*ZoneSettingResponse, error) { + uri := "/zones/" + zoneID + "/settings" + res, err := api.makeRequest("PATCH", uri, struct { + Items []ZoneSetting `json:"items"` + }{settings}) + if err != nil { + return nil, errors.Wrap(err, errMakeRequestError) + } + + response := &ZoneSettingResponse{} + err = json.Unmarshal(res, &response) + if err != nil { + return nil, errors.Wrap(err, errUnmarshalError) + } + + return response, nil +} + +// ZoneSSLSettings returns information about SSL setting to the specified zone. +// +// API reference: https://api.cloudflare.com/#zone-settings-get-ssl-setting +func (api *API) ZoneSSLSettings(zoneID string) (ZoneSSLSetting, error) { + uri := "/zones/" + zoneID + "/settings/ssl" + res, err := api.makeRequest("GET", uri, nil) + if err != nil { + return ZoneSSLSetting{}, errors.Wrap(err, errMakeRequestError) + } + var r ZoneSSLSettingResponse + err = json.Unmarshal(res, &r) + if err != nil { + return ZoneSSLSetting{}, errors.Wrap(err, errUnmarshalError) + } + return r.Result, nil +} diff --git a/vendor/github.com/cpu/goacmedns/.errcheck_exclude b/vendor/github.com/cpu/goacmedns/.errcheck_exclude new file mode 100644 index 000000000..95d2005f5 --- /dev/null +++ b/vendor/github.com/cpu/goacmedns/.errcheck_exclude @@ -0,0 +1 @@ +fmt.Fprintf diff --git a/vendor/github.com/cpu/goacmedns/.gitignore b/vendor/github.com/cpu/goacmedns/.gitignore new file mode 100644 index 000000000..f1c181ec9 --- /dev/null +++ b/vendor/github.com/cpu/goacmedns/.gitignore @@ -0,0 +1,12 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out diff --git a/vendor/github.com/cpu/goacmedns/.travis.yml b/vendor/github.com/cpu/goacmedns/.travis.yml new file mode 100644 index 000000000..bc1970f02 --- /dev/null +++ b/vendor/github.com/cpu/goacmedns/.travis.yml @@ -0,0 +1,18 @@ +language: go + +sudo: false + +go: + - "1.10.3" + +install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - go get github.com/kisielk/errcheck + - go get ./... + +script: + - go vet ./... + - errcheck -exclude .errcheck_exclude ./... + - go test -v -race -covermode=atomic -coverprofile=coverage.out ./... + - goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN diff --git a/vendor/github.com/cpu/goacmedns/LICENSE b/vendor/github.com/cpu/goacmedns/LICENSE new file mode 100644 index 000000000..3215897de --- /dev/null +++ b/vendor/github.com/cpu/goacmedns/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Daniel McCarney + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/cpu/goacmedns/README.md b/vendor/github.com/cpu/goacmedns/README.md new file mode 100644 index 000000000..ea385aa98 --- /dev/null +++ b/vendor/github.com/cpu/goacmedns/README.md @@ -0,0 +1,93 @@ +# goacmedns + +A Go library to handle [acme-dns](https://github.com/joohoi/acme-dns) client +communication and persistent account storage. + +[![Build Status](https://travis-ci.org/cpu/goacmedns.svg?branch=master)](https://travis-ci.org/cpu/goacmedns) +[![Coverage Status](https://coveralls.io/repos/github/cpu/goacmedns/badge.svg?branch=master)](https://coveralls.io/github/cpu/goacmedns?branch=master) +[![Go Report Card](https://goreportcard.com/badge/github.com/cpu/goacmedns)](https://goreportcard.com/report/github.com/cpu/goacmedns) + +You may also be interested in a Python equivalent, +[pyacmedns](https://github.com/joohoi/pyacmedns/). + +# Installation + +Once you have [installed Go](https://golang.org/doc/install) 1.10+ you can +install `goacmedns` with `go get`: + + go get github.com/cpu/goacmedns/... + +# Usage + +The following is a short example of using the library to update a TXT record +served by an `acme-dns` instance. + +```go +package main + +import ( + "log" + + "github.com/cpu/goacmedns" +) + +const ( + domain = "your.example.org" +) + +var ( + whitelistedNetworks = []string{"192.168.11.0/24", "[::1]/128"} +) + +func main() { + // Initialize the client. Point it towards your acme-dns instance. + client := goacmedns.NewClient("https://auth.acme-dns.io") + // Initialize the storage. If the file does not exist, it will be + // automatically created. + storage := goacmedns.NewFileStorage("/tmp/storage.json", 0600) + + // Check if credentials were previously saved for your domain + account, err := storage.Fetch(domain) + if err != nil && err != goacmedns.ErrDomainNotFound { + log.Fatal(err) + } else if err == goacmedns.ErrDomainNotFound { + // The account did not exist. Let's create a new one + // The whitelisted networks parameter is optional and can be nil + newAcct, err := client.RegisterAccount(whitelistedNetworks) + if err != nil { + log.Fatal(err) + } + // Save it + err = storage.Put(domain, newAcct) + if err != nil { + log.Fatalf("Failed to put account in storage: %v", err) + } + err = storage.Save() + if err != nil { + log.Fatalf("Failed to save storage: %v", err) + } + account = newAcct + } + + // Update the acme-dns TXT record + err = client.UpdateTXTRecord(account, "___validation_token_recieved_from_the_ca___") + if err != nil { + log.Fatal(err) + } +} +``` + +# Pre-Registration + +When using `goacmedns` with an ACME client hook it may be desirable to do the +initial ACME-DNS account creation and CNAME delegation ahead of time The +`goacmedns-register` command line utility provides an easy way to do this: + + go install github.com/cpu/goacmedns/... + goacmedns-register -api http://10.0.0.1:4443 -domain example.com -allowFrom 192.168.100.1/24,1.2.3.4/32,2002:c0a8:2a00::0/40 -storage /tmp/example.storage.json + +This will register an account for `example.com` that is only usable from the +specified CIDR `-allowFrom` networks with the ACME-DNS server at +`http://10.0.0.1:4443`, saving the account details in +`/tmp/example.storage.json` and printing the required CNAME record for the +`example.com` DNS zone to stdout. diff --git a/vendor/github.com/cpu/goacmedns/account.go b/vendor/github.com/cpu/goacmedns/account.go new file mode 100644 index 000000000..9a1d9c81a --- /dev/null +++ b/vendor/github.com/cpu/goacmedns/account.go @@ -0,0 +1,11 @@ +package goacmedns + +// Account is a struct that holds the registration response from an ACME-DNS +// server. It represents an API username/key that can be used to update TXT +// records for the account's subdomain. +type Account struct { + FullDomain string + SubDomain string + Username string + Password string +} diff --git a/vendor/github.com/cpu/goacmedns/client.go b/vendor/github.com/cpu/goacmedns/client.go new file mode 100644 index 000000000..8be70306e --- /dev/null +++ b/vendor/github.com/cpu/goacmedns/client.go @@ -0,0 +1,191 @@ +package goacmedns + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net" + "net/http" + "runtime" + "time" +) + +const ( + // ua is a custom user-agent identifier + ua = "goacmedns" +) + +// userAgent returns a string that can be used as a HTTP request `User-Agent` +// header. It includes the `ua` string alongside the OS and architecture of the +// system. +func userAgent() string { + return fmt.Sprintf("%s (%s; %s)", ua, runtime.GOOS, runtime.GOARCH) +} + +var ( + // defaultTimeout is used for the httpClient Timeout settings + defaultTimeout = 30 * time.Second + // httpClient is a `http.Client` that is customized with the `defaultTimeout` + httpClient = http.Client{ + Transport: &http.Transport{ + Dial: (&net.Dialer{ + Timeout: defaultTimeout, + KeepAlive: defaultTimeout, + }).Dial, + TLSHandshakeTimeout: defaultTimeout, + ResponseHeaderTimeout: defaultTimeout, + ExpectContinueTimeout: 1 * time.Second, + }, + } +) + +// postAPI makes an HTTP POST request to the given URL, sending the given body +// and attaching the requested custom headers to the request. If there is no +// error the HTTP response body and HTTP response object are returned, otherwise +// an error is returned.. All POST requests include a `User-Agent` header +// populated with the `userAgent` function and a `Content-Type` header of +// `application/json`. +func postAPI(url string, body []byte, headers map[string]string) ([]byte, *http.Response, error) { + req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(body)) + if err != nil { + fmt.Printf("Failed to make req: %s\n", err.Error()) + return nil, nil, err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("User-Agent", userAgent()) + for h, v := range headers { + req.Header.Set(h, v) + } + + resp, err := httpClient.Do(req) + if err != nil { + fmt.Printf("Failed to do req: %s\n", err.Error()) + return nil, resp, err + } + defer func() { _ = resp.Body.Close() }() + + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Printf("Failed to read body: %s\n", err.Error()) + return nil, resp, err + } + return respBody, resp, nil +} + +// ClientError represents an error from the ACME-DNS server. It holds +// a `Message` describing the operation the client was doing, a `HTTPStatus` +// code returned by the server, and the `Body` of the HTTP Response from the +// server. +type ClientError struct { + // Message is a string describing the client operation that failed + Message string + // HTTPStatus is the HTTP status code the ACME DNS server returned + HTTPStatus int + // Body is the response body the ACME DNS server returned + Body []byte +} + +// Error collects all of the ClientError fields into a single string +func (e ClientError) Error() string { + return fmt.Sprintf("%s : status code %d response: %s", + e.Message, e.HTTPStatus, string(e.Body)) +} + +// newClientError creates a ClientError instance populated with the given +// arguments +func newClientError(msg string, respCode int, respBody []byte) ClientError { + return ClientError{ + Message: msg, + HTTPStatus: respCode, + Body: respBody, + } +} + +// Client is a struct that can be used to interact with an ACME DNS server to +// register accounts and update TXT records. +type Client struct { + // baseURL is the address of the ACME DNS server + baseURL string +} + +// NewClient returns a Client configured to interact with the ACME DNS server at +// the given URL. +func NewClient(url string) Client { + return Client{ + baseURL: url, + } +} + +// RegisterAccount creates an Account with the ACME DNS server. The optional +// `allowFrom` argument is used to constrain which CIDR ranges can use the +// created Account. +func (c Client) RegisterAccount(allowFrom []string) (Account, error) { + var body []byte + if len(allowFrom) > 0 { + req := struct { + AllowFrom []string + }{ + AllowFrom: allowFrom, + } + reqBody, err := json.Marshal(req) + if err != nil { + return Account{}, err + } + body = reqBody + } + + url := fmt.Sprintf("%s/register", c.baseURL) + respBody, resp, err := postAPI(url, body, nil) + if err != nil { + return Account{}, err + } + + if resp.StatusCode != http.StatusCreated { + return Account{}, newClientError( + "failed to register account", resp.StatusCode, respBody) + } + + var acct Account + err = json.Unmarshal(respBody, &acct) + if err != nil { + return Account{}, err + } + + return acct, nil +} + +// UpdateTXTRecord updates a TXT record with the ACME DNS server to the `value` +// provided using the `account` specified. +func (c Client) UpdateTXTRecord(account Account, value string) error { + update := struct { + SubDomain string + Txt string + }{ + SubDomain: account.SubDomain, + Txt: value, + } + updateBody, err := json.Marshal(update) + if err != nil { + fmt.Printf("Failed to marshal update: %s\n", update) + return err + } + + headers := map[string]string{ + "X-Api-User": account.Username, + "X-Api-Key": account.Password, + } + + url := fmt.Sprintf("%s/update", c.baseURL) + respBody, resp, err := postAPI(url, updateBody, headers) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + return newClientError( + "failed to update txt record", resp.StatusCode, respBody) + } + + return nil +} diff --git a/vendor/github.com/cpu/goacmedns/storage.go b/vendor/github.com/cpu/goacmedns/storage.go new file mode 100644 index 000000000..6e0186b0c --- /dev/null +++ b/vendor/github.com/cpu/goacmedns/storage.go @@ -0,0 +1,89 @@ +package goacmedns + +import ( + "encoding/json" + "errors" + "io/ioutil" + "os" +) + +// Storage is an interface describing the required functions for an ACME DNS +// Account storage mechanism. +type Storage interface { + // Save will persist the `Account` data that has been `Put` so far + Save() error + // Put will add an `Account` for the given domain to the storage. It may not + // be persisted until `Save` is called. + Put(string, Account) error + // Fetch will retrieve an `Account` for the given domain from the storage. If + // the provided domain does not have an `Account` saved in the storage + // `ErrDomainNotFound` will be returned + Fetch(string) (Account, error) +} + +var ( + // ErrDomainNotFound is returned from `Fetch` when the provided domain is not + // present in the storage. + ErrDomainNotFound = errors.New("requested domain is not present in storage") +) + +// fileStorage implements the `Storage` interface and persists `Accounts` to +// a JSON file on disk. +type fileStorage struct { + // path is the filepath that the `accounts` are persisted to when the `Save` + // function is called. + path string + // mode is the file mode used when the `path` JSON file must be created + mode os.FileMode + // accounts holds the `Account` data that has been `Put` into the storage + accounts map[string]Account +} + +// NewFileStorage returns a `Storage` implementation backed by JSON content +// saved into the provided `path` on disk. The file at `path` will be created if +// required. When creating a new file the provided `mode` is used to set the +// permissions. +func NewFileStorage(path string, mode os.FileMode) Storage { + fs := fileStorage{ + path: path, + mode: mode, + accounts: make(map[string]Account), + } + // Opportunistically try to load the account data. Return an empty account if + // any errors occur. + if jsonData, err := ioutil.ReadFile(path); err == nil { + if err := json.Unmarshal(jsonData, &fs.accounts); err != nil { + return fs + } + } + return fs +} + +// Save persists the `Account` data to the fileStorage's configured path. The +// file at that path will be created with the fileStorage's mode if required. +func (f fileStorage) Save() error { + if serialized, err := json.Marshal(f.accounts); err != nil { + return err + } else if err = ioutil.WriteFile(f.path, serialized, f.mode); err != nil { + return err + } + return nil +} + +// Put saves an `Account` for the given `Domain` into the in-memory accounts of +// the fileStorage instance. The `Account` data will not be written to disk +// until the `Save` function is called +func (f fileStorage) Put(domain string, acct Account) error { + f.accounts[domain] = acct + return nil +} + +// Fetch retrieves the `Account` object for the given `domain` from the +// fileStorage in-memory accounts. If the `domain` provided does not have an +// `Account` in the storage an `ErrDomainNotFound` error is returned. +func (f fileStorage) Fetch(domain string) (Account, error) { + if acct, exists := f.accounts[domain]; exists { + return acct, nil + } + return Account{}, ErrDomainNotFound +} diff --git a/vendor/github.com/decker502/dnspod-go/LICENSE b/vendor/github.com/decker502/dnspod-go/LICENSE new file mode 100644 index 000000000..c5c9a4e37 --- /dev/null +++ b/vendor/github.com/decker502/dnspod-go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 decker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/decker502/dnspod-go/README.md b/vendor/github.com/decker502/dnspod-go/README.md new file mode 100644 index 000000000..60866d825 --- /dev/null +++ b/vendor/github.com/decker502/dnspod-go/README.md @@ -0,0 +1,59 @@ +# dnspod-go + +A Go client for the [DNSPod API](https://www.dnspod.cn/docs/index.html). + +Borrowed from : [dnsimple](https://github.com/weppos/dnsimple-go/dnsimple) + +## Installation + +``` +$ go get github.com/decker502/dnspod-go +``` + + +## Getting Started + +This library is a Go client you can use to interact with the [DNSPod API](https://www.dnspod.cn/docs/index.html). Here are some examples. + + +```go +package main + +import ( + "fmt" + "log" + + "github.com/decker502/dnspod-go" +) + +func main() { + apiToken := "xxxxx" + + params := dnspod.CommonParams{LoginToken: apiToken, Format: "json"} + client := dnspod.NewClient(params) + + // Get a list of your domains + domains, _, _ := client.Domains.List() + for _, domain := range domains { + fmt.Printf("Domain: %s (id: %d)\n", domain.Name, domain.ID) + } + + // Get a list of your domains (with error management) + domains, _, error := client.Domains.List() + if error != nil { + log.Fatalln(error) + } + for _, domain := range domains { + fmt.Printf("Domain: %s (id: %d)\n", domain.Name, domain.ID) + } + + // Create a new Domain + newDomain := dnspod.Domain{Name: "example.com"} + domain, _, _ := client.Domains.Create(newDomain) + fmt.Printf("Domain: %s\n (id: %d)", domain.Name, domain.ID) +} + +``` +## License + +This is Free Software distributed under the MIT license. diff --git a/vendor/github.com/decker502/dnspod-go/dnspod.go b/vendor/github.com/decker502/dnspod-go/dnspod.go new file mode 100644 index 000000000..17e67488a --- /dev/null +++ b/vendor/github.com/decker502/dnspod-go/dnspod.go @@ -0,0 +1,233 @@ +// Package dnspod implements a client for the dnspod API. +// +// In order to use this package you will need a dnspod account and your API Token. +package dnspod + +import ( + // "bytes" + "encoding/json" + "fmt" + "io" + "net" + "net/http" + "net/url" + "strings" + "time" +) + +const ( + libraryVersion = "0.1" + baseURL = "https://dnsapi.cn/" + userAgent = "dnspod-go/" + libraryVersion + + apiVersion = "v1" + timeout = 5 + keepAlive = 30 +) + +// dnspod API docs: https://www.dnspod.cn/docs/info.html + +type CommonParams struct { + LoginToken string + Format string + Lang string + ErrorOnEmpty string + UserID string + Timeout int + KeepAlive int +} + +func newPayLoad(params CommonParams) url.Values { + p := url.Values{} + + if params.LoginToken != "" { + p.Set("login_token", params.LoginToken) + } + if params.Format != "" { + p.Set("format", params.Format) + } + if params.Lang != "" { + p.Set("lang", params.Lang) + } + if params.ErrorOnEmpty != "" { + p.Set("error_on_empty", params.ErrorOnEmpty) + } + if params.UserID != "" { + p.Set("user_id", params.UserID) + } + + return p +} + +type Status struct { + Code string `json:"code,omitempty"` + Message string `json:"message,omitempty"` + CreatedAt string `json:"created_at,omitempty"` +} + +type Client struct { + // HTTP client used to communicate with the API. + HttpClient *http.Client + + // CommonParams used communicating with the dnspod API. + CommonParams CommonParams + + // Base URL for API requests. + // Defaults to the public dnspod API, but can be set to a different endpoint (e.g. the sandbox). + // BaseURL should always be specified with a trailing slash. + BaseURL string + + // User agent used when communicating with the dnspod API. + UserAgent string + + // Services used for talking to different parts of the dnspod API. + Domains *DomainsService +} + +// NewClient returns a new dnspod API client. +func NewClient(CommonParams CommonParams) *Client { + var _timeout, _keepalive int + _timeout = timeout + _keepalive = keepAlive + + if CommonParams.Timeout != 0 { + _timeout = CommonParams.Timeout + } + if CommonParams.KeepAlive != 0 { + _keepalive = CommonParams.KeepAlive + } + + cli := http.Client{ + Transport: &http.Transport{ + Dial: (&net.Dialer{ + Timeout: time.Duration(_timeout) * time.Second, + KeepAlive: time.Duration(_keepalive) * time.Second, + }).Dial, + }, + } + + c := &Client{HttpClient: &cli, CommonParams: CommonParams, BaseURL: baseURL, UserAgent: userAgent} + c.Domains = &DomainsService{client: c} + return c + +} + +// NewRequest creates an API request. +// The path is expected to be a relative path and will be resolved +// according to the BaseURL of the Client. Paths should always be specified without a preceding slash. +func (client *Client) NewRequest(method, path string, payload url.Values) (*http.Request, error) { + url := client.BaseURL + fmt.Sprintf("%s", path) + + req, err := http.NewRequest(method, url, strings.NewReader(payload.Encode())) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add("Accept", "application/json") + req.Header.Add("User-Agent", client.UserAgent) + + return req, nil +} + +func (c *Client) get(path string, v interface{}) (*Response, error) { + return c.Do("GET", path, nil, v) +} + +func (c *Client) post(path string, payload url.Values, v interface{}) (*Response, error) { + return c.Do("POST", path, payload, v) +} + +func (c *Client) put(path string, payload url.Values, v interface{}) (*Response, error) { + return c.Do("PUT", path, payload, v) +} + +func (c *Client) delete(path string, payload url.Values) (*Response, error) { + return c.Do("DELETE", path, payload, nil) +} + +// Do sends an API request and returns the API response. +// The API response is JSON decoded and stored in the value pointed by v, +// or returned as an error if an API error has occurred. +// If v implements the io.Writer interface, the raw response body will be written to v, +// without attempting to decode it. +func (c *Client) Do(method, path string, payload url.Values, v interface{}) (*Response, error) { + req, err := c.NewRequest(method, path, payload) + if err != nil { + return nil, err + } + + res, err := c.HttpClient.Do(req) + if err != nil { + return nil, err + } + defer res.Body.Close() + response := &Response{Response: res} + err = CheckResponse(res) + if err != nil { + return response, err + } + if v != nil { + if w, ok := v.(io.Writer); ok { + io.Copy(w, res.Body) + } else { + err = json.NewDecoder(res.Body).Decode(v) + } + } + + return response, err +} + +// A Response represents an API response. +type Response struct { + *http.Response +} + +// An ErrorResponse represents an error caused by an API request. +type ErrorResponse struct { + Response *http.Response // HTTP response that caused this error + Message string `json:"message"` // human-readable message +} + +// Error implements the error interface. +func (r *ErrorResponse) Error() string { + return fmt.Sprintf("%v %v: %d %v", + r.Response.Request.Method, r.Response.Request.URL, + r.Response.StatusCode, r.Message) +} + +// CheckResponse checks the API response for errors, and returns them if present. +// A response is considered an error if the status code is different than 2xx. Specific requests +// may have additional requirements, but this is sufficient in most of the cases. +func CheckResponse(r *http.Response) error { + if code := r.StatusCode; 200 <= code && code <= 299 { + return nil + } + + errorResponse := &ErrorResponse{Response: r} + err := json.NewDecoder(r.Body).Decode(errorResponse) + if err != nil { + return err + } + + return errorResponse +} + +// Date custom type. +type Date struct { + time.Time +} + +// UnmarshalJSON handles the deserialization of the custom Date type. +func (d *Date) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("date should be a string, got %s", data) + } + t, err := time.Parse("2006-01-02", s) + if err != nil { + return fmt.Errorf("invalid date: %v", err) + } + d.Time = t + return nil +} diff --git a/vendor/github.com/decker502/dnspod-go/domain_records.go b/vendor/github.com/decker502/dnspod-go/domain_records.go new file mode 100644 index 000000000..dea4ad97c --- /dev/null +++ b/vendor/github.com/decker502/dnspod-go/domain_records.go @@ -0,0 +1,237 @@ +package dnspod + +import ( + "fmt" +) + +type Record struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Line string `json:"line,omitempty"` + LineID string `json:"line_id,omitempty"` + Type string `json:"type,omitempty"` + TTL string `json:"ttl,omitempty"` + Value string `json:"value,omitempty"` + MX string `json:"mx,omitempty"` + Enabled string `json:"enabled,omitempty"` + Status string `json:"status,omitempty"` + MonitorStatus string `json:"monitor_status,omitempty"` + Remark string `json:"remark,omitempty"` + UpdateOn string `json:"updated_on,omitempty"` + UseAQB string `json:"use_aqb,omitempty"` +} + +type recordsWrapper struct { + Status Status `json:"status"` + Info DomainInfo `json:"info"` + Records []Record `json:"records"` +} + +type recordWrapper struct { + Status Status `json:"status"` + Info DomainInfo `json:"info"` + Record Record `json:"record"` +} + +// recordAction generates the resource path for given record that belongs to a domain. +func recordAction(action string) string { + if len(action) > 0 { + return fmt.Sprintf("Record.%s", action) + } + return "Record.List" +} + +// List the domain records. +// +// dnspod API docs: https://www.dnspod.cn/docs/records.html#record-list +func (s *DomainsService) ListRecords(domainID string, recordName string) ([]Record, *Response, error) { + path := recordAction("List") + + payload := newPayLoad(s.client.CommonParams) + + payload.Add("domain_id", domainID) + + if recordName != "" { + payload.Add("sub_domain", recordName) + } + + wrappedRecords := recordsWrapper{} + + res, err := s.client.post(path, payload, &wrappedRecords) + if err != nil { + return []Record{}, res, err + } + + if wrappedRecords.Status.Code != "1" { + return wrappedRecords.Records, nil, fmt.Errorf("Could not get domains: %s", wrappedRecords.Status.Message) + } + + records := []Record{} + for _, record := range wrappedRecords.Records { + records = append(records, record) + } + + return records, res, nil +} + +// CreateRecord creates a domain record. +// +// dnspod API docs: https://www.dnspod.cn/docs/records.html#record-create +func (s *DomainsService) CreateRecord(domain string, recordAttributes Record) (Record, *Response, error) { + path := recordAction("Create") + + payload := newPayLoad(s.client.CommonParams) + + payload.Add("domain_id", domain) + + if recordAttributes.Name != "" { + payload.Add("sub_domain", recordAttributes.Name) + } + + if recordAttributes.Type != "" { + payload.Add("record_type", recordAttributes.Type) + } + + if recordAttributes.Line != "" { + payload.Add("record_line", recordAttributes.Line) + } + + if recordAttributes.LineID != "" { + payload.Add("record_line_id", recordAttributes.LineID) + } + + if recordAttributes.Value != "" { + payload.Add("value", recordAttributes.Value) + } + + if recordAttributes.MX != "" { + payload.Add("mx", recordAttributes.MX) + } + + if recordAttributes.TTL != "" { + payload.Add("ttl", recordAttributes.TTL) + } + + if recordAttributes.Status != "" { + payload.Add("status", recordAttributes.Status) + } + + returnedRecord := recordWrapper{} + + res, err := s.client.post(path, payload, &returnedRecord) + if err != nil { + return Record{}, res, err + } + + if returnedRecord.Status.Code != "1" { + return returnedRecord.Record, nil, fmt.Errorf("Could not get domains: %s", returnedRecord.Status.Message) + } + + return returnedRecord.Record, res, nil +} + +// GetRecord fetches the domain record. +// +// dnspod API docs: https://www.dnspod.cn/docs/records.html#record-info +func (s *DomainsService) GetRecord(domain string, recordID string) (Record, *Response, error) { + path := recordAction("Info") + + payload := newPayLoad(s.client.CommonParams) + + payload.Add("domain_id", domain) + payload.Add("record_id", recordID) + + returnedRecord := recordWrapper{} + + res, err := s.client.post(path, payload, &returnedRecord) + if err != nil { + return Record{}, res, err + } + + if returnedRecord.Status.Code != "1" { + return returnedRecord.Record, nil, fmt.Errorf("Could not get domains: %s", returnedRecord.Status.Message) + } + + return returnedRecord.Record, res, nil +} + +// UpdateRecord updates a domain record. +// +// dnspod API docs: https://www.dnspod.cn/docs/records.html#record-modify +func (s *DomainsService) UpdateRecord(domain string, recordID string, recordAttributes Record) (Record, *Response, error) { + path := recordAction("Modify") + + payload := newPayLoad(s.client.CommonParams) + + payload.Add("domain_id", domain) + + if recordAttributes.Name != "" { + payload.Add("sub_domain", recordAttributes.Name) + } + + if recordAttributes.Type != "" { + payload.Add("record_type", recordAttributes.Type) + } + + if recordAttributes.Line != "" { + payload.Add("record_line", recordAttributes.Line) + } + + if recordAttributes.LineID != "" { + payload.Add("record_line_id", recordAttributes.LineID) + } + + if recordAttributes.Value != "" { + payload.Add("value", recordAttributes.Value) + } + + if recordAttributes.MX != "" { + payload.Add("mx", recordAttributes.MX) + } + + if recordAttributes.TTL != "" { + payload.Add("ttl", recordAttributes.TTL) + } + + if recordAttributes.Status != "" { + payload.Add("status", recordAttributes.Status) + } + + returnedRecord := recordWrapper{} + + res, err := s.client.post(path, payload, &returnedRecord) + if err != nil { + return Record{}, res, err + } + + if returnedRecord.Status.Code != "1" { + return returnedRecord.Record, nil, fmt.Errorf("Could not get domains: %s", returnedRecord.Status.Message) + } + + return returnedRecord.Record, res, nil +} + +// DeleteRecord deletes a domain record. +// +// dnspod API docs: https://www.dnspod.cn/docs/records.html#record-remove +func (s *DomainsService) DeleteRecord(domain string, recordID string) (*Response, error) { + path := recordAction("Remove") + + payload := newPayLoad(s.client.CommonParams) + + payload.Add("domain_id", domain) + payload.Add("record_id", recordID) + + returnedRecord := recordWrapper{} + + res, err := s.client.post(path, payload, &returnedRecord) + if err != nil { + return res, err + } + + if returnedRecord.Status.Code != "1" { + return nil, fmt.Errorf("Could not get domains: %s", returnedRecord.Status.Message) + } + + return res, nil +} diff --git a/vendor/github.com/decker502/dnspod-go/domains.go b/vendor/github.com/decker502/dnspod-go/domains.go new file mode 100644 index 000000000..befd4bd25 --- /dev/null +++ b/vendor/github.com/decker502/dnspod-go/domains.go @@ -0,0 +1,162 @@ +package dnspod + +import ( + "encoding/json" + "fmt" + "strconv" + // "time" +) + +// DomainsService handles communication with the domain related +// methods of the dnspod API. +// +// dnspod API docs: https://www.dnspod.cn/docs/domains.html +type DomainsService struct { + client *Client +} + +type DomainInfo struct { + DomainTotal int `json:"domain_total,omitempty"` + AllTotal int `json:"all_total,omitempty"` + MineTotal int `json:"mine_total,omitempty"` + ShareTotal string `json:"share_total,omitempty"` + VipTotal int `json:"vip_total,omitempty"` + IsMarkTotal int `json:"ismark_total,omitempty"` + PauseTotal int `json:"pause_total,omitempty"` + ErrorTotal int `json:"error_total,omitempty"` + LockTotal int `json:"lock_total,omitempty"` + SpamTotal int `json:"spam_total,omitempty"` + VipExpire int `json:"vip_expire,omitempty"` + ShareOutTotal int `json:"share_out_total,omitempty"` +} + +type Domain struct { + ID json.Number `json:"id,omitempty"` + Name string `json:"name,omitempty"` + PunyCode string `json:"punycode,omitempty"` + Grade string `json:"grade,omitempty"` + GradeTitle string `json:"grade_title,omitempty"` + Status string `json:"status,omitempty"` + ExtStatus string `json:"ext_status,omitempty"` + Records string `json:"records,omitempty"` + GroupID json.Number `json:"group_id,omitempty"` + IsMark string `json:"is_mark,omitempty"` + Remark string `json:"remark,omitempty"` + IsVIP string `json:"is_vip,omitempty"` + SearchenginePush string `json:"searchengine_push,omitempty"` + UserID string `json:"user_id,omitempty"` + CreatedOn string `json:"created_on,omitempty"` + UpdatedOn string `json:"updated_on,omitempty"` + TTL string `json:"ttl,omitempty"` + CNameSpeedUp string `json:"cname_speedup,omitempty"` + Owner string `json:"owner,omitempty"` + AuthToAnquanBao bool `json:"auth_to_anquanbao,omitempty"` +} + +type domainListWrapper struct { + Status Status `json:"status"` + Info DomainInfo `json:"info"` + Domains []Domain `json:"domains"` +} + +type domainWrapper struct { + Status Status `json:"status"` + Info DomainInfo `json:"info"` + Domain Domain `json:"domain"` +} + +// domainRequest represents a generic wrapper for a domain request, +// when domainWrapper cannot be used because of type constraint on Domain. +type domainRequest struct { + Domain interface{} `json:"domain"` +} + +// domainAction generates the resource path for given domain. +func domainAction(action string) string { + if len(action) > 0 { + return fmt.Sprintf("Domain.%s", action) + } + return "Domain.List" +} + +// List the domains. +// +// dnspod API docs: https://www.dnspod.cn/docs/domains.html#domain-list +func (s *DomainsService) List() ([]Domain, *Response, error) { + path := domainAction("List") + returnedDomains := domainListWrapper{} + + payload := newPayLoad(s.client.CommonParams) + res, err := s.client.post(path, payload, &returnedDomains) + if err != nil { + return []Domain{}, res, err + } + + domains := []Domain{} + + if returnedDomains.Status.Code != "1" { + return domains, nil, fmt.Errorf("Could not get domains: %s", returnedDomains.Status.Message) + } + + for _, domain := range returnedDomains.Domains { + domains = append(domains, domain) + } + + return domains, res, nil +} + +// Create a new domain. +// +// dnspod API docs: https://www.dnspod.cn/docs/domains.html#domain-create +func (s *DomainsService) Create(domainAttributes Domain) (Domain, *Response, error) { + path := domainAction("Create") + returnedDomain := domainWrapper{} + + payload := newPayLoad(s.client.CommonParams) + payload.Set("domain", domainAttributes.Name) + payload.Set("group_id", domainAttributes.GroupID.String()) + payload.Set("is_mark", domainAttributes.IsMark) + + res, err := s.client.post(path, payload, &returnedDomain) + if err != nil { + return Domain{}, res, err + } + + return returnedDomain.Domain, res, nil +} + +// Get fetches a domain. +// +// dnspod API docs: https://www.dnspod.cn/docs/domains.html#domain-info +func (s *DomainsService) Get(ID int) (Domain, *Response, error) { + path := domainAction("Info") + returnedDomain := domainWrapper{} + + payload := newPayLoad(s.client.CommonParams) + payload.Set("domain_id", strconv.FormatInt(int64(ID), 10)) + + res, err := s.client.post(path, payload, &returnedDomain) + if err != nil { + return Domain{}, res, err + } + + return returnedDomain.Domain, res, nil +} + +// Delete a domain. +// +// dnspod API docs: https://dnsapi.cn/Domain.Remove +func (s *DomainsService) Delete(ID int) (*Response, error) { + path := domainAction("Remove") + returnedDomain := domainWrapper{} + + payload := newPayLoad(s.client.CommonParams) + payload.Set("domain_id", strconv.FormatInt(int64(ID), 10)) + + res, err := s.client.post(path, payload, &returnedDomain) + if err != nil { + return res, err + } + + return res, nil +} diff --git a/vendor/github.com/decker502/dnspod-go/go.mod b/vendor/github.com/decker502/dnspod-go/go.mod new file mode 100644 index 000000000..3fb955447 --- /dev/null +++ b/vendor/github.com/decker502/dnspod-go/go.mod @@ -0,0 +1,3 @@ +module github.com/decker502/dnspod-go + +go 1.11 diff --git a/vendor/github.com/decker502/dnspod-go/go.sum b/vendor/github.com/decker502/dnspod-go/go.sum new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/github.com/dgrijalva/jwt-go/.gitignore b/vendor/github.com/dgrijalva/jwt-go/.gitignore new file mode 100644 index 000000000..80bed650e --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +bin + + diff --git a/vendor/github.com/dgrijalva/jwt-go/.travis.yml b/vendor/github.com/dgrijalva/jwt-go/.travis.yml new file mode 100644 index 000000000..1027f56cd --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/.travis.yml @@ -0,0 +1,13 @@ +language: go + +script: + - go vet ./... + - go test -v ./... + +go: + - 1.3 + - 1.4 + - 1.5 + - 1.6 + - 1.7 + - tip diff --git a/vendor/github.com/dgrijalva/jwt-go/LICENSE b/vendor/github.com/dgrijalva/jwt-go/LICENSE new file mode 100644 index 000000000..df83a9c2f --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/LICENSE @@ -0,0 +1,8 @@ +Copyright (c) 2012 Dave Grijalva + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md b/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md new file mode 100644 index 000000000..7fc1f793c --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md @@ -0,0 +1,97 @@ +## Migration Guide from v2 -> v3 + +Version 3 adds several new, frequently requested features. To do so, it introduces a few breaking changes. We've worked to keep these as minimal as possible. This guide explains the breaking changes and how you can quickly update your code. + +### `Token.Claims` is now an interface type + +The most requested feature from the 2.0 verison of this library was the ability to provide a custom type to the JSON parser for claims. This was implemented by introducing a new interface, `Claims`, to replace `map[string]interface{}`. We also included two concrete implementations of `Claims`: `MapClaims` and `StandardClaims`. + +`MapClaims` is an alias for `map[string]interface{}` with built in validation behavior. It is the default claims type when using `Parse`. The usage is unchanged except you must type cast the claims property. + +The old example for parsing a token looked like this.. + +```go + if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil { + fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"]) + } +``` + +is now directly mapped to... + +```go + if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil { + claims := token.Claims.(jwt.MapClaims) + fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"]) + } +``` + +`StandardClaims` is designed to be embedded in your custom type. You can supply a custom claims type with the new `ParseWithClaims` function. Here's an example of using a custom claims type. + +```go + type MyCustomClaims struct { + User string + *StandardClaims + } + + if token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyLookupFunc); err == nil { + claims := token.Claims.(*MyCustomClaims) + fmt.Printf("Token for user %v expires %v", claims.User, claims.StandardClaims.ExpiresAt) + } +``` + +### `ParseFromRequest` has been moved + +To keep this library focused on the tokens without becoming overburdened with complex request processing logic, `ParseFromRequest` and its new companion `ParseFromRequestWithClaims` have been moved to a subpackage, `request`. The method signatues have also been augmented to receive a new argument: `Extractor`. + +`Extractors` do the work of picking the token string out of a request. The interface is simple and composable. + +This simple parsing example: + +```go + if token, err := jwt.ParseFromRequest(tokenString, req, keyLookupFunc); err == nil { + fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"]) + } +``` + +is directly mapped to: + +```go + if token, err := request.ParseFromRequest(req, request.OAuth2Extractor, keyLookupFunc); err == nil { + claims := token.Claims.(jwt.MapClaims) + fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"]) + } +``` + +There are several concrete `Extractor` types provided for your convenience: + +* `HeaderExtractor` will search a list of headers until one contains content. +* `ArgumentExtractor` will search a list of keys in request query and form arguments until one contains content. +* `MultiExtractor` will try a list of `Extractors` in order until one returns content. +* `AuthorizationHeaderExtractor` will look in the `Authorization` header for a `Bearer` token. +* `OAuth2Extractor` searches the places an OAuth2 token would be specified (per the spec): `Authorization` header and `access_token` argument +* `PostExtractionFilter` wraps an `Extractor`, allowing you to process the content before it's parsed. A simple example is stripping the `Bearer ` text from a header + + +### RSA signing methods no longer accept `[]byte` keys + +Due to a [critical vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), we've decided the convenience of accepting `[]byte` instead of `rsa.PublicKey` or `rsa.PrivateKey` isn't worth the risk of misuse. + +To replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error)` and `ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)`. These are just simple helpers for unpacking PEM encoded PKCS1 and PKCS8 keys. If your keys are encoded any other way, all you need to do is convert them to the `crypto/rsa` package's types. + +```go + func keyLookupFunc(*Token) (interface{}, error) { + // Don't forget to validate the alg is what you expect: + if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { + return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) + } + + // Look up key + key, err := lookupPublicKey(token.Header["kid"]) + if err != nil { + return nil, err + } + + // Unpack key from PEM encoded PKCS8 + return jwt.ParseRSAPublicKeyFromPEM(key) + } +``` diff --git a/vendor/github.com/dgrijalva/jwt-go/README.md b/vendor/github.com/dgrijalva/jwt-go/README.md new file mode 100644 index 000000000..d358d881b --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/README.md @@ -0,0 +1,100 @@ +# jwt-go + +[![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go) +[![GoDoc](https://godoc.org/github.com/dgrijalva/jwt-go?status.svg)](https://godoc.org/github.com/dgrijalva/jwt-go) + +A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) + +**NEW VERSION COMING:** There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3. + +**SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail. + +**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided. + +## What the heck is a JWT? + +JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens. + +In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is made of three parts, separated by `.`'s. The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded. The last part is the signature, encoded the same way. + +The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used. + +The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own. + +## What's in the box? + +This library supports the parsing and verification as well as the generation and signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own. + +## Examples + +See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage: + +* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac) +* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac) +* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples) + +## Extensions + +This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`. + +Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go + +## Compliance + +This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences: + +* In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key. + +## Project Status & Versioning + +This library is considered production ready. Feedback and feature requests are appreciated. The API should be considered stable. There should be very few backwards-incompatible changes outside of major version updates (and only with good reason). + +This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `master`. Periodically, versions will be tagged from `master`. You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases). + +While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v3`. It will do the right thing WRT semantic versioning. + +**BREAKING CHANGES:*** +* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API. We've tried to break as few things as possible, so there should just be a few type signature changes. A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code. + +## Usage Tips + +### Signing vs Encryption + +A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data: + +* The author of the token was in the possession of the signing secret +* The data has not been modified since it was signed + +It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library. + +### Choosing a Signing Method + +There are several signing methods available, and you should probably take the time to learn about the various options before choosing one. The principal design decision is most likely going to be symmetric vs asymmetric. + +Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation. + +Asymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification. + +### Signing Methods and Key Types + +Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones: + +* The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation +* The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation +* The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation + +### JWT and OAuth + +It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication. + +Without going too far down the rabbit hole, here's a description of the interaction of these technologies: + +* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth. +* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token. +* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL. + +## More + +Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go). + +The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation. diff --git a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md new file mode 100644 index 000000000..637029831 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md @@ -0,0 +1,118 @@ +## `jwt-go` Version History + +#### 3.2.0 + +* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation +* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate +* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before. +* Deprecated `ParseFromRequestWithClaims` to simplify API in the future. + +#### 3.1.0 + +* Improvements to `jwt` command line tool +* Added `SkipClaimsValidation` option to `Parser` +* Documentation updates + +#### 3.0.0 + +* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code + * Dropped support for `[]byte` keys when using RSA signing methods. This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods. + * `ParseFromRequest` has been moved to `request` subpackage and usage has changed + * The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`. The default value is type `MapClaims`, which is an alias to `map[string]interface{}`. This makes it possible to use a custom type when decoding claims. +* Other Additions and Changes + * Added `Claims` interface type to allow users to decode the claims into a custom type + * Added `ParseWithClaims`, which takes a third argument of type `Claims`. Use this function instead of `Parse` if you have a custom type you'd like to decode into. + * Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage + * Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims` + * Added new interface type `Extractor`, which is used for extracting JWT strings from http requests. Used with `ParseFromRequest` and `ParseFromRequestWithClaims`. + * Added several new, more specific, validation errors to error type bitmask + * Moved examples from README to executable example files + * Signing method registry is now thread safe + * Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser) + +#### 2.7.0 + +This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes. + +* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying +* Error text for expired tokens includes how long it's been expired +* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM` +* Documentation updates + +#### 2.6.0 + +* Exposed inner error within ValidationError +* Fixed validation errors when using UseJSONNumber flag +* Added several unit tests + +#### 2.5.0 + +* Added support for signing method none. You shouldn't use this. The API tries to make this clear. +* Updated/fixed some documentation +* Added more helpful error message when trying to parse tokens that begin with `BEARER ` + +#### 2.4.0 + +* Added new type, Parser, to allow for configuration of various parsing parameters + * You can now specify a list of valid signing methods. Anything outside this set will be rejected. + * You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON +* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go) +* Fixed some bugs with ECDSA parsing + +#### 2.3.0 + +* Added support for ECDSA signing methods +* Added support for RSA PSS signing methods (requires go v1.4) + +#### 2.2.0 + +* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`. Result will now be the parsed token and an error, instead of a panic. + +#### 2.1.0 + +Backwards compatible API change that was missed in 2.0.0. + +* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte` + +#### 2.0.0 + +There were two major reasons for breaking backwards compatibility with this update. The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations. There will likely be no required code changes to support this change. + +The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods. Not all keys used for all signing methods have a single standard on-disk representation. Requiring `[]byte` as the type for all keys proved too limiting. Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys. Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`. + +It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`. + +* **Compatibility Breaking Changes** + * `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct` + * `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct` + * `KeyFunc` now returns `interface{}` instead of `[]byte` + * `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key + * `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key +* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodHS256` + * Added public package global `SigningMethodHS384` + * Added public package global `SigningMethodHS512` +* Renamed type `SigningMethodRS256` to `SigningMethodRSA`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodRS256` + * Added public package global `SigningMethodRS384` + * Added public package global `SigningMethodRS512` +* Moved sample private key for HMAC tests from an inline value to a file on disk. Value is unchanged. +* Refactored the RSA implementation to be easier to read +* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM` + +#### 1.0.2 + +* Fixed bug in parsing public keys from certificates +* Added more tests around the parsing of keys for RS256 +* Code refactoring in RS256 implementation. No functional changes + +#### 1.0.1 + +* Fixed panic if RS256 signing method was passed an invalid key + +#### 1.0.0 + +* First versioned release +* API stabilized +* Supports creating, signing, parsing, and validating JWT tokens +* Supports RS256 and HS256 signing methods \ No newline at end of file diff --git a/vendor/github.com/dgrijalva/jwt-go/claims.go b/vendor/github.com/dgrijalva/jwt-go/claims.go new file mode 100644 index 000000000..f0228f02e --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/claims.go @@ -0,0 +1,134 @@ +package jwt + +import ( + "crypto/subtle" + "fmt" + "time" +) + +// For a type to be a Claims object, it must just have a Valid method that determines +// if the token is invalid for any supported reason +type Claims interface { + Valid() error +} + +// Structured version of Claims Section, as referenced at +// https://tools.ietf.org/html/rfc7519#section-4.1 +// See examples for how to use this with your own claim types +type StandardClaims struct { + Audience string `json:"aud,omitempty"` + ExpiresAt int64 `json:"exp,omitempty"` + Id string `json:"jti,omitempty"` + IssuedAt int64 `json:"iat,omitempty"` + Issuer string `json:"iss,omitempty"` + NotBefore int64 `json:"nbf,omitempty"` + Subject string `json:"sub,omitempty"` +} + +// Validates time based claims "exp, iat, nbf". +// There is no accounting for clock skew. +// As well, if any of the above claims are not in the token, it will still +// be considered a valid claim. +func (c StandardClaims) Valid() error { + vErr := new(ValidationError) + now := TimeFunc().Unix() + + // The claims below are optional, by default, so if they are set to the + // default value in Go, let's not fail the verification for them. + if c.VerifyExpiresAt(now, false) == false { + delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0)) + vErr.Inner = fmt.Errorf("token is expired by %v", delta) + vErr.Errors |= ValidationErrorExpired + } + + if c.VerifyIssuedAt(now, false) == false { + vErr.Inner = fmt.Errorf("Token used before issued") + vErr.Errors |= ValidationErrorIssuedAt + } + + if c.VerifyNotBefore(now, false) == false { + vErr.Inner = fmt.Errorf("token is not valid yet") + vErr.Errors |= ValidationErrorNotValidYet + } + + if vErr.valid() { + return nil + } + + return vErr +} + +// Compares the aud claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool { + return verifyAud(c.Audience, cmp, req) +} + +// Compares the exp claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool { + return verifyExp(c.ExpiresAt, cmp, req) +} + +// Compares the iat claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool { + return verifyIat(c.IssuedAt, cmp, req) +} + +// Compares the iss claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool { + return verifyIss(c.Issuer, cmp, req) +} + +// Compares the nbf claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool { + return verifyNbf(c.NotBefore, cmp, req) +} + +// ----- helpers + +func verifyAud(aud string, cmp string, required bool) bool { + if aud == "" { + return !required + } + if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 { + return true + } else { + return false + } +} + +func verifyExp(exp int64, now int64, required bool) bool { + if exp == 0 { + return !required + } + return now <= exp +} + +func verifyIat(iat int64, now int64, required bool) bool { + if iat == 0 { + return !required + } + return now >= iat +} + +func verifyIss(iss string, cmp string, required bool) bool { + if iss == "" { + return !required + } + if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 { + return true + } else { + return false + } +} + +func verifyNbf(nbf int64, now int64, required bool) bool { + if nbf == 0 { + return !required + } + return now >= nbf +} diff --git a/vendor/github.com/dgrijalva/jwt-go/doc.go b/vendor/github.com/dgrijalva/jwt-go/doc.go new file mode 100644 index 000000000..a86dc1a3b --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/doc.go @@ -0,0 +1,4 @@ +// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html +// +// See README.md for more info. +package jwt diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go new file mode 100644 index 000000000..f97738124 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/ecdsa.go @@ -0,0 +1,148 @@ +package jwt + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rand" + "errors" + "math/big" +) + +var ( + // Sadly this is missing from crypto/ecdsa compared to crypto/rsa + ErrECDSAVerification = errors.New("crypto/ecdsa: verification error") +) + +// Implements the ECDSA family of signing methods signing methods +// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification +type SigningMethodECDSA struct { + Name string + Hash crypto.Hash + KeySize int + CurveBits int +} + +// Specific instances for EC256 and company +var ( + SigningMethodES256 *SigningMethodECDSA + SigningMethodES384 *SigningMethodECDSA + SigningMethodES512 *SigningMethodECDSA +) + +func init() { + // ES256 + SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256} + RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod { + return SigningMethodES256 + }) + + // ES384 + SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384} + RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod { + return SigningMethodES384 + }) + + // ES512 + SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521} + RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod { + return SigningMethodES512 + }) +} + +func (m *SigningMethodECDSA) Alg() string { + return m.Name +} + +// Implements the Verify method from SigningMethod +// For this verify method, key must be an ecdsa.PublicKey struct +func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + // Get the key + var ecdsaKey *ecdsa.PublicKey + switch k := key.(type) { + case *ecdsa.PublicKey: + ecdsaKey = k + default: + return ErrInvalidKeyType + } + + if len(sig) != 2*m.KeySize { + return ErrECDSAVerification + } + + r := big.NewInt(0).SetBytes(sig[:m.KeySize]) + s := big.NewInt(0).SetBytes(sig[m.KeySize:]) + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true { + return nil + } else { + return ErrECDSAVerification + } +} + +// Implements the Sign method from SigningMethod +// For this signing method, key must be an ecdsa.PrivateKey struct +func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) { + // Get the key + var ecdsaKey *ecdsa.PrivateKey + switch k := key.(type) { + case *ecdsa.PrivateKey: + ecdsaKey = k + default: + return "", ErrInvalidKeyType + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return r, s + if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil { + curveBits := ecdsaKey.Curve.Params().BitSize + + if m.CurveBits != curveBits { + return "", ErrInvalidKey + } + + keyBytes := curveBits / 8 + if curveBits%8 > 0 { + keyBytes += 1 + } + + // We serialize the outpus (r and s) into big-endian byte arrays and pad + // them with zeros on the left to make sure the sizes work out. Both arrays + // must be keyBytes long, and the output must be 2*keyBytes long. + rBytes := r.Bytes() + rBytesPadded := make([]byte, keyBytes) + copy(rBytesPadded[keyBytes-len(rBytes):], rBytes) + + sBytes := s.Bytes() + sBytesPadded := make([]byte, keyBytes) + copy(sBytesPadded[keyBytes-len(sBytes):], sBytes) + + out := append(rBytesPadded, sBytesPadded...) + + return EncodeSegment(out), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go new file mode 100644 index 000000000..d19624b72 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go @@ -0,0 +1,67 @@ +package jwt + +import ( + "crypto/ecdsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrNotECPublicKey = errors.New("Key is not a valid ECDSA public key") + ErrNotECPrivateKey = errors.New("Key is not a valid ECDSA private key") +) + +// Parse PEM encoded Elliptic Curve Private Key Structure +func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil { + return nil, err + } + + var pkey *ecdsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok { + return nil, ErrNotECPrivateKey + } + + return pkey, nil +} + +// Parse PEM encoded PKCS1 or PKCS8 public key +func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + return nil, err + } + } + + var pkey *ecdsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok { + return nil, ErrNotECPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/errors.go b/vendor/github.com/dgrijalva/jwt-go/errors.go new file mode 100644 index 000000000..1c93024aa --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/errors.go @@ -0,0 +1,59 @@ +package jwt + +import ( + "errors" +) + +// Error constants +var ( + ErrInvalidKey = errors.New("key is invalid") + ErrInvalidKeyType = errors.New("key is of invalid type") + ErrHashUnavailable = errors.New("the requested hash function is unavailable") +) + +// The errors that might occur when parsing and validating a token +const ( + ValidationErrorMalformed uint32 = 1 << iota // Token is malformed + ValidationErrorUnverifiable // Token could not be verified because of signing problems + ValidationErrorSignatureInvalid // Signature validation failed + + // Standard Claim validation errors + ValidationErrorAudience // AUD validation failed + ValidationErrorExpired // EXP validation failed + ValidationErrorIssuedAt // IAT validation failed + ValidationErrorIssuer // ISS validation failed + ValidationErrorNotValidYet // NBF validation failed + ValidationErrorId // JTI validation failed + ValidationErrorClaimsInvalid // Generic claims validation error +) + +// Helper for constructing a ValidationError with a string error message +func NewValidationError(errorText string, errorFlags uint32) *ValidationError { + return &ValidationError{ + text: errorText, + Errors: errorFlags, + } +} + +// The error from Parse if token is not valid +type ValidationError struct { + Inner error // stores the error returned by external dependencies, i.e.: KeyFunc + Errors uint32 // bitfield. see ValidationError... constants + text string // errors that do not have a valid error just have text +} + +// Validation error is an error type +func (e ValidationError) Error() string { + if e.Inner != nil { + return e.Inner.Error() + } else if e.text != "" { + return e.text + } else { + return "token is invalid" + } +} + +// No errors +func (e *ValidationError) valid() bool { + return e.Errors == 0 +} diff --git a/vendor/github.com/dgrijalva/jwt-go/hmac.go b/vendor/github.com/dgrijalva/jwt-go/hmac.go new file mode 100644 index 000000000..addbe5d40 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/hmac.go @@ -0,0 +1,95 @@ +package jwt + +import ( + "crypto" + "crypto/hmac" + "errors" +) + +// Implements the HMAC-SHA family of signing methods signing methods +// Expects key type of []byte for both signing and validation +type SigningMethodHMAC struct { + Name string + Hash crypto.Hash +} + +// Specific instances for HS256 and company +var ( + SigningMethodHS256 *SigningMethodHMAC + SigningMethodHS384 *SigningMethodHMAC + SigningMethodHS512 *SigningMethodHMAC + ErrSignatureInvalid = errors.New("signature is invalid") +) + +func init() { + // HS256 + SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod { + return SigningMethodHS256 + }) + + // HS384 + SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod { + return SigningMethodHS384 + }) + + // HS512 + SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod { + return SigningMethodHS512 + }) +} + +func (m *SigningMethodHMAC) Alg() string { + return m.Name +} + +// Verify the signature of HSXXX tokens. Returns nil if the signature is valid. +func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error { + // Verify the key is the right type + keyBytes, ok := key.([]byte) + if !ok { + return ErrInvalidKeyType + } + + // Decode signature, for comparison + sig, err := DecodeSegment(signature) + if err != nil { + return err + } + + // Can we use the specified hashing method? + if !m.Hash.Available() { + return ErrHashUnavailable + } + + // This signing method is symmetric, so we validate the signature + // by reproducing the signature from the signing string and key, then + // comparing that against the provided signature. + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + if !hmac.Equal(sig, hasher.Sum(nil)) { + return ErrSignatureInvalid + } + + // No validation errors. Signature is good. + return nil +} + +// Implements the Sign method from SigningMethod for this signing method. +// Key must be []byte +func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) { + if keyBytes, ok := key.([]byte); ok { + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + + return EncodeSegment(hasher.Sum(nil)), nil + } + + return "", ErrInvalidKeyType +} diff --git a/vendor/github.com/dgrijalva/jwt-go/map_claims.go b/vendor/github.com/dgrijalva/jwt-go/map_claims.go new file mode 100644 index 000000000..291213c46 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/map_claims.go @@ -0,0 +1,94 @@ +package jwt + +import ( + "encoding/json" + "errors" + // "fmt" +) + +// Claims type that uses the map[string]interface{} for JSON decoding +// This is the default claims type if you don't supply one +type MapClaims map[string]interface{} + +// Compares the aud claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyAudience(cmp string, req bool) bool { + aud, _ := m["aud"].(string) + return verifyAud(aud, cmp, req) +} + +// Compares the exp claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool { + switch exp := m["exp"].(type) { + case float64: + return verifyExp(int64(exp), cmp, req) + case json.Number: + v, _ := exp.Int64() + return verifyExp(v, cmp, req) + } + return req == false +} + +// Compares the iat claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool { + switch iat := m["iat"].(type) { + case float64: + return verifyIat(int64(iat), cmp, req) + case json.Number: + v, _ := iat.Int64() + return verifyIat(v, cmp, req) + } + return req == false +} + +// Compares the iss claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyIssuer(cmp string, req bool) bool { + iss, _ := m["iss"].(string) + return verifyIss(iss, cmp, req) +} + +// Compares the nbf claim against cmp. +// If required is false, this method will return true if the value matches or is unset +func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool { + switch nbf := m["nbf"].(type) { + case float64: + return verifyNbf(int64(nbf), cmp, req) + case json.Number: + v, _ := nbf.Int64() + return verifyNbf(v, cmp, req) + } + return req == false +} + +// Validates time based claims "exp, iat, nbf". +// There is no accounting for clock skew. +// As well, if any of the above claims are not in the token, it will still +// be considered a valid claim. +func (m MapClaims) Valid() error { + vErr := new(ValidationError) + now := TimeFunc().Unix() + + if m.VerifyExpiresAt(now, false) == false { + vErr.Inner = errors.New("Token is expired") + vErr.Errors |= ValidationErrorExpired + } + + if m.VerifyIssuedAt(now, false) == false { + vErr.Inner = errors.New("Token used before issued") + vErr.Errors |= ValidationErrorIssuedAt + } + + if m.VerifyNotBefore(now, false) == false { + vErr.Inner = errors.New("Token is not valid yet") + vErr.Errors |= ValidationErrorNotValidYet + } + + if vErr.valid() { + return nil + } + + return vErr +} diff --git a/vendor/github.com/dgrijalva/jwt-go/none.go b/vendor/github.com/dgrijalva/jwt-go/none.go new file mode 100644 index 000000000..f04d189d0 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/none.go @@ -0,0 +1,52 @@ +package jwt + +// Implements the none signing method. This is required by the spec +// but you probably should never use it. +var SigningMethodNone *signingMethodNone + +const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed" + +var NoneSignatureTypeDisallowedError error + +type signingMethodNone struct{} +type unsafeNoneMagicConstant string + +func init() { + SigningMethodNone = &signingMethodNone{} + NoneSignatureTypeDisallowedError = NewValidationError("'none' signature type is not allowed", ValidationErrorSignatureInvalid) + + RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod { + return SigningMethodNone + }) +} + +func (m *signingMethodNone) Alg() string { + return "none" +} + +// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Verify(signingString, signature string, key interface{}) (err error) { + // Key must be UnsafeAllowNoneSignatureType to prevent accidentally + // accepting 'none' signing method + if _, ok := key.(unsafeNoneMagicConstant); !ok { + return NoneSignatureTypeDisallowedError + } + // If signing method is none, signature must be an empty string + if signature != "" { + return NewValidationError( + "'none' signing method with non-empty signature", + ValidationErrorSignatureInvalid, + ) + } + + // Accept 'none' signing method. + return nil +} + +// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Sign(signingString string, key interface{}) (string, error) { + if _, ok := key.(unsafeNoneMagicConstant); ok { + return "", nil + } + return "", NoneSignatureTypeDisallowedError +} diff --git a/vendor/github.com/dgrijalva/jwt-go/parser.go b/vendor/github.com/dgrijalva/jwt-go/parser.go new file mode 100644 index 000000000..d6901d9ad --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/parser.go @@ -0,0 +1,148 @@ +package jwt + +import ( + "bytes" + "encoding/json" + "fmt" + "strings" +) + +type Parser struct { + ValidMethods []string // If populated, only these methods will be considered valid + UseJSONNumber bool // Use JSON Number format in JSON decoder + SkipClaimsValidation bool // Skip claims validation during token parsing +} + +// Parse, validate, and return a token. +// keyFunc will receive the parsed token and should return the key for validating. +// If everything is kosher, err will be nil +func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { + return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) +} + +func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { + token, parts, err := p.ParseUnverified(tokenString, claims) + if err != nil { + return token, err + } + + // Verify signing method is in the required set + if p.ValidMethods != nil { + var signingMethodValid = false + var alg = token.Method.Alg() + for _, m := range p.ValidMethods { + if m == alg { + signingMethodValid = true + break + } + } + if !signingMethodValid { + // signing method is not in the listed set + return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid) + } + } + + // Lookup key + var key interface{} + if keyFunc == nil { + // keyFunc was not provided. short circuiting validation + return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable) + } + if key, err = keyFunc(token); err != nil { + // keyFunc returned an error + if ve, ok := err.(*ValidationError); ok { + return token, ve + } + return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable} + } + + vErr := &ValidationError{} + + // Validate Claims + if !p.SkipClaimsValidation { + if err := token.Claims.Valid(); err != nil { + + // If the Claims Valid returned an error, check if it is a validation error, + // If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set + if e, ok := err.(*ValidationError); !ok { + vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid} + } else { + vErr = e + } + } + } + + // Perform validation + token.Signature = parts[2] + if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil { + vErr.Inner = err + vErr.Errors |= ValidationErrorSignatureInvalid + } + + if vErr.valid() { + token.Valid = true + return token, nil + } + + return token, vErr +} + +// WARNING: Don't use this method unless you know what you're doing +// +// This method parses the token but doesn't validate the signature. It's only +// ever useful in cases where you know the signature is valid (because it has +// been checked previously in the stack) and you want to extract values from +// it. +func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { + parts = strings.Split(tokenString, ".") + if len(parts) != 3 { + return nil, parts, NewValidationError("token contains an invalid number of segments", ValidationErrorMalformed) + } + + token = &Token{Raw: tokenString} + + // parse Header + var headerBytes []byte + if headerBytes, err = DecodeSegment(parts[0]); err != nil { + if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") { + return token, parts, NewValidationError("tokenstring should not contain 'bearer '", ValidationErrorMalformed) + } + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + if err = json.Unmarshal(headerBytes, &token.Header); err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // parse Claims + var claimBytes []byte + token.Claims = claims + + if claimBytes, err = DecodeSegment(parts[1]); err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) + if p.UseJSONNumber { + dec.UseNumber() + } + // JSON Decode. Special case for map type to avoid weird pointer behavior + if c, ok := token.Claims.(MapClaims); ok { + err = dec.Decode(&c) + } else { + err = dec.Decode(&claims) + } + // Handle decode error + if err != nil { + return token, parts, &ValidationError{Inner: err, Errors: ValidationErrorMalformed} + } + + // Lookup signature method + if method, ok := token.Header["alg"].(string); ok { + if token.Method = GetSigningMethod(method); token.Method == nil { + return token, parts, NewValidationError("signing method (alg) is unavailable.", ValidationErrorUnverifiable) + } + } else { + return token, parts, NewValidationError("signing method (alg) is unspecified.", ValidationErrorUnverifiable) + } + + return token, parts, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa.go b/vendor/github.com/dgrijalva/jwt-go/rsa.go new file mode 100644 index 000000000..e4caf1ca4 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa.go @@ -0,0 +1,101 @@ +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// Implements the RSA family of signing methods signing methods +// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation +type SigningMethodRSA struct { + Name string + Hash crypto.Hash +} + +// Specific instances for RS256 and company +var ( + SigningMethodRS256 *SigningMethodRSA + SigningMethodRS384 *SigningMethodRSA + SigningMethodRS512 *SigningMethodRSA +) + +func init() { + // RS256 + SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { + return SigningMethodRS256 + }) + + // RS384 + SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { + return SigningMethodRS384 + }) + + // RS512 + SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { + return SigningMethodRS512 + }) +} + +func (m *SigningMethodRSA) Alg() string { + return m.Name +} + +// Implements the Verify method from SigningMethod +// For this signing method, must be an *rsa.PublicKey structure. +func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + var rsaKey *rsa.PublicKey + var ok bool + + if rsaKey, ok = key.(*rsa.PublicKey); !ok { + return ErrInvalidKeyType + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) +} + +// Implements the Sign method from SigningMethod +// For this signing method, must be an *rsa.PrivateKey structure. +func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { + var rsaKey *rsa.PrivateKey + var ok bool + + // Validate type of key + if rsaKey, ok = key.(*rsa.PrivateKey); !ok { + return "", ErrInvalidKey + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { + return EncodeSegment(sigBytes), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go b/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go new file mode 100644 index 000000000..10ee9db8a --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go @@ -0,0 +1,126 @@ +// +build go1.4 + +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// Implements the RSAPSS family of signing methods signing methods +type SigningMethodRSAPSS struct { + *SigningMethodRSA + Options *rsa.PSSOptions +} + +// Specific instances for RS/PS and company +var ( + SigningMethodPS256 *SigningMethodRSAPSS + SigningMethodPS384 *SigningMethodRSAPSS + SigningMethodPS512 *SigningMethodRSAPSS +) + +func init() { + // PS256 + SigningMethodPS256 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS256", + Hash: crypto.SHA256, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA256, + }, + } + RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod { + return SigningMethodPS256 + }) + + // PS384 + SigningMethodPS384 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS384", + Hash: crypto.SHA384, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA384, + }, + } + RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod { + return SigningMethodPS384 + }) + + // PS512 + SigningMethodPS512 = &SigningMethodRSAPSS{ + &SigningMethodRSA{ + Name: "PS512", + Hash: crypto.SHA512, + }, + &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + Hash: crypto.SHA512, + }, + } + RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod { + return SigningMethodPS512 + }) +} + +// Implements the Verify method from SigningMethod +// For this verify method, key must be an rsa.PublicKey struct +func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interface{}) error { + var err error + + // Decode the signature + var sig []byte + if sig, err = DecodeSegment(signature); err != nil { + return err + } + + var rsaKey *rsa.PublicKey + switch k := key.(type) { + case *rsa.PublicKey: + rsaKey = k + default: + return ErrInvalidKey + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options) +} + +// Implements the Sign method from SigningMethod +// For this signing method, key must be an rsa.PrivateKey struct +func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) (string, error) { + var rsaKey *rsa.PrivateKey + + switch k := key.(type) { + case *rsa.PrivateKey: + rsaKey = k + default: + return "", ErrInvalidKeyType + } + + // Create the hasher + if !m.Hash.Available() { + return "", ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil { + return EncodeSegment(sigBytes), nil + } else { + return "", err + } +} diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go new file mode 100644 index 000000000..a5ababf95 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go @@ -0,0 +1,101 @@ +package jwt + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key") + ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key") + ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key") +) + +// Parse PEM encoded PKCS1 or PKCS8 private key +func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// Parse PEM encoded PKCS1 or PKCS8 private key protected with password +func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey interface{} + + var blockDecrypted []byte + if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil { + return nil, err + } + + if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// Parse PEM encoded PKCS1 or PKCS8 public key +func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey interface{} + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + return nil, err + } + } + + var pkey *rsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PublicKey); !ok { + return nil, ErrNotRSAPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/dgrijalva/jwt-go/signing_method.go b/vendor/github.com/dgrijalva/jwt-go/signing_method.go new file mode 100644 index 000000000..ed1f212b2 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/signing_method.go @@ -0,0 +1,35 @@ +package jwt + +import ( + "sync" +) + +var signingMethods = map[string]func() SigningMethod{} +var signingMethodLock = new(sync.RWMutex) + +// Implement SigningMethod to add new methods for signing or verifying tokens. +type SigningMethod interface { + Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid + Sign(signingString string, key interface{}) (string, error) // Returns encoded signature or error + Alg() string // returns the alg identifier for this method (example: 'HS256') +} + +// Register the "alg" name and a factory function for signing method. +// This is typically done during init() in the method's implementation +func RegisterSigningMethod(alg string, f func() SigningMethod) { + signingMethodLock.Lock() + defer signingMethodLock.Unlock() + + signingMethods[alg] = f +} + +// Get a signing method from an "alg" string +func GetSigningMethod(alg string) (method SigningMethod) { + signingMethodLock.RLock() + defer signingMethodLock.RUnlock() + + if methodF, ok := signingMethods[alg]; ok { + method = methodF() + } + return +} diff --git a/vendor/github.com/dgrijalva/jwt-go/token.go b/vendor/github.com/dgrijalva/jwt-go/token.go new file mode 100644 index 000000000..d637e0867 --- /dev/null +++ b/vendor/github.com/dgrijalva/jwt-go/token.go @@ -0,0 +1,108 @@ +package jwt + +import ( + "encoding/base64" + "encoding/json" + "strings" + "time" +) + +// TimeFunc provides the current time when parsing token to validate "exp" claim (expiration time). +// You can override it to use another time value. This is useful for testing or if your +// server uses a different time zone than your tokens. +var TimeFunc = time.Now + +// Parse methods use this callback function to supply +// the key for verification. The function receives the parsed, +// but unverified Token. This allows you to use properties in the +// Header of the token (such as `kid`) to identify which key to use. +type Keyfunc func(*Token) (interface{}, error) + +// A JWT Token. Different fields will be used depending on whether you're +// creating or parsing/verifying a token. +type Token struct { + Raw string // The raw token. Populated when you Parse a token + Method SigningMethod // The signing method used or to be used + Header map[string]interface{} // The first segment of the token + Claims Claims // The second segment of the token + Signature string // The third segment of the token. Populated when you Parse a token + Valid bool // Is the token valid? Populated when you Parse/Verify a token +} + +// Create a new Token. Takes a signing method +func New(method SigningMethod) *Token { + return NewWithClaims(method, MapClaims{}) +} + +func NewWithClaims(method SigningMethod, claims Claims) *Token { + return &Token{ + Header: map[string]interface{}{ + "typ": "JWT", + "alg": method.Alg(), + }, + Claims: claims, + Method: method, + } +} + +// Get the complete, signed token +func (t *Token) SignedString(key interface{}) (string, error) { + var sig, sstr string + var err error + if sstr, err = t.SigningString(); err != nil { + return "", err + } + if sig, err = t.Method.Sign(sstr, key); err != nil { + return "", err + } + return strings.Join([]string{sstr, sig}, "."), nil +} + +// Generate the signing string. This is the +// most expensive part of the whole deal. Unless you +// need this for something special, just go straight for +// the SignedString. +func (t *Token) SigningString() (string, error) { + var err error + parts := make([]string, 2) + for i, _ := range parts { + var jsonValue []byte + if i == 0 { + if jsonValue, err = json.Marshal(t.Header); err != nil { + return "", err + } + } else { + if jsonValue, err = json.Marshal(t.Claims); err != nil { + return "", err + } + } + + parts[i] = EncodeSegment(jsonValue) + } + return strings.Join(parts, "."), nil +} + +// Parse, validate, and return a token. +// keyFunc will receive the parsed token and should return the key for validating. +// If everything is kosher, err will be nil +func Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { + return new(Parser).Parse(tokenString, keyFunc) +} + +func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { + return new(Parser).ParseWithClaims(tokenString, claims, keyFunc) +} + +// Encode JWT specific base64url encoding with padding stripped +func EncodeSegment(seg []byte) string { + return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=") +} + +// Decode JWT specific base64url encoding with padding stripped +func DecodeSegment(seg string) ([]byte, error) { + if l := len(seg) % 4; l > 0 { + seg += strings.Repeat("=", 4-l) + } + + return base64.URLEncoding.DecodeString(seg) +} diff --git a/vendor/github.com/dimchansky/utfbom/.gitignore b/vendor/github.com/dimchansky/utfbom/.gitignore new file mode 100644 index 000000000..d7ec5cebb --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/.gitignore @@ -0,0 +1,37 @@ +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib +*.o +*.a + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.prof + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ + +# Gogland +.idea/ \ No newline at end of file diff --git a/vendor/github.com/dimchansky/utfbom/.travis.yml b/vendor/github.com/dimchansky/utfbom/.travis.yml new file mode 100644 index 000000000..3512c8519 --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/.travis.yml @@ -0,0 +1,18 @@ +language: go + +go: + - '1.10' + - '1.11' + +# sudo=false makes the build run using a container +sudo: false + +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover + - go get golang.org/x/tools/cmd/goimports + - go get github.com/golang/lint/golint +script: + - gofiles=$(find ./ -name '*.go') && [ -z "$gofiles" ] || unformatted=$(goimports -l $gofiles) && [ -z "$unformatted" ] || (echo >&2 "Go files must be formatted with gofmt. Following files has problem:\n $unformatted" && false) + - golint ./... # This won't break the build, just show warnings + - $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/dimchansky/utfbom/LICENSE b/vendor/github.com/dimchansky/utfbom/LICENSE new file mode 100644 index 000000000..8dada3eda --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/LICENSE @@ -0,0 +1,201 @@ + 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. diff --git a/vendor/github.com/dimchansky/utfbom/README.md b/vendor/github.com/dimchansky/utfbom/README.md new file mode 100644 index 000000000..8ece28008 --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/README.md @@ -0,0 +1,66 @@ +# utfbom [![Godoc](https://godoc.org/github.com/dimchansky/utfbom?status.png)](https://godoc.org/github.com/dimchansky/utfbom) [![License](https://img.shields.io/:license-apache-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Build Status](https://travis-ci.org/dimchansky/utfbom.svg?branch=master)](https://travis-ci.org/dimchansky/utfbom) [![Go Report Card](https://goreportcard.com/badge/github.com/dimchansky/utfbom)](https://goreportcard.com/report/github.com/dimchansky/utfbom) [![Coverage Status](https://coveralls.io/repos/github/dimchansky/utfbom/badge.svg?branch=master)](https://coveralls.io/github/dimchansky/utfbom?branch=master) + +The package utfbom implements the detection of the BOM (Unicode Byte Order Mark) and removing as necessary. It can also return the encoding detected by the BOM. + +## Installation + + go get -u github.com/dimchansky/utfbom + +## Example + +```go +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + + "github.com/dimchansky/utfbom" +) + +func main() { + trySkip([]byte("\xEF\xBB\xBFhello")) + trySkip([]byte("hello")) +} + +func trySkip(byteData []byte) { + fmt.Println("Input:", byteData) + + // just skip BOM + output, err := ioutil.ReadAll(utfbom.SkipOnly(bytes.NewReader(byteData))) + if err != nil { + fmt.Println(err) + return + } + fmt.Println("ReadAll with BOM skipping", output) + + // skip BOM and detect encoding + sr, enc := utfbom.Skip(bytes.NewReader(byteData)) + fmt.Printf("Detected encoding: %s\n", enc) + output, err = ioutil.ReadAll(sr) + if err != nil { + fmt.Println(err) + return + } + fmt.Println("ReadAll with BOM detection and skipping", output) + fmt.Println() +} +``` + +Output: + +``` +$ go run main.go +Input: [239 187 191 104 101 108 108 111] +ReadAll with BOM skipping [104 101 108 108 111] +Detected encoding: UTF8 +ReadAll with BOM detection and skipping [104 101 108 108 111] + +Input: [104 101 108 108 111] +ReadAll with BOM skipping [104 101 108 108 111] +Detected encoding: Unknown +ReadAll with BOM detection and skipping [104 101 108 108 111] +``` + + diff --git a/vendor/github.com/dimchansky/utfbom/go.mod b/vendor/github.com/dimchansky/utfbom/go.mod new file mode 100644 index 000000000..4b9ecc6f5 --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/go.mod @@ -0,0 +1 @@ +module github.com/dimchansky/utfbom \ No newline at end of file diff --git a/vendor/github.com/dimchansky/utfbom/utfbom.go b/vendor/github.com/dimchansky/utfbom/utfbom.go new file mode 100644 index 000000000..77a303e56 --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/utfbom.go @@ -0,0 +1,192 @@ +// Package utfbom implements the detection of the BOM (Unicode Byte Order Mark) and removing as necessary. +// It wraps an io.Reader object, creating another object (Reader) that also implements the io.Reader +// interface but provides automatic BOM checking and removing as necessary. +package utfbom + +import ( + "errors" + "io" +) + +// Encoding is type alias for detected UTF encoding. +type Encoding int + +// Constants to identify detected UTF encodings. +const ( + // Unknown encoding, returned when no BOM was detected + Unknown Encoding = iota + + // UTF8, BOM bytes: EF BB BF + UTF8 + + // UTF-16, big-endian, BOM bytes: FE FF + UTF16BigEndian + + // UTF-16, little-endian, BOM bytes: FF FE + UTF16LittleEndian + + // UTF-32, big-endian, BOM bytes: 00 00 FE FF + UTF32BigEndian + + // UTF-32, little-endian, BOM bytes: FF FE 00 00 + UTF32LittleEndian +) + +// String returns a user-friendly string representation of the encoding. Satisfies fmt.Stringer interface. +func (e Encoding) String() string { + switch e { + case UTF8: + return "UTF8" + case UTF16BigEndian: + return "UTF16BigEndian" + case UTF16LittleEndian: + return "UTF16LittleEndian" + case UTF32BigEndian: + return "UTF32BigEndian" + case UTF32LittleEndian: + return "UTF32LittleEndian" + default: + return "Unknown" + } +} + +const maxConsecutiveEmptyReads = 100 + +// Skip creates Reader which automatically detects BOM (Unicode Byte Order Mark) and removes it as necessary. +// It also returns the encoding detected by the BOM. +// If the detected encoding is not needed, you can call the SkipOnly function. +func Skip(rd io.Reader) (*Reader, Encoding) { + // Is it already a Reader? + b, ok := rd.(*Reader) + if ok { + return b, Unknown + } + + enc, left, err := detectUtf(rd) + return &Reader{ + rd: rd, + buf: left, + err: err, + }, enc +} + +// SkipOnly creates Reader which automatically detects BOM (Unicode Byte Order Mark) and removes it as necessary. +func SkipOnly(rd io.Reader) *Reader { + r, _ := Skip(rd) + return r +} + +// Reader implements automatic BOM (Unicode Byte Order Mark) checking and +// removing as necessary for an io.Reader object. +type Reader struct { + rd io.Reader // reader provided by the client + buf []byte // buffered data + err error // last error +} + +// Read is an implementation of io.Reader interface. +// The bytes are taken from the underlying Reader, but it checks for BOMs, removing them as necessary. +func (r *Reader) Read(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + + if r.buf == nil { + if r.err != nil { + return 0, r.readErr() + } + + return r.rd.Read(p) + } + + // copy as much as we can + n = copy(p, r.buf) + r.buf = nilIfEmpty(r.buf[n:]) + return n, nil +} + +func (r *Reader) readErr() error { + err := r.err + r.err = nil + return err +} + +var errNegativeRead = errors.New("utfbom: reader returned negative count from Read") + +func detectUtf(rd io.Reader) (enc Encoding, buf []byte, err error) { + buf, err = readBOM(rd) + + if len(buf) >= 4 { + if isUTF32BigEndianBOM4(buf) { + return UTF32BigEndian, nilIfEmpty(buf[4:]), err + } + if isUTF32LittleEndianBOM4(buf) { + return UTF32LittleEndian, nilIfEmpty(buf[4:]), err + } + } + + if len(buf) > 2 && isUTF8BOM3(buf) { + return UTF8, nilIfEmpty(buf[3:]), err + } + + if (err != nil && err != io.EOF) || (len(buf) < 2) { + return Unknown, nilIfEmpty(buf), err + } + + if isUTF16BigEndianBOM2(buf) { + return UTF16BigEndian, nilIfEmpty(buf[2:]), err + } + if isUTF16LittleEndianBOM2(buf) { + return UTF16LittleEndian, nilIfEmpty(buf[2:]), err + } + + return Unknown, nilIfEmpty(buf), err +} + +func readBOM(rd io.Reader) (buf []byte, err error) { + const maxBOMSize = 4 + var bom [maxBOMSize]byte // used to read BOM + + // read as many bytes as possible + for nEmpty, n := 0, 0; err == nil && len(buf) < maxBOMSize; buf = bom[:len(buf)+n] { + if n, err = rd.Read(bom[len(buf):]); n < 0 { + panic(errNegativeRead) + } + if n > 0 { + nEmpty = 0 + } else { + nEmpty++ + if nEmpty >= maxConsecutiveEmptyReads { + err = io.ErrNoProgress + } + } + } + return +} + +func isUTF32BigEndianBOM4(buf []byte) bool { + return buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0xFE && buf[3] == 0xFF +} + +func isUTF32LittleEndianBOM4(buf []byte) bool { + return buf[0] == 0xFF && buf[1] == 0xFE && buf[2] == 0x00 && buf[3] == 0x00 +} + +func isUTF8BOM3(buf []byte) bool { + return buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF +} + +func isUTF16BigEndianBOM2(buf []byte) bool { + return buf[0] == 0xFE && buf[1] == 0xFF +} + +func isUTF16LittleEndianBOM2(buf []byte) bool { + return buf[0] == 0xFF && buf[1] == 0xFE +} + +func nilIfEmpty(buf []byte) (res []byte) { + if len(buf) > 0 { + res = buf + } + return +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/LICENSE.txt b/vendor/github.com/dnsimple/dnsimple-go/LICENSE.txt new file mode 100644 index 000000000..3c2f300e1 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018 Aetrion LLC dba DNSimple + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/accounts.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/accounts.go new file mode 100644 index 000000000..2f86ed305 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/accounts.go @@ -0,0 +1,41 @@ +package dnsimple + +type AccountsService struct { + client *Client +} + +// Account represents a DNSimple account. +type Account struct { + ID int64 `json:"id,omitempty"` + Email string `json:"email,omitempty"` + PlanIdentifier string `json:"plan_identifier,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// accountsResponse represents a response from an API method that returns a collection of Account struct. +type accountsResponse struct { + Response + Data []Account `json:"data"` +} + +// ListAccounts list the accounts for an user. +// +// See https://developer.dnsimple.com/v2/accounts/#list +func (s *AccountsService) ListAccounts(options *ListOptions) (*accountsResponse, error) { + path := versioned("/accounts") + accountsResponse := &accountsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, accountsResponse) + if err != nil { + return accountsResponse, err + } + + accountsResponse.HttpResponse = resp + return accountsResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/authentication.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/authentication.go new file mode 100644 index 000000000..dac6f51b3 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/authentication.go @@ -0,0 +1,52 @@ +package dnsimple + +import ( + "net/http" +) + +// BasicAuthTransport is an http.RoundTripper that authenticates all requests +// using HTTP Basic Authentication with the provided username and password. +type BasicAuthTransport struct { + Username string + Password string + + // Transport is the transport RoundTripper used to make HTTP requests. + // If nil, http.DefaultTransport is used. + Transport http.RoundTripper +} + +// RoundTrip implements the RoundTripper interface. We just add the +// basic auth and return the RoundTripper for this transport type. +func (t *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) { + req2 := cloneRequest(req) // per RoundTripper contract + + req2.SetBasicAuth(t.Username, t.Password) + return t.transport().RoundTrip(req2) +} + +// Client returns an *http.Client that uses the BasicAuthTransport transport +// to authenticate the request via HTTP Basic Auth. +func (t *BasicAuthTransport) Client() *http.Client { + return &http.Client{Transport: t} +} + +func (t *BasicAuthTransport) transport() http.RoundTripper { + if t.Transport != nil { + return t.Transport + } + return http.DefaultTransport +} + +// cloneRequest returns a clone of the provided *http.Request. +// The clone is a shallow copy of the struct and its Header map. +func cloneRequest(r *http.Request) *http.Request { + // shallow copy of the struct + r2 := new(http.Request) + *r2 = *r + // deep copy of the Header + r2.Header = make(http.Header, len(r.Header)) + for k, s := range r.Header { + r2.Header[k] = append([]string(nil), s...) + } + return r2 +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/certificates.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/certificates.go new file mode 100644 index 000000000..84ddba094 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/certificates.go @@ -0,0 +1,249 @@ +package dnsimple + +import ( + "fmt" +) + +// CertificatesService handles communication with the certificate related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/certificates +type CertificatesService struct { + client *Client +} + +// Certificate represents a Certificate in DNSimple. +type Certificate struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + ContactID int64 `json:"contact_id,omitempty"` + CommonName string `json:"common_name,omitempty"` + AlternateNames []string `json:"alternate_names,omitempty"` + Years int `json:"years,omitempty"` + State string `json:"state,omitempty"` + AuthorityIdentifier string `json:"authority_identifier,omitempty"` + AutoRenew bool `json:"auto_renew"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` + ExpiresOn string `json:"expires_on,omitempty"` + CertificateRequest string `json:"csr,omitempty"` +} + +// CertificateBundle represents a container for all the PEM-encoded X509 certificate entities, +// such as the private key, the server certificate and the intermediate chain. +type CertificateBundle struct { + // CertificateRequest string `json:"csr,omitempty"` + PrivateKey string `json:"private_key,omitempty"` + ServerCertificate string `json:"server,omitempty"` + RootCertificate string `json:"root,omitempty"` + IntermediateCertificates []string `json:"chain,omitempty"` +} + +// CertificatePurchase represents a Certificate Purchase in DNSimple. +type CertificatePurchase struct { + ID int64 `json:"id,omitempty"` + CertificateID int64 `json:"new_certificate_id,omitempty"` + State string `json:"state,omitempty"` + AutoRenew bool `json:"auto_renew,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// CertificateRenewal represents a Certificate Renewal in DNSimple. +type CertificateRenewal struct { + ID int64 `json:"id,omitempty"` + OldCertificateID int64 `json:"old_certificate_id,omitempty"` + NewCertificateID int64 `json:"new_certificate_id,omitempty"` + State string `json:"state,omitempty"` + AutoRenew bool `json:"auto_renew,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// LetsencryptCertificateAttributes is a set of attributes to purchase a Let's Encrypt certificate. +type LetsencryptCertificateAttributes struct { + ContactID int64 `json:"contact_id,omitempty"` + Name string `json:"name,omitempty"` + AutoRenew bool `json:"auto_renew,omitempty"` + AlternateNames []string `json:"alternate_names,omitempty"` +} + +func certificatePath(accountID, domainIdentifier string, certificateID int64) (path string) { + path = fmt.Sprintf("%v/certificates", domainPath(accountID, domainIdentifier)) + if certificateID != 0 { + path += fmt.Sprintf("/%v", certificateID) + } + return +} + +func letsencryptCertificatePath(accountID, domainIdentifier string, certificateID int64) (path string) { + path = fmt.Sprintf("%v/certificates/letsencrypt", domainPath(accountID, domainIdentifier)) + if certificateID != 0 { + path += fmt.Sprintf("/%v", certificateID) + } + return +} + +// certificateResponse represents a response from an API method that returns a Certificate struct. +type certificateResponse struct { + Response + Data *Certificate `json:"data"` +} + +// certificateBundleResponse represents a response from an API method that returns a CertificatBundle struct. +type certificateBundleResponse struct { + Response + Data *CertificateBundle `json:"data"` +} + +// certificatesResponse represents a response from an API method that returns a collection of Certificate struct. +type certificatesResponse struct { + Response + Data []Certificate `json:"data"` +} + +// certificatePurchaseResponse represents a response from an API method that returns a CertificatePurchase struct. +type certificatePurchaseResponse struct { + Response + Data *CertificatePurchase `json:"data"` +} + +// certificateRenewalResponse represents a response from an API method that returns a CertificateRenewal struct. +type certificateRenewalResponse struct { + Response + Data *CertificateRenewal `json:"data"` +} + +// ListCertificates lists the certificates for a domain in the account. +// +// See https://developer.dnsimple.com/v2/certificates#listCertificates +func (s *CertificatesService) ListCertificates(accountID, domainIdentifier string, options *ListOptions) (*certificatesResponse, error) { + path := versioned(certificatePath(accountID, domainIdentifier, 0)) + certificatesResponse := &certificatesResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, certificatesResponse) + if err != nil { + return certificatesResponse, err + } + + certificatesResponse.HttpResponse = resp + return certificatesResponse, nil +} + +// GetCertificate gets the details of a certificate. +// +// See https://developer.dnsimple.com/v2/certificates#getCertificate +func (s *CertificatesService) GetCertificate(accountID, domainIdentifier string, certificateID int64) (*certificateResponse, error) { + path := versioned(certificatePath(accountID, domainIdentifier, certificateID)) + certificateResponse := &certificateResponse{} + + resp, err := s.client.get(path, certificateResponse) + if err != nil { + return nil, err + } + + certificateResponse.HttpResponse = resp + return certificateResponse, nil +} + +// DownloadCertificate gets the PEM-encoded certificate, +// along with the root certificate and intermediate chain. +// +// See https://developer.dnsimple.com/v2/certificates#downloadCertificate +func (s *CertificatesService) DownloadCertificate(accountID, domainIdentifier string, certificateID int64) (*certificateBundleResponse, error) { + path := versioned(certificatePath(accountID, domainIdentifier, certificateID) + "/download") + certificateBundleResponse := &certificateBundleResponse{} + + resp, err := s.client.get(path, certificateBundleResponse) + if err != nil { + return nil, err + } + + certificateBundleResponse.HttpResponse = resp + return certificateBundleResponse, nil +} + +// GetCertificatePrivateKey gets the PEM-encoded certificate private key. +// +// See https://developer.dnsimple.com/v2/certificates#getCertificatePrivateKey +func (s *CertificatesService) GetCertificatePrivateKey(accountID, domainIdentifier string, certificateID int64) (*certificateBundleResponse, error) { + path := versioned(certificatePath(accountID, domainIdentifier, certificateID) + "/private_key") + certificateBundleResponse := &certificateBundleResponse{} + + resp, err := s.client.get(path, certificateBundleResponse) + if err != nil { + return nil, err + } + + certificateBundleResponse.HttpResponse = resp + return certificateBundleResponse, nil +} + +// PurchaseLetsencryptCertificate purchases a Let's Encrypt certificate. +// +// See https://developer.dnsimple.com/v2/certificates/#purchaseLetsencryptCertificate +func (s *CertificatesService) PurchaseLetsencryptCertificate(accountID, domainIdentifier string, certificateAttributes LetsencryptCertificateAttributes) (*certificatePurchaseResponse, error) { + path := versioned(letsencryptCertificatePath(accountID, domainIdentifier, 0)) + certificatePurchaseResponse := &certificatePurchaseResponse{} + + resp, err := s.client.post(path, certificateAttributes, certificatePurchaseResponse) + if err != nil { + return nil, err + } + + certificatePurchaseResponse.HttpResponse = resp + return certificatePurchaseResponse, nil +} + +// IssueLetsencryptCertificate issues a pending Let's Encrypt certificate purchase order. +// +// See https://developer.dnsimple.com/v2/certificates/#issueLetsencryptCertificate +func (s *CertificatesService) IssueLetsencryptCertificate(accountID, domainIdentifier string, certificateID int64) (*certificateResponse, error) { + path := versioned(letsencryptCertificatePath(accountID, domainIdentifier, certificateID) + "/issue") + certificateResponse := &certificateResponse{} + + resp, err := s.client.post(path, nil, certificateResponse) + if err != nil { + return nil, err + } + + certificateResponse.HttpResponse = resp + return certificateResponse, nil +} + +// PurchaseLetsencryptCertificateRenewal purchases a Let's Encrypt certificate renewal. +// +// See https://developer.dnsimple.com/v2/certificates/#purchaseRenewalLetsencryptCertificate +func (s *CertificatesService) PurchaseLetsencryptCertificateRenewal(accountID, domainIdentifier string, certificateID int64, certificateAttributes LetsencryptCertificateAttributes) (*certificateRenewalResponse, error) { + path := versioned(letsencryptCertificatePath(accountID, domainIdentifier, certificateID) + "/renewals") + certificateRenewalResponse := &certificateRenewalResponse{} + + resp, err := s.client.post(path, certificateAttributes, certificateRenewalResponse) + if err != nil { + return nil, err + } + + certificateRenewalResponse.HttpResponse = resp + return certificateRenewalResponse, nil +} + +// IssueLetsencryptCertificateRenewal issues a pending Let's Encrypt certificate renewal order. +// +// See https://developer.dnsimple.com/v2/certificates/#issueRenewalLetsencryptCertificate +func (s *CertificatesService) IssueLetsencryptCertificateRenewal(accountID, domainIdentifier string, certificateID, certificateRenewalID int64) (*certificateResponse, error) { + path := versioned(letsencryptCertificatePath(accountID, domainIdentifier, certificateID) + fmt.Sprintf("/renewals/%d/issue", certificateRenewalID)) + certificateResponse := &certificateResponse{} + + resp, err := s.client.post(path, nil, certificateResponse) + if err != nil { + return nil, err + } + + certificateResponse.HttpResponse = resp + return certificateResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/contacts.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/contacts.go new file mode 100644 index 000000000..d35cffef9 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/contacts.go @@ -0,0 +1,140 @@ +package dnsimple + +import ( + "fmt" +) + +// ContactsService handles communication with the contact related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/contacts/ +type ContactsService struct { + client *Client +} + +// Contact represents a Contact in DNSimple. +type Contact struct { + ID int64 `json:"id,omitempty"` + AccountID int64 `json:"account_id,omitempty"` + Label string `json:"label,omitempty"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` + JobTitle string `json:"job_title,omitempty"` + Organization string `json:"organization_name,omitempty"` + Address1 string `json:"address1,omitempty"` + Address2 string `json:"address2,omitempty"` + City string `json:"city,omitempty"` + StateProvince string `json:"state_province,omitempty"` + PostalCode string `json:"postal_code,omitempty"` + Country string `json:"country,omitempty"` + Phone string `json:"phone,omitempty"` + Fax string `json:"fax,omitempty"` + Email string `json:"email,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func contactPath(accountID string, contactID int64) (path string) { + path = fmt.Sprintf("/%v/contacts", accountID) + if contactID != 0 { + path += fmt.Sprintf("/%v", contactID) + } + return +} + +// contactResponse represents a response from an API method that returns a Contact struct. +type contactResponse struct { + Response + Data *Contact `json:"data"` +} + +// contactsResponse represents a response from an API method that returns a collection of Contact struct. +type contactsResponse struct { + Response + Data []Contact `json:"data"` +} + +// ListContacts list the contacts for an account. +// +// See https://developer.dnsimple.com/v2/contacts/#list +func (s *ContactsService) ListContacts(accountID string, options *ListOptions) (*contactsResponse, error) { + path := versioned(contactPath(accountID, 0)) + contactsResponse := &contactsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, contactsResponse) + if err != nil { + return contactsResponse, err + } + + contactsResponse.HttpResponse = resp + return contactsResponse, nil +} + +// CreateContact creates a new contact. +// +// See https://developer.dnsimple.com/v2/contacts/#create +func (s *ContactsService) CreateContact(accountID string, contactAttributes Contact) (*contactResponse, error) { + path := versioned(contactPath(accountID, 0)) + contactResponse := &contactResponse{} + + resp, err := s.client.post(path, contactAttributes, contactResponse) + if err != nil { + return nil, err + } + + contactResponse.HttpResponse = resp + return contactResponse, nil +} + +// GetContact fetches a contact. +// +// See https://developer.dnsimple.com/v2/contacts/#get +func (s *ContactsService) GetContact(accountID string, contactID int64) (*contactResponse, error) { + path := versioned(contactPath(accountID, contactID)) + contactResponse := &contactResponse{} + + resp, err := s.client.get(path, contactResponse) + if err != nil { + return nil, err + } + + contactResponse.HttpResponse = resp + return contactResponse, nil +} + +// UpdateContact updates a contact. +// +// See https://developer.dnsimple.com/v2/contacts/#update +func (s *ContactsService) UpdateContact(accountID string, contactID int64, contactAttributes Contact) (*contactResponse, error) { + path := versioned(contactPath(accountID, contactID)) + contactResponse := &contactResponse{} + + resp, err := s.client.patch(path, contactAttributes, contactResponse) + if err != nil { + return nil, err + } + + contactResponse.HttpResponse = resp + return contactResponse, nil +} + +// DeleteContact PERMANENTLY deletes a contact from the account. +// +// See https://developer.dnsimple.com/v2/contacts/#delete +func (s *ContactsService) DeleteContact(accountID string, contactID int64) (*contactResponse, error) { + path := versioned(contactPath(accountID, contactID)) + contactResponse := &contactResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + contactResponse.HttpResponse = resp + return contactResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/dnsimple.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/dnsimple.go new file mode 100644 index 000000000..0738aa03a --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/dnsimple.go @@ -0,0 +1,338 @@ +// Package dnsimple provides a client for the DNSimple API. +// In order to use this package you will need a DNSimple account. +package dnsimple + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "net/url" + "reflect" + "strconv" + "strings" + "time" + + "github.com/google/go-querystring/query" +) + +const ( + // Version identifies the current library version. + // This is a pro-forma convention given that Go dependencies + // tends to be fetched directly from the repo. + // It is also used in the user-agent identify the client. + Version = "0.30.0" + + // defaultBaseURL to the DNSimple production API. + defaultBaseURL = "https://api.dnsimple.com" + + // userAgent represents the default user agent used + // when no other user agent is set. + defaultUserAgent = "dnsimple-go/" + Version + + apiVersion = "v2" +) + +// Client represents a client to the DNSimple API. +type Client struct { + // httpClient is the underlying HTTP client + // used to communicate with the API. + httpClient *http.Client + + // BaseURL for API requests. + // Defaults to the public DNSimple API, but can be set to a different endpoint (e.g. the sandbox). + BaseURL string + + // UserAgent used when communicating with the DNSimple API. + UserAgent string + + // Services used for talking to different parts of the DNSimple API. + Identity *IdentityService + Accounts *AccountsService + Certificates *CertificatesService + Contacts *ContactsService + Domains *DomainsService + Oauth *OauthService + Registrar *RegistrarService + Services *ServicesService + Templates *TemplatesService + Tlds *TldsService + VanityNameServers *VanityNameServersService + Webhooks *WebhooksService + Zones *ZonesService + + // Set to true to output debugging logs during API calls + Debug bool +} + +// ListOptions contains the common options you can pass to a List method +// in order to control parameters such as paginations and page number. +type ListOptions struct { + // The page to return + Page int `url:"page,omitempty"` + + // The number of entries to return per page + PerPage int `url:"per_page,omitempty"` + + // The order criteria to sort the results. + // The value is a comma-separated list of field[:direction], + // eg. name | name:desc | name:desc,expiration:desc + Sort string `url:"sort,omitempty"` +} + +// NewClient returns a new DNSimple API client. +// +// To authenticate you must provide an http.Client that will perform authentication +// for you with one of the currently supported mechanisms: OAuth or HTTP Basic. +func NewClient(httpClient *http.Client) *Client { + c := &Client{httpClient: httpClient, BaseURL: defaultBaseURL} + c.Identity = &IdentityService{client: c} + c.Accounts = &AccountsService{client: c} + c.Certificates = &CertificatesService{client: c} + c.Contacts = &ContactsService{client: c} + c.Domains = &DomainsService{client: c} + c.Oauth = &OauthService{client: c} + c.Registrar = &RegistrarService{client: c} + c.Services = &ServicesService{client: c} + c.Templates = &TemplatesService{client: c} + c.Tlds = &TldsService{client: c} + c.VanityNameServers = &VanityNameServersService{client: c} + c.Webhooks = &WebhooksService{client: c} + c.Zones = &ZonesService{client: c} + return c +} + +// NewRequest creates an API request. +// The path is expected to be a relative path and will be resolved +// according to the BaseURL of the Client. Paths should always be specified without a preceding slash. +func (c *Client) NewRequest(method, path string, payload interface{}) (*http.Request, error) { + url := c.BaseURL + path + + body := new(bytes.Buffer) + if payload != nil { + err := json.NewEncoder(body).Encode(payload) + if err != nil { + return nil, err + } + } + + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Add("Accept", "application/json") + req.Header.Add("User-Agent", formatUserAgent(c.UserAgent)) + + return req, nil +} + +// formatUserAgent builds the final user agent to use for HTTP requests. +// +// If no custom user agent is provided, the default user agent is used. +// +// dnsimple-go/1.0 +// +// If a custom user agent is provided, the final user agent is the combination of the custom user agent +// prepended by the default user agent. +// +// dnsimple-go/1.0 customAgentFlag +// +func formatUserAgent(customUserAgent string) string { + if customUserAgent == "" { + return defaultUserAgent + } + + return fmt.Sprintf("%s %s", defaultUserAgent, customUserAgent) +} + +func versioned(path string) string { + return fmt.Sprintf("/%s/%s", apiVersion, strings.Trim(path, "/")) +} + +func (c *Client) get(path string, obj interface{}) (*http.Response, error) { + req, err := c.NewRequest("GET", path, nil) + if err != nil { + return nil, err + } + + return c.Do(req, obj) +} + +func (c *Client) post(path string, payload, obj interface{}) (*http.Response, error) { + req, err := c.NewRequest("POST", path, payload) + if err != nil { + return nil, err + } + + return c.Do(req, obj) +} + +func (c *Client) put(path string, payload, obj interface{}) (*http.Response, error) { + req, err := c.NewRequest("PUT", path, payload) + if err != nil { + return nil, err + } + + return c.Do(req, obj) +} + +func (c *Client) patch(path string, payload, obj interface{}) (*http.Response, error) { + req, err := c.NewRequest("PATCH", path, payload) + if err != nil { + return nil, err + } + + return c.Do(req, obj) +} + +func (c *Client) delete(path string, payload interface{}, obj interface{}) (*http.Response, error) { + req, err := c.NewRequest("DELETE", path, payload) + if err != nil { + return nil, err + } + + return c.Do(req, obj) +} + +// Do sends an API request and returns the API response. +// +// The API response is JSON decoded and stored in the value pointed by obj, +// or returned as an error if an API error has occurred. +// If obj implements the io.Writer interface, the raw response body will be written to obj, +// without attempting to decode it. +func (c *Client) Do(req *http.Request, obj interface{}) (*http.Response, error) { + if c.Debug { + log.Printf("Executing request (%v): %#v", req.URL, req) + } + + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if c.Debug { + log.Printf("Response received: %#v", resp) + } + + err = CheckResponse(resp) + if err != nil { + return resp, err + } + + // If obj implements the io.Writer, + // the response body is decoded into v. + if obj != nil { + if w, ok := obj.(io.Writer); ok { + _, err = io.Copy(w, resp.Body) + } else { + err = json.NewDecoder(resp.Body).Decode(obj) + } + } + + return resp, err +} + +// A Response represents an API response. +type Response struct { + // HTTP response + HttpResponse *http.Response + + // If the response is paginated, the Pagination will store them. + Pagination *Pagination `json:"pagination"` +} + +// RateLimit returns the maximum amount of requests this account can send in an hour. +func (r *Response) RateLimit() int { + value, _ := strconv.Atoi(r.HttpResponse.Header.Get("X-RateLimit-Limit")) + return value +} + +// RateLimitRemaining returns the remaining amount of requests this account can send within this hour window. +func (r *Response) RateLimitRemaining() int { + value, _ := strconv.Atoi(r.HttpResponse.Header.Get("X-RateLimit-Remaining")) + return value +} + +// RateLimitReset returns when the throttling window will be reset for this account. +func (r *Response) RateLimitReset() time.Time { + value, _ := strconv.ParseInt(r.HttpResponse.Header.Get("X-RateLimit-Reset"), 10, 64) + return time.Unix(value, 0) +} + +// If the response is paginated, Pagination represents the pagination information. +type Pagination struct { + CurrentPage int `json:"current_page"` + PerPage int `json:"per_page"` + TotalPages int `json:"total_pages"` + TotalEntries int `json:"total_entries"` +} + +// An ErrorResponse represents an API response that generated an error. +type ErrorResponse struct { + Response + + // human-readable message + Message string `json:"message"` +} + +// Error implements the error interface. +func (r *ErrorResponse) Error() string { + return fmt.Sprintf("%v %v: %v %v", + r.HttpResponse.Request.Method, r.HttpResponse.Request.URL, + r.HttpResponse.StatusCode, r.Message) +} + +// CheckResponse checks the API response for errors, and returns them if present. +// A response is considered an error if the status code is different than 2xx. Specific requests +// may have additional requirements, but this is sufficient in most of the cases. +func CheckResponse(resp *http.Response) error { + if code := resp.StatusCode; 200 <= code && code <= 299 { + return nil + } + + errorResponse := &ErrorResponse{} + errorResponse.HttpResponse = resp + + err := json.NewDecoder(resp.Body).Decode(errorResponse) + if err != nil { + return err + } + + return errorResponse +} + +// addOptions adds the parameters in opt as URL query parameters to s. opt +// must be a struct whose fields may contain "url" tags. +func addURLQueryOptions(path string, options interface{}) (string, error) { + opt := reflect.ValueOf(options) + + // options is a pointer + // return if the value of the pointer is nil, + if opt.Kind() == reflect.Ptr && opt.IsNil() { + return path, nil + } + + // append the options to the URL + u, err := url.Parse(path) + if err != nil { + return path, err + } + + qs, err := query.Values(options) + if err != nil { + return path, err + } + + uqs := u.Query() + for k, _ := range qs { + uqs.Set(k, qs.Get(k)) + } + u.RawQuery = uqs.Encode() + + return u.String(), nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains.go new file mode 100644 index 000000000..8ca687144 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains.go @@ -0,0 +1,138 @@ +package dnsimple + +import ( + "fmt" +) + +// DomainsService handles communication with the domain related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/domains/ +type DomainsService struct { + client *Client +} + +// Domain represents a domain in DNSimple. +type Domain struct { + ID int64 `json:"id,omitempty"` + AccountID int64 `json:"account_id,omitempty"` + RegistrantID int64 `json:"registrant_id,omitempty"` + Name string `json:"name,omitempty"` + UnicodeName string `json:"unicode_name,omitempty"` + Token string `json:"token,omitempty"` + State string `json:"state,omitempty"` + AutoRenew bool `json:"auto_renew,omitempty"` + PrivateWhois bool `json:"private_whois,omitempty"` + ExpiresOn string `json:"expires_on,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func domainPath(accountID string, domainIdentifier string) (path string) { + path = fmt.Sprintf("/%v/domains", accountID) + if domainIdentifier != "" { + path += fmt.Sprintf("/%v", domainIdentifier) + } + return +} + +// domainResponse represents a response from an API method that returns a Domain struct. +type domainResponse struct { + Response + Data *Domain `json:"data"` +} + +// domainsResponse represents a response from an API method that returns a collection of Domain struct. +type domainsResponse struct { + Response + Data []Domain `json:"data"` +} + +// DomainListOptions specifies the optional parameters you can provide +// to customize the DomainsService.ListDomains method. +type DomainListOptions struct { + // Select domains where the name contains given string. + NameLike string `url:"name_like,omitempty"` + + // Select domains where the registrant matches given ID. + RegistrantID int `url:"registrant_id,omitempty"` + + ListOptions +} + +// ListDomains lists the domains for an account. +// +// See https://developer.dnsimple.com/v2/domains/#list +func (s *DomainsService) ListDomains(accountID string, options *DomainListOptions) (*domainsResponse, error) { + path := versioned(domainPath(accountID, "")) + domainsResponse := &domainsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, domainsResponse) + if err != nil { + return nil, err + } + + domainsResponse.HttpResponse = resp + return domainsResponse, nil +} + +// CreateDomain creates a new domain in the account. +// +// See https://developer.dnsimple.com/v2/domains/#create +func (s *DomainsService) CreateDomain(accountID string, domainAttributes Domain) (*domainResponse, error) { + path := versioned(domainPath(accountID, "")) + domainResponse := &domainResponse{} + + resp, err := s.client.post(path, domainAttributes, domainResponse) + if err != nil { + return nil, err + } + + domainResponse.HttpResponse = resp + return domainResponse, nil +} + +// GetDomain fetches a domain. +// +// See https://developer.dnsimple.com/v2/domains/#get +func (s *DomainsService) GetDomain(accountID string, domainIdentifier string) (*domainResponse, error) { + path := versioned(domainPath(accountID, domainIdentifier)) + domainResponse := &domainResponse{} + + resp, err := s.client.get(path, domainResponse) + if err != nil { + return nil, err + } + + domainResponse.HttpResponse = resp + return domainResponse, nil +} + +// DeleteDomain PERMANENTLY deletes a domain from the account. +// +// See https://developer.dnsimple.com/v2/domains/#delete +func (s *DomainsService) DeleteDomain(accountID string, domainIdentifier string) (*domainResponse, error) { + path := versioned(domainPath(accountID, domainIdentifier)) + domainResponse := &domainResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + domainResponse.HttpResponse = resp + return domainResponse, nil +} + +// DEPRECATED +// +// See https://developer.dnsimple.com/v2/domains/#reset-token +func (s *DomainsService) ResetDomainToken(accountID string, domainIdentifier string) (*domainResponse, error) { + // noop + return &domainResponse{}, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_collaborators.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_collaborators.go new file mode 100644 index 000000000..da0513996 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_collaborators.go @@ -0,0 +1,96 @@ +package dnsimple + +import ( + "fmt" +) + +// Collaborator represents a Collaborator in DNSimple. +type Collaborator struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + DomainName string `json:"domain_name,omitempty"` + UserID int64 `json:"user_id,omitempty"` + UserEmail string `json:"user_email,omitempty"` + Invitation bool `json:"invitation,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` + AcceptedAt string `json:"accepted_at,omitempty"` +} + +func collaboratorPath(accountID, domainIdentifier string, collaboratorID int64) (path string) { + path = fmt.Sprintf("%v/collaborators", domainPath(accountID, domainIdentifier)) + if collaboratorID != 0 { + path += fmt.Sprintf("/%v", collaboratorID) + } + return +} + +// CollaboratorAttributes represents Collaborator attributes for AddCollaborator operation. +type CollaboratorAttributes struct { + Email string `json:"email,omitempty"` +} + +// collaboratorResponse represents a response from an API method that returns a Collaborator struct. +type collaboratorResponse struct { + Response + Data *Collaborator `json:"data"` +} + +// collaboratorsResponse represents a response from an API method that returns a collection of Collaborator struct. +type collaboratorsResponse struct { + Response + Data []Collaborator `json:"data"` +} + +// ListCollaborators list the collaborators for a domain. +// +// See https://developer.dnsimple.com/v2/domains/collaborators#list +func (s *DomainsService) ListCollaborators(accountID, domainIdentifier string, options *ListOptions) (*collaboratorsResponse, error) { + path := versioned(collaboratorPath(accountID, domainIdentifier, 0)) + collaboratorsResponse := &collaboratorsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, collaboratorsResponse) + if err != nil { + return collaboratorsResponse, err + } + + collaboratorsResponse.HttpResponse = resp + return collaboratorsResponse, nil +} + +// AddCollaborator adds a new collaborator to the domain in the account. +// +// See https://developer.dnsimple.com/v2/domains/collaborators#add +func (s *DomainsService) AddCollaborator(accountID string, domainIdentifier string, attributes CollaboratorAttributes) (*collaboratorResponse, error) { + path := versioned(collaboratorPath(accountID, domainIdentifier, 0)) + collaboratorResponse := &collaboratorResponse{} + + resp, err := s.client.post(path, attributes, collaboratorResponse) + if err != nil { + return nil, err + } + + collaboratorResponse.HttpResponse = resp + return collaboratorResponse, nil +} + +// RemoveCollaborator PERMANENTLY deletes a domain from the account. +// +// See https://developer.dnsimple.com/v2/domains/collaborators#remove +func (s *DomainsService) RemoveCollaborator(accountID string, domainIdentifier string, collaboratorID int64) (*collaboratorResponse, error) { + path := versioned(collaboratorPath(accountID, domainIdentifier, collaboratorID)) + collaboratorResponse := &collaboratorResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + collaboratorResponse.HttpResponse = resp + return collaboratorResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_delegation_signer_records.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_delegation_signer_records.go new file mode 100644 index 000000000..f2f0092de --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_delegation_signer_records.go @@ -0,0 +1,105 @@ +package dnsimple + +import "fmt" + +// DelegationSignerRecord represents a delegation signer record for a domain in DNSimple. +type DelegationSignerRecord struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + Algorithm string `json:"algorithm"` + Digest string `json:"digest"` + DigestType string `json:"digest_type"` + Keytag string `json:"keytag"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func delegationSignerRecordPath(accountID string, domainIdentifier string, dsRecordID int64) (path string) { + path = fmt.Sprintf("%v/ds_records", domainPath(accountID, domainIdentifier)) + if dsRecordID != 0 { + path += fmt.Sprintf("/%v", dsRecordID) + } + return +} + +// delegationSignerRecordResponse represents a response from an API method that returns a DelegationSignerRecord struct. +type delegationSignerRecordResponse struct { + Response + Data *DelegationSignerRecord `json:"data"` +} + +// delegationSignerRecordResponse represents a response from an API method that returns a DelegationSignerRecord struct. +type delegationSignerRecordsResponse struct { + Response + Data []DelegationSignerRecord `json:"data"` +} + +// ListDelegationSignerRecords lists the delegation signer records for a domain. +// +// See https://developer.dnsimple.com/v2/domains/dnssec/#ds-record-list +func (s *DomainsService) ListDelegationSignerRecords(accountID string, domainIdentifier string, options *ListOptions) (*delegationSignerRecordsResponse, error) { + path := versioned(delegationSignerRecordPath(accountID, domainIdentifier, 0)) + dsRecordsResponse := &delegationSignerRecordsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, dsRecordsResponse) + if err != nil { + return nil, err + } + + dsRecordsResponse.HttpResponse = resp + return dsRecordsResponse, nil +} + +// CreateDelegationSignerRecord creates a new delegation signer record. +// +// See https://developer.dnsimple.com/v2/domains/dnssec/#ds-record-create +func (s *DomainsService) CreateDelegationSignerRecord(accountID string, domainIdentifier string, dsRecordAttributes DelegationSignerRecord) (*delegationSignerRecordResponse, error) { + path := versioned(delegationSignerRecordPath(accountID, domainIdentifier, 0)) + dsRecordResponse := &delegationSignerRecordResponse{} + + resp, err := s.client.post(path, dsRecordAttributes, dsRecordResponse) + if err != nil { + return nil, err + } + + dsRecordResponse.HttpResponse = resp + return dsRecordResponse, nil +} + +// GetDelegationSignerRecord fetches a delegation signer record. +// +// See https://developer.dnsimple.com/v2/domains/dnssec/#ds-record-get +func (s *DomainsService) GetDelegationSignerRecord(accountID string, domainIdentifier string, dsRecordID int64) (*delegationSignerRecordResponse, error) { + path := versioned(delegationSignerRecordPath(accountID, domainIdentifier, dsRecordID)) + dsRecordResponse := &delegationSignerRecordResponse{} + + resp, err := s.client.get(path, dsRecordResponse) + if err != nil { + return nil, err + } + + dsRecordResponse.HttpResponse = resp + return dsRecordResponse, nil +} + +// DeleteDelegationSignerRecord PERMANENTLY deletes a delegation signer record +// from the domain. +// +// See https://developer.dnsimple.com/v2/domains/dnssec/#ds-record-delete +func (s *DomainsService) DeleteDelegationSignerRecord(accountID string, domainIdentifier string, dsRecordID int64) (*delegationSignerRecordResponse, error) { + path := versioned(delegationSignerRecordPath(accountID, domainIdentifier, dsRecordID)) + dsRecordResponse := &delegationSignerRecordResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + dsRecordResponse.HttpResponse = resp + return dsRecordResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_dnssec.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_dnssec.go new file mode 100644 index 000000000..1ef054bcc --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_dnssec.go @@ -0,0 +1,70 @@ +package dnsimple + +import ( + "fmt" +) + +// Dnssec represents the current DNSSEC settings for a domain in DNSimple. +type Dnssec struct { + Enabled bool `json:"enabled"` +} + +func dnssecPath(accountID string, domainIdentifier string) (path string) { + path = fmt.Sprintf("%v/dnssec", domainPath(accountID, domainIdentifier)) + return +} + +// dnssecResponse represents a response from an API method that returns a Dnssec struct. +type dnssecResponse struct { + Response + Data *Dnssec `json:"data"` +} + +// EnableDnssec enables DNSSEC on the domain. +// +// See https://developer.dnsimple.com/v2/domains/dnssec/#enable + +func (s *DomainsService) EnableDnssec(accountID string, domainIdentifier string) (*dnssecResponse, error) { + path := versioned(dnssecPath(accountID, domainIdentifier)) + dnssecResponse := &dnssecResponse{} + + resp, err := s.client.post(path, dnssecResponse, nil) + if err != nil { + return nil, err + } + + dnssecResponse.HttpResponse = resp + return dnssecResponse, nil +} + +// DisableDnssec disables DNSSEC on the domain. +// +// See https://developer.dnsimple.com/v2/domains/dnssec/#disable +func (s *DomainsService) DisableDnssec(accountID string, domainIdentifier string) (*dnssecResponse, error) { + path := versioned(dnssecPath(accountID, domainIdentifier)) + dnssecResponse := &dnssecResponse{} + + resp, err := s.client.delete(path, dnssecResponse, nil) + if err != nil { + return nil, err + } + + dnssecResponse.HttpResponse = resp + return dnssecResponse, nil +} + +// GetDnssec retrieves the current status of DNSSEC on the domain. +// +// See https://developer.dnsimple.com/v2/domains/dnssec/#get +func (s *DomainsService) GetDnssec(accountID string, domainIdentifier string) (*dnssecResponse, error) { + path := versioned(dnssecPath(accountID, domainIdentifier)) + dnssecResponse := &dnssecResponse{} + + resp, err := s.client.get(path, dnssecResponse) + if err != nil { + return nil, err + } + + dnssecResponse.HttpResponse = resp + return dnssecResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_email_forwards.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_email_forwards.go new file mode 100644 index 000000000..3d4299ac5 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_email_forwards.go @@ -0,0 +1,104 @@ +package dnsimple + +import ( + "fmt" +) + +// EmailForward represents an email forward in DNSimple. +type EmailForward struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + From string `json:"from,omitempty"` + To string `json:"to,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func emailForwardPath(accountID string, domainIdentifier string, forwardID int64) (path string) { + path = fmt.Sprintf("%v/email_forwards", domainPath(accountID, domainIdentifier)) + if forwardID != 0 { + path += fmt.Sprintf("/%v", forwardID) + } + return +} + +// emailForwardResponse represents a response from an API method that returns an EmailForward struct. +type emailForwardResponse struct { + Response + Data *EmailForward `json:"data"` +} + +// emailForwardsResponse represents a response from an API method that returns a collection of EmailForward struct. +type emailForwardsResponse struct { + Response + Data []EmailForward `json:"data"` +} + +// ListEmailForwards lists the email forwards for a domain. +// +// See https://developer.dnsimple.com/v2/domains/email-forwards/#list +func (s *DomainsService) ListEmailForwards(accountID string, domainIdentifier string, options *ListOptions) (*emailForwardsResponse, error) { + path := versioned(emailForwardPath(accountID, domainIdentifier, 0)) + forwardsResponse := &emailForwardsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, forwardsResponse) + if err != nil { + return nil, err + } + + forwardsResponse.HttpResponse = resp + return forwardsResponse, nil +} + +// CreateEmailForward creates a new email forward. +// +// See https://developer.dnsimple.com/v2/domains/email-forwards/#create +func (s *DomainsService) CreateEmailForward(accountID string, domainIdentifier string, forwardAttributes EmailForward) (*emailForwardResponse, error) { + path := versioned(emailForwardPath(accountID, domainIdentifier, 0)) + forwardResponse := &emailForwardResponse{} + + resp, err := s.client.post(path, forwardAttributes, forwardResponse) + if err != nil { + return nil, err + } + + forwardResponse.HttpResponse = resp + return forwardResponse, nil +} + +// GetEmailForward fetches an email forward. +// +// See https://developer.dnsimple.com/v2/domains/email-forwards/#get +func (s *DomainsService) GetEmailForward(accountID string, domainIdentifier string, forwardID int64) (*emailForwardResponse, error) { + path := versioned(emailForwardPath(accountID, domainIdentifier, forwardID)) + forwardResponse := &emailForwardResponse{} + + resp, err := s.client.get(path, forwardResponse) + if err != nil { + return nil, err + } + + forwardResponse.HttpResponse = resp + return forwardResponse, nil +} + +// DeleteEmailForward PERMANENTLY deletes an email forward from the domain. +// +// See https://developer.dnsimple.com/v2/domains/email-forwards/#delete +func (s *DomainsService) DeleteEmailForward(accountID string, domainIdentifier string, forwardID int64) (*emailForwardResponse, error) { + path := versioned(emailForwardPath(accountID, domainIdentifier, forwardID)) + forwardResponse := &emailForwardResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + forwardResponse.HttpResponse = resp + return forwardResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_pushes.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_pushes.go new file mode 100644 index 000000000..b965c7daf --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/domains_pushes.go @@ -0,0 +1,111 @@ +package dnsimple + +import ( + "fmt" +) + +// DomainPush represents a domain push in DNSimple. +type DomainPush struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + ContactID int64 `json:"contact_id,omitempty"` + AccountID int64 `json:"account_id,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` + AcceptedAt string `json:"accepted_at,omitempty"` +} + +func domainPushPath(accountID string, pushID int64) (path string) { + path = fmt.Sprintf("/%v/pushes", accountID) + if pushID != 0 { + path += fmt.Sprintf("/%v", pushID) + } + return +} + +// domainPushResponse represents a response from an API method that returns a DomainPush struct. +type domainPushResponse struct { + Response + Data *DomainPush `json:"data"` +} + +// domainPushesResponse represents a response from an API method that returns a collection of DomainPush struct. +type domainPushesResponse struct { + Response + Data []DomainPush `json:"data"` +} + +// DomainPushAttributes represent a domain push payload (see initiate). +type DomainPushAttributes struct { + NewAccountEmail string `json:"new_account_email,omitempty"` + ContactID int64 `json:"contact_id,omitempty"` +} + +// InitiatePush initiate a new domain push. +// +// See https://developer.dnsimple.com/v2/domains/pushes/#initiate +func (s *DomainsService) InitiatePush(accountID, domainID string, pushAttributes DomainPushAttributes) (*domainPushResponse, error) { + path := versioned(fmt.Sprintf("/%v/pushes", domainPath(accountID, domainID))) + pushResponse := &domainPushResponse{} + + resp, err := s.client.post(path, pushAttributes, pushResponse) + if err != nil { + return nil, err + } + + pushResponse.HttpResponse = resp + return pushResponse, nil +} + +// ListPushes lists the pushes for an account. +// +// See https://developer.dnsimple.com/v2/domains/pushes/#list +func (s *DomainsService) ListPushes(accountID string, options *ListOptions) (*domainPushesResponse, error) { + path := versioned(domainPushPath(accountID, 0)) + pushesResponse := &domainPushesResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, pushesResponse) + if err != nil { + return nil, err + } + + pushesResponse.HttpResponse = resp + return pushesResponse, nil +} + +// AcceptPush accept a push for a domain. +// +// See https://developer.dnsimple.com/v2/domains/pushes/#accept +func (s *DomainsService) AcceptPush(accountID string, pushID int64, pushAttributes DomainPushAttributes) (*domainPushResponse, error) { + path := versioned(domainPushPath(accountID, pushID)) + pushResponse := &domainPushResponse{} + + resp, err := s.client.post(path, pushAttributes, nil) + if err != nil { + return nil, err + } + + pushResponse.HttpResponse = resp + return pushResponse, nil +} + +// RejectPush reject a push for a domain. +// +// See https://developer.dnsimple.com/v2/domains/pushes/#reject +func (s *DomainsService) RejectPush(accountID string, pushID int64) (*domainPushResponse, error) { + path := versioned(domainPushPath(accountID, pushID)) + pushResponse := &domainPushResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + pushResponse.HttpResponse = resp + return pushResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/identity.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/identity.go new file mode 100644 index 000000000..be7ca9ea8 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/identity.go @@ -0,0 +1,48 @@ +package dnsimple + +// IdentityService handles communication with several authentication identity +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/identity/ +type IdentityService struct { + client *Client +} + +// WhoamiData represents an authenticated context +// that contains information about the current logged User and/or Account. +type WhoamiData struct { + User *User `json:"user,omitempty"` + Account *Account `json:"account,omitempty"` +} + +// whoamiResponse represents a response from an API method that returns a Whoami struct. +type whoamiResponse struct { + Response + Data *WhoamiData `json:"data"` +} + +// Whoami gets the current authenticate context. +// +// See https://developer.dnsimple.com/v2/whoami +func (s *IdentityService) Whoami() (*whoamiResponse, error) { + path := versioned("/whoami") + whoamiResponse := &whoamiResponse{} + + resp, err := s.client.get(path, whoamiResponse) + if err != nil { + return nil, err + } + + whoamiResponse.HttpResponse = resp + return whoamiResponse, nil +} + +// Whoami is a state-less shortcut to client.Whoami() +// that returns only the relevant Data. +func Whoami(c *Client) (data *WhoamiData, err error) { + resp, err := c.Identity.Whoami() + if resp != nil { + data = resp.Data + } + return +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/oauth.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/oauth.go new file mode 100644 index 000000000..74a2b34a2 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/oauth.go @@ -0,0 +1,113 @@ +package dnsimple + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + "strings" +) + +// GrantType is a string that identifies a particular grant type in the exchange request. +type GrantType string + +const ( + // AuthorizationCodeGrant is the type of access token request + // for an Authorization Code Grant flow. + // https://tools.ietf.org/html/rfc6749#section-4.1 + AuthorizationCodeGrant = GrantType("authorization_code") +) + +// OauthService handles communication with the authorization related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/oauth/ +type OauthService struct { + client *Client +} + +// AccessToken represents a DNSimple Oauth access token. +type AccessToken struct { + Token string `json:"access_token"` + Type string `json:"token_type"` + AccountID int `json:"account_id"` +} + +// ExchangeAuthorizationRequest represents a request to exchange +// an authorization code for an access token. +// RedirectURI is optional, all the other fields are mandatory. +type ExchangeAuthorizationRequest struct { + Code string `json:"code"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RedirectURI string `json:"redirect_uri,omitempty"` + State string `json:"state,omitempty"` + GrantType GrantType `json:"grant_type,omitempty"` +} + +// ExchangeAuthorizationError represents a failed request to exchange +// an authorization code for an access token. +type ExchangeAuthorizationError struct { + // HTTP response + HttpResponse *http.Response + + ErrorCode string `json:"error"` + ErrorDescription string `json:"error_description"` +} + +// Error implements the error interface. +func (r *ExchangeAuthorizationError) Error() string { + return fmt.Sprintf("%v %v: %v %v", + r.HttpResponse.Request.Method, r.HttpResponse.Request.URL, + r.ErrorCode, r.ErrorDescription) +} + +// ExchangeAuthorizationForToken exchanges the short-lived authorization code for an access token +// you can use to authenticate your API calls. +func (s *OauthService) ExchangeAuthorizationForToken(authorization *ExchangeAuthorizationRequest) (*AccessToken, error) { + path := versioned("/oauth/access_token") + + req, err := s.client.NewRequest("POST", path, authorization) + if err != nil { + return nil, err + } + + resp, err := s.client.httpClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + errorResponse := &ExchangeAuthorizationError{} + errorResponse.HttpResponse = resp + json.NewDecoder(resp.Body).Decode(errorResponse) + return nil, errorResponse + } + + accessToken := &AccessToken{} + err = json.NewDecoder(resp.Body).Decode(accessToken) + + return accessToken, err +} + +// AuthorizationOptions represents the option you can use to generate an authorization URL. +type AuthorizationOptions struct { + RedirectURI string `url:"redirect_uri,omitempty"` + // A randomly generated string to verify the validity of the request. + // Currently "state" is required by the DNSimple OAuth implementation, so you must specify it. + State string `url:"state,omitempty"` +} + +// AuthorizeURL generates the URL to authorize an user for an application via the OAuth2 flow. +func (s *OauthService) AuthorizeURL(clientID string, options *AuthorizationOptions) string { + uri, _ := url.Parse(strings.Replace(s.client.BaseURL, "api.", "", 1)) + uri.Path = "/oauth/authorize" + query := uri.Query() + query.Add("client_id", clientID) + query.Add("response_type", "code") + uri.RawQuery = query.Encode() + + path, _ := addURLQueryOptions(uri.String(), options) + return path +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar.go new file mode 100644 index 000000000..1013bd607 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar.go @@ -0,0 +1,261 @@ +package dnsimple + +import ( + "fmt" +) + +// RegistrarService handles communication with the registrar related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/registrar/ +type RegistrarService struct { + client *Client +} + +// DomainCheck represents the result of a domain check. +type DomainCheck struct { + Domain string `json:"domain"` + Available bool `json:"available"` + Premium bool `json:"premium"` +} + +// domainCheckResponse represents a response from a domain check request. +type domainCheckResponse struct { + Response + Data *DomainCheck `json:"data"` +} + +// CheckDomain checks a domain name. +// +// See https://developer.dnsimple.com/v2/registrar/#check +func (s *RegistrarService) CheckDomain(accountID string, domainName string) (*domainCheckResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/check", accountID, domainName)) + checkResponse := &domainCheckResponse{} + + resp, err := s.client.get(path, checkResponse) + if err != nil { + return nil, err + } + + checkResponse.HttpResponse = resp + return checkResponse, nil +} + +// DomainPremiumPrice represents the premium price for a premium domain. +type DomainPremiumPrice struct { + // The domain premium price + PremiumPrice string `json:"premium_price"` + // The registrar action. + // Possible values are registration|transfer|renewal + Action string `json:"action"` +} + +// domainPremiumPriceResponse represents a response from a domain premium price request. +type domainPremiumPriceResponse struct { + Response + Data *DomainPremiumPrice `json:"data"` +} + +// DomainPremiumPriceOptions specifies the optional parameters you can provide +// to customize the RegistrarService.GetDomainPremiumPrice method. +type DomainPremiumPriceOptions struct { + Action string `url:"action,omitempty"` +} + +// GetDomainPremiumPrice gets the premium price for a domain. +// +// You must specify an action to get the price for. Valid actions are: +// - registration +// - transfer +// - renewal +// +// See https://developer.dnsimple.com/v2/registrar/#premium-price +func (s *RegistrarService) GetDomainPremiumPrice(accountID string, domainName string, options *DomainPremiumPriceOptions) (*domainPremiumPriceResponse, error) { + var err error + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/premium_price", accountID, domainName)) + priceResponse := &domainPremiumPriceResponse{} + + if options != nil { + path, err = addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + } + + resp, err := s.client.get(path, priceResponse) + if err != nil { + return nil, err + } + + priceResponse.HttpResponse = resp + return priceResponse, nil +} + +// DomainRegistration represents the result of a domain renewal call. +type DomainRegistration struct { + ID int `json:"id"` + DomainID int `json:"domain_id"` + RegistrantID int `json:"registrant_id"` + Period int `json:"period"` + State string `json:"state"` + AutoRenew bool `json:"auto_renew"` + WhoisPrivacy bool `json:"whois_privacy"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// domainRegistrationResponse represents a response from an API method that results in a domain registration. +type domainRegistrationResponse struct { + Response + Data *DomainRegistration `json:"data"` +} + +// DomainRegisterRequest represents the attributes you can pass to a register API request. +// Some attributes are mandatory. +type DomainRegisterRequest struct { + // The ID of the Contact to use as registrant for the domain + RegistrantID int `json:"registrant_id"` + // Set to true to enable the whois privacy service. An extra cost may apply. + // Default to false. + EnableWhoisPrivacy bool `json:"whois_privacy,omitempty"` + // Set to true to enable the auto-renewal of the domain. + // Default to true. + EnableAutoRenewal bool `json:"auto_renew,omitempty"` + // Required as confirmation of the price, only if the domain is premium. + PremiumPrice string `json:"premium_price,omitempty"` +} + +// RegisterDomain registers a domain name. +// +// See https://developer.dnsimple.com/v2/registrar/#register +func (s *RegistrarService) RegisterDomain(accountID string, domainName string, request *DomainRegisterRequest) (*domainRegistrationResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/registrations", accountID, domainName)) + registrationResponse := &domainRegistrationResponse{} + + // TODO: validate mandatory attributes RegistrantID + + resp, err := s.client.post(path, request, registrationResponse) + if err != nil { + return nil, err + } + + registrationResponse.HttpResponse = resp + return registrationResponse, nil +} + +// DomainTransfer represents the result of a domain renewal call. +type DomainTransfer struct { + ID int `json:"id"` + DomainID int `json:"domain_id"` + RegistrantID int `json:"registrant_id"` + State string `json:"state"` + AutoRenew bool `json:"auto_renew"` + WhoisPrivacy bool `json:"whois_privacy"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// domainTransferResponse represents a response from an API method that results in a domain transfer. +type domainTransferResponse struct { + Response + Data *DomainTransfer `json:"data"` +} + +// DomainTransferRequest represents the attributes you can pass to a transfer API request. +// Some attributes are mandatory. +type DomainTransferRequest struct { + // The ID of the Contact to use as registrant for the domain + RegistrantID int `json:"registrant_id"` + // The Auth-Code required to transfer the domain. + // This is provided by the current registrar of the domain. + AuthCode string `json:"auth_code,omitempty"` + // Set to true to enable the whois privacy service. An extra cost may apply. + // Default to false. + EnableWhoisPrivacy bool `json:"whois_privacy,omitempty"` + // Set to true to enable the auto-renewal of the domain. + // Default to true. + EnableAutoRenewal bool `json:"auto_renew,omitempty"` + // Required as confirmation of the price, only if the domain is premium. + PremiumPrice string `json:"premium_price,omitempty"` +} + +// TransferDomain transfers a domain name. +// +// See https://developer.dnsimple.com/v2/registrar/#transfer +func (s *RegistrarService) TransferDomain(accountID string, domainName string, request *DomainTransferRequest) (*domainTransferResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/transfers", accountID, domainName)) + transferResponse := &domainTransferResponse{} + + // TODO: validate mandatory attributes RegistrantID + + resp, err := s.client.post(path, request, transferResponse) + if err != nil { + return nil, err + } + + transferResponse.HttpResponse = resp + return transferResponse, nil +} + +// domainTransferOutResponse represents a response from an API method that results in a domain transfer out. +type domainTransferOutResponse struct { + Response + Data *Domain `json:"data"` +} + +// Transfer out a domain name. +// +// See https://developer.dnsimple.com/v2/registrar/#transfer-out +func (s *RegistrarService) TransferDomainOut(accountID string, domainName string) (*domainTransferOutResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/authorize_transfer_out", accountID, domainName)) + transferResponse := &domainTransferOutResponse{} + + resp, err := s.client.post(path, nil, nil) + if err != nil { + return nil, err + } + + transferResponse.HttpResponse = resp + return transferResponse, nil +} + +// DomainRenewal represents the result of a domain renewal call. +type DomainRenewal struct { + ID int `json:"id"` + DomainID int `json:"domain_id"` + Period int `json:"period"` + State string `json:"state"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// domainRenewalResponse represents a response from an API method that returns a domain renewal. +type domainRenewalResponse struct { + Response + Data *DomainRenewal `json:"data"` +} + +// DomainRenewRequest represents the attributes you can pass to a renew API request. +// Some attributes are mandatory. +type DomainRenewRequest struct { + // The number of years + Period int `json:"period"` + // Required as confirmation of the price, only if the domain is premium. + PremiumPrice string `json:"premium_price,omitempty"` +} + +// RenewDomain renews a domain name. +// +// See https://developer.dnsimple.com/v2/registrar/#register +func (s *RegistrarService) RenewDomain(accountID string, domainName string, request *DomainRenewRequest) (*domainRenewalResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/renewals", accountID, domainName)) + renewalResponse := &domainRenewalResponse{} + + resp, err := s.client.post(path, request, renewalResponse) + if err != nil { + return nil, err + } + + renewalResponse.HttpResponse = resp + return renewalResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_auto_renewal.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_auto_renewal.go new file mode 100644 index 000000000..c98f8d5cd --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_auto_renewal.go @@ -0,0 +1,37 @@ +package dnsimple + +import ( + "fmt" +) + +// EnableDomainAutoRenewal enables auto-renewal for the domain. +// +// See https://developer.dnsimple.com/v2/registrar/auto-renewal/#enable +func (s *RegistrarService) EnableDomainAutoRenewal(accountID string, domainName string) (*domainResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/auto_renewal", accountID, domainName)) + domainResponse := &domainResponse{} + + resp, err := s.client.put(path, nil, nil) + if err != nil { + return nil, err + } + + domainResponse.HttpResponse = resp + return domainResponse, nil +} + +// DisableDomainAutoRenewal disables auto-renewal for the domain. +// +// See https://developer.dnsimple.com/v2/registrar/auto-renewal/#enable +func (s *RegistrarService) DisableDomainAutoRenewal(accountID string, domainName string) (*domainResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/auto_renewal", accountID, domainName)) + domainResponse := &domainResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + domainResponse.HttpResponse = resp + return domainResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_delegation.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_delegation.go new file mode 100644 index 000000000..4ebd3454c --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_delegation.go @@ -0,0 +1,84 @@ +package dnsimple + +import ( + "fmt" +) + +// Delegation represents a list of name servers that correspond to a domain delegation. +type Delegation []string + +// delegationResponse represents a response from an API method that returns a delegation struct. +type delegationResponse struct { + Response + Data *Delegation `json:"data"` +} + +// vanityDelegationResponse represents a response for vanity name server enable and disable operations. +type vanityDelegationResponse struct { + Response + Data []VanityNameServer `json:"data"` +} + +// GetDomainDelegation gets the current delegated name servers for the domain. +// +// See https://developer.dnsimple.com/v2/registrar/delegation/#get +func (s *RegistrarService) GetDomainDelegation(accountID string, domainName string) (*delegationResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/delegation", accountID, domainName)) + delegationResponse := &delegationResponse{} + + resp, err := s.client.get(path, delegationResponse) + if err != nil { + return nil, err + } + + delegationResponse.HttpResponse = resp + return delegationResponse, nil +} + +// ChangeDomainDelegation updates the delegated name severs for the domain. +// +// See https://developer.dnsimple.com/v2/registrar/delegation/#get +func (s *RegistrarService) ChangeDomainDelegation(accountID string, domainName string, newDelegation *Delegation) (*delegationResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/delegation", accountID, domainName)) + delegationResponse := &delegationResponse{} + + resp, err := s.client.put(path, newDelegation, delegationResponse) + if err != nil { + return nil, err + } + + delegationResponse.HttpResponse = resp + return delegationResponse, nil +} + +// ChangeDomainDelegationToVanity enables vanity name servers for the given domain. +// +// See https://developer.dnsimple.com/v2/registrar/delegation/#delegateToVanity +func (s *RegistrarService) ChangeDomainDelegationToVanity(accountID string, domainName string, newDelegation *Delegation) (*vanityDelegationResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/delegation/vanity", accountID, domainName)) + delegationResponse := &vanityDelegationResponse{} + + resp, err := s.client.put(path, newDelegation, delegationResponse) + if err != nil { + return nil, err + } + + delegationResponse.HttpResponse = resp + return delegationResponse, nil +} + +// ChangeDomainDelegationFromVanity disables vanity name servers for the given domain. +// +// See https://developer.dnsimple.com/v2/registrar/delegation/#dedelegateFromVanity +func (s *RegistrarService) ChangeDomainDelegationFromVanity(accountID string, domainName string) (*vanityDelegationResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/delegation/vanity", accountID, domainName)) + delegationResponse := &vanityDelegationResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + delegationResponse.HttpResponse = resp + return delegationResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_whois_privacy.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_whois_privacy.go new file mode 100644 index 000000000..730fd8a44 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/registrar_whois_privacy.go @@ -0,0 +1,103 @@ +package dnsimple + +import ( + "fmt" +) + +// WhoisPrivacy represents a whois privacy in DNSimple. +type WhoisPrivacy struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + Enabled bool `json:"enabled,omitempty"` + ExpiresOn string `json:"expires_on,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// WhoisPrivacyRenewal represents a whois privacy renewal in DNSimple. +type WhoisPrivacyRenewal struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + WhoisPrivacyID int64 `json:"whois_privacy_id,omitempty"` + State string `json:"string,omitempty"` + Enabled bool `json:"enabled,omitempty"` + ExpiresOn string `json:"expires_on,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// whoisPrivacyResponse represents a response from an API method that returns a WhoisPrivacy struct. +type whoisPrivacyResponse struct { + Response + Data *WhoisPrivacy `json:"data"` +} + +// whoisPrivacyRenewalResponse represents a response from an API method that returns a WhoisPrivacyRenewal struct. +type whoisPrivacyRenewalResponse struct { + Response + Data *WhoisPrivacyRenewal `json:"data"` +} + +// GetWhoisPrivacy gets the whois privacy for the domain. +// +// See https://developer.dnsimple.com/v2/registrar/whois-privacy/#get +func (s *RegistrarService) GetWhoisPrivacy(accountID string, domainName string) (*whoisPrivacyResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/whois_privacy", accountID, domainName)) + privacyResponse := &whoisPrivacyResponse{} + + resp, err := s.client.get(path, privacyResponse) + if err != nil { + return nil, err + } + + privacyResponse.HttpResponse = resp + return privacyResponse, nil +} + +// EnableWhoisPrivacy enables the whois privacy for the domain. +// +// See https://developer.dnsimple.com/v2/registrar/whois-privacy/#enable +func (s *RegistrarService) EnableWhoisPrivacy(accountID string, domainName string) (*whoisPrivacyResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/whois_privacy", accountID, domainName)) + privacyResponse := &whoisPrivacyResponse{} + + resp, err := s.client.put(path, nil, privacyResponse) + if err != nil { + return nil, err + } + + privacyResponse.HttpResponse = resp + return privacyResponse, nil +} + +// DisableWhoisPrivacy disables the whois privacy for the domain. +// +// See https://developer.dnsimple.com/v2/registrar/whois-privacy/#enable +func (s *RegistrarService) DisableWhoisPrivacy(accountID string, domainName string) (*whoisPrivacyResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/whois_privacy", accountID, domainName)) + privacyResponse := &whoisPrivacyResponse{} + + resp, err := s.client.delete(path, nil, privacyResponse) + if err != nil { + return nil, err + } + + privacyResponse.HttpResponse = resp + return privacyResponse, nil +} + +// RenewWhoisPrivacy renews the whois privacy for the domain. +// +// See https://developer.dnsimple.com/v2/registrar/whois-privacy/#renew +func (s *RegistrarService) RenewWhoisPrivacy(accountID string, domainName string) (*whoisPrivacyRenewalResponse, error) { + path := versioned(fmt.Sprintf("/%v/registrar/domains/%v/whois_privacy/renewals", accountID, domainName)) + privacyRenewalResponse := &whoisPrivacyRenewalResponse{} + + resp, err := s.client.post(path, nil, privacyRenewalResponse) + if err != nil { + return nil, err + } + + privacyRenewalResponse.HttpResponse = resp + return privacyRenewalResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/services.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/services.go new file mode 100644 index 000000000..18afd1185 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/services.go @@ -0,0 +1,94 @@ +package dnsimple + +import ( + "fmt" +) + +// ServicesService handles communication with the service related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/services/ +type ServicesService struct { + client *Client +} + +// Service represents a Service in DNSimple. +type Service struct { + ID int64 `json:"id,omitempty"` + SID string `json:"sid,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + SetupDescription string `json:"setup_description,omitempty"` + RequiresSetup bool `json:"requires_setup,omitempty"` + DefaultSubdomain string `json:"default_subdomain,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` + Settings []ServiceSetting `json:"settings,omitempty"` +} + +// ServiceSetting represents a single group of settings for a DNSimple Service. +type ServiceSetting struct { + Name string `json:"name,omitempty"` + Label string `json:"label,omitempty"` + Append string `json:"append,omitempty"` + Description string `json:"description,omitempty"` + Example string `json:"example,omitempty"` + Password bool `json:"password,omitempty"` +} + +func servicePath(serviceIdentifier string) (path string) { + path = "/services" + if serviceIdentifier != "" { + path += fmt.Sprintf("/%v", serviceIdentifier) + } + return +} + +// serviceResponse represents a response from an API method that returns a Service struct. +type serviceResponse struct { + Response + Data *Service `json:"data"` +} + +// servicesResponse represents a response from an API method that returns a collection of Service struct. +type servicesResponse struct { + Response + Data []Service `json:"data"` +} + +// ListServices lists the one-click services available in DNSimple. +// +// See https://developer.dnsimple.com/v2/services/#list +func (s *ServicesService) ListServices(options *ListOptions) (*servicesResponse, error) { + path := versioned(servicePath("")) + servicesResponse := &servicesResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, servicesResponse) + if err != nil { + return servicesResponse, err + } + + servicesResponse.HttpResponse = resp + return servicesResponse, nil +} + +// GetService fetches a one-click service. +// +// See https://developer.dnsimple.com/v2/services/#get +func (s *ServicesService) GetService(serviceIdentifier string) (*serviceResponse, error) { + path := versioned(servicePath(serviceIdentifier)) + serviceResponse := &serviceResponse{} + + resp, err := s.client.get(path, serviceResponse) + if err != nil { + return nil, err + } + + serviceResponse.HttpResponse = resp + return serviceResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/services_domains.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/services_domains.go new file mode 100644 index 000000000..0426dd620 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/services_domains.go @@ -0,0 +1,70 @@ +package dnsimple + +import ( + "fmt" +) + +func domainServicesPath(accountID string, domainIdentifier string, serviceIdentifier string) string { + if serviceIdentifier != "" { + return fmt.Sprintf("/%v/domains/%v/services/%v", accountID, domainIdentifier, serviceIdentifier) + } + return fmt.Sprintf("/%v/domains/%v/services", accountID, domainIdentifier) +} + +// DomainServiceSettings represents optional settings when applying a DNSimple one-click service to a domain. +type DomainServiceSettings struct { + Settings map[string]string `url:"settings,omitempty"` +} + +// AppliedServices lists the applied one-click services for a domain. +// +// See https://developer.dnsimple.com/v2/services/domains/#applied +func (s *ServicesService) AppliedServices(accountID string, domainIdentifier string, options *ListOptions) (*servicesResponse, error) { + path := versioned(domainServicesPath(accountID, domainIdentifier, "")) + servicesResponse := &servicesResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, servicesResponse) + if err != nil { + return servicesResponse, err + } + + servicesResponse.HttpResponse = resp + return servicesResponse, nil +} + +// ApplyService applies a one-click services to a domain. +// +// See https://developer.dnsimple.com/v2/services/domains/#apply +func (s *ServicesService) ApplyService(accountID string, serviceIdentifier string, domainIdentifier string, settings DomainServiceSettings) (*serviceResponse, error) { + path := versioned(domainServicesPath(accountID, domainIdentifier, serviceIdentifier)) + serviceResponse := &serviceResponse{} + + resp, err := s.client.post(path, settings, nil) + if err != nil { + return nil, err + } + + serviceResponse.HttpResponse = resp + return serviceResponse, nil +} + +// UnapplyService unapplies a one-click services from a domain. +// +// See https://developer.dnsimple.com/v2/services/domains/#unapply +func (s *ServicesService) UnapplyService(accountID string, serviceIdentifier string, domainIdentifier string) (*serviceResponse, error) { + path := versioned(domainServicesPath(accountID, domainIdentifier, serviceIdentifier)) + serviceResponse := &serviceResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + serviceResponse.HttpResponse = resp + return serviceResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates.go new file mode 100644 index 000000000..0cd2ec859 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates.go @@ -0,0 +1,129 @@ +package dnsimple + +import ( + "fmt" +) + +// TemplatesService handles communication with the template related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/templates/ +type TemplatesService struct { + client *Client +} + +// Template represents a Template in DNSimple. +type Template struct { + ID int64 `json:"id,omitempty"` + SID string `json:"sid,omitempty"` + AccountID int64 `json:"account_id,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func templatePath(accountID string, templateIdentifier string) (path string) { + path = fmt.Sprintf("/%v/templates", accountID) + if templateIdentifier != "" { + path += fmt.Sprintf("/%v", templateIdentifier) + } + return +} + +// templateResponse represents a response from an API method that returns a Template struct. +type templateResponse struct { + Response + Data *Template `json:"data"` +} + +// templatesResponse represents a response from an API method that returns a collection of Template struct. +type templatesResponse struct { + Response + Data []Template `json:"data"` +} + +// ListTemplates list the templates for an account. +// +// See https://developer.dnsimple.com/v2/templates/#list +func (s *TemplatesService) ListTemplates(accountID string, options *ListOptions) (*templatesResponse, error) { + path := versioned(templatePath(accountID, "")) + templatesResponse := &templatesResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, templatesResponse) + if err != nil { + return templatesResponse, err + } + + templatesResponse.HttpResponse = resp + return templatesResponse, nil +} + +// CreateTemplate creates a new template. +// +// See https://developer.dnsimple.com/v2/templates/#create +func (s *TemplatesService) CreateTemplate(accountID string, templateAttributes Template) (*templateResponse, error) { + path := versioned(templatePath(accountID, "")) + templateResponse := &templateResponse{} + + resp, err := s.client.post(path, templateAttributes, templateResponse) + if err != nil { + return nil, err + } + + templateResponse.HttpResponse = resp + return templateResponse, nil +} + +// GetTemplate fetches a template. +// +// See https://developer.dnsimple.com/v2/templates/#get +func (s *TemplatesService) GetTemplate(accountID string, templateIdentifier string) (*templateResponse, error) { + path := versioned(templatePath(accountID, templateIdentifier)) + templateResponse := &templateResponse{} + + resp, err := s.client.get(path, templateResponse) + if err != nil { + return nil, err + } + + templateResponse.HttpResponse = resp + return templateResponse, nil +} + +// UpdateTemplate updates a template. +// +// See https://developer.dnsimple.com/v2/templates/#update +func (s *TemplatesService) UpdateTemplate(accountID string, templateIdentifier string, templateAttributes Template) (*templateResponse, error) { + path := versioned(templatePath(accountID, templateIdentifier)) + templateResponse := &templateResponse{} + + resp, err := s.client.patch(path, templateAttributes, templateResponse) + if err != nil { + return nil, err + } + + templateResponse.HttpResponse = resp + return templateResponse, nil +} + +// DeleteTemplate deletes a template. +// +// See https://developer.dnsimple.com/v2/templates/#delete +func (s *TemplatesService) DeleteTemplate(accountID string, templateIdentifier string) (*templateResponse, error) { + path := versioned(templatePath(accountID, templateIdentifier)) + templateResponse := &templateResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + templateResponse.HttpResponse = resp + return templateResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates_domains.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates_domains.go new file mode 100644 index 000000000..01901bb08 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates_domains.go @@ -0,0 +1,21 @@ +package dnsimple + +import ( + "fmt" +) + +// ApplyTemplate applies a template to the given domain. +// +// See https://developer.dnsimple.com/v2/templates/domains/#apply +func (s *TemplatesService) ApplyTemplate(accountID string, templateIdentifier string, domainIdentifier string) (*templateResponse, error) { + path := versioned(fmt.Sprintf("%v/templates/%v", domainPath(accountID, domainIdentifier), templateIdentifier)) + templateResponse := &templateResponse{} + + resp, err := s.client.post(path, nil, nil) + if err != nil { + return nil, err + } + + templateResponse.HttpResponse = resp + return templateResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates_records.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates_records.go new file mode 100644 index 000000000..74f6fd65a --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/templates_records.go @@ -0,0 +1,107 @@ +package dnsimple + +import ( + "fmt" +) + +// TemplateRecord represents a DNS record for a template in DNSimple. +type TemplateRecord struct { + ID int64 `json:"id,omitempty"` + TemplateID int64 `json:"template_id,omitempty"` + Name string `json:"name"` + Content string `json:"content,omitempty"` + TTL int `json:"ttl,omitempty"` + Type string `json:"type,omitempty"` + Priority int `json:"priority,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func templateRecordPath(accountID string, templateIdentifier string, templateRecordID int64) string { + if templateRecordID != 0 { + return fmt.Sprintf("%v/records/%v", templatePath(accountID, templateIdentifier), templateRecordID) + } + + return templatePath(accountID, templateIdentifier) + "/records" +} + +// templateRecordResponse represents a response from an API method that returns a TemplateRecord struct. +type templateRecordResponse struct { + Response + Data *TemplateRecord `json:"data"` +} + +// templateRecordsResponse represents a response from an API method that returns a collection of TemplateRecord struct. +type templateRecordsResponse struct { + Response + Data []TemplateRecord `json:"data"` +} + +// ListTemplateRecords list the templates for an account. +// +// See https://developer.dnsimple.com/v2/templates/records/#list +func (s *TemplatesService) ListTemplateRecords(accountID string, templateIdentifier string, options *ListOptions) (*templateRecordsResponse, error) { + path := versioned(templateRecordPath(accountID, templateIdentifier, 0)) + templateRecordsResponse := &templateRecordsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, templateRecordsResponse) + if err != nil { + return templateRecordsResponse, err + } + + templateRecordsResponse.HttpResponse = resp + return templateRecordsResponse, nil +} + +// CreateTemplateRecord creates a new template record. +// +// See https://developer.dnsimple.com/v2/templates/records/#create +func (s *TemplatesService) CreateTemplateRecord(accountID string, templateIdentifier string, templateRecordAttributes TemplateRecord) (*templateRecordResponse, error) { + path := versioned(templateRecordPath(accountID, templateIdentifier, 0)) + templateRecordResponse := &templateRecordResponse{} + + resp, err := s.client.post(path, templateRecordAttributes, templateRecordResponse) + if err != nil { + return nil, err + } + + templateRecordResponse.HttpResponse = resp + return templateRecordResponse, nil +} + +// GetTemplateRecord fetches a template record. +// +// See https://developer.dnsimple.com/v2/templates/records/#get +func (s *TemplatesService) GetTemplateRecord(accountID string, templateIdentifier string, templateRecordID int64) (*templateRecordResponse, error) { + path := versioned(templateRecordPath(accountID, templateIdentifier, templateRecordID)) + templateRecordResponse := &templateRecordResponse{} + + resp, err := s.client.get(path, templateRecordResponse) + if err != nil { + return nil, err + } + + templateRecordResponse.HttpResponse = resp + return templateRecordResponse, nil +} + +// DeleteTemplateRecord deletes a template record. +// +// See https://developer.dnsimple.com/v2/templates/records/#delete +func (s *TemplatesService) DeleteTemplateRecord(accountID string, templateIdentifier string, templateRecordID int64) (*templateRecordResponse, error) { + path := versioned(templateRecordPath(accountID, templateIdentifier, templateRecordID)) + templateRecordResponse := &templateRecordResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + templateRecordResponse.HttpResponse = resp + return templateRecordResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/tlds.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/tlds.go new file mode 100644 index 000000000..9c5c250dd --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/tlds.go @@ -0,0 +1,117 @@ +package dnsimple + +import ( + "fmt" +) + +// TldsService handles communication with the Tld related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/tlds/ +type TldsService struct { + client *Client +} + +// Tld represents a TLD in DNSimple. +type Tld struct { + Tld string `json:"tld"` + TldType int `json:"tld_type"` + WhoisPrivacy bool `json:"whois_privacy"` + AutoRenewOnly bool `json:"auto_renew_only"` + MinimumRegistration int `json:"minimum_registration"` + RegistrationEnabled bool `json:"registration_enabled"` + RenewalEnabled bool `json:"renewal_enabled"` + TransferEnabled bool `json:"transfer_enabled"` +} + +// TldExtendedAttribute represents an extended attributes supported or required +// by a specific TLD. +// +// See https://developer.dnsimple.com/v2/tlds/ +type TldExtendedAttribute struct { + Name string `json:"name"` + Description string `json:"description"` + Required bool `json:"required"` + Options []TldExtendedAttributeOption `json:"options"` +} + +// TldExtendedAttributeOption represents a single option you can assign to an extended attributes. +// +// See https://developer.dnsimple.com/v2/tlds/ +type TldExtendedAttributeOption struct { + Title string `json:"title"` + Value string `json:"value"` + Description string `json:"description"` +} + +// tldResponse represents a response from an API method that returns a Tld struct. +type tldResponse struct { + Response + Data *Tld `json:"data"` +} + +// tldsResponse represents a response from an API method that returns a collection of Tld struct. +type tldsResponse struct { + Response + Data []Tld `json:"data"` +} + +// tldExtendedAttributesResponse represents a response from an API method that returns +// a collection of Tld extended attributes. +type tldExtendedAttributesResponse struct { + Response + Data []TldExtendedAttribute `json:"data"` +} + +// ListTlds lists the supported TLDs. +// +// See https://developer.dnsimple.com/v2/tlds/#list +func (s *TldsService) ListTlds(options *ListOptions) (*tldsResponse, error) { + path := versioned("/tlds") + tldsResponse := &tldsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, tldsResponse) + if err != nil { + return tldsResponse, err + } + + tldsResponse.HttpResponse = resp + return tldsResponse, nil +} + +// GetTld fetches a TLD. +// +// See https://developer.dnsimple.com/v2/tlds/#get +func (s *TldsService) GetTld(tld string) (*tldResponse, error) { + path := versioned(fmt.Sprintf("/tlds/%s", tld)) + tldResponse := &tldResponse{} + + resp, err := s.client.get(path, tldResponse) + if err != nil { + return nil, err + } + + tldResponse.HttpResponse = resp + return tldResponse, nil +} + +// GetTldExtendedAttributes fetches the extended attributes of a TLD. +// +// See https://developer.dnsimple.com/v2/tlds/#get +func (s *TldsService) GetTldExtendedAttributes(tld string) (*tldExtendedAttributesResponse, error) { + path := versioned(fmt.Sprintf("/tlds/%s/extended_attributes", tld)) + tldResponse := &tldExtendedAttributesResponse{} + + resp, err := s.client.get(path, tldResponse) + if err != nil { + return nil, err + } + + tldResponse.HttpResponse = resp + return tldResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/users.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/users.go new file mode 100644 index 000000000..9c33f4083 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/users.go @@ -0,0 +1,7 @@ +package dnsimple + +// User represents a DNSimple user. +type User struct { + ID int64 `json:"id,omitempty"` + Email string `json:"email,omitempty"` +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/vanity_name_server.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/vanity_name_server.go new file mode 100644 index 000000000..cd1314a4c --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/vanity_name_server.go @@ -0,0 +1,65 @@ +package dnsimple + +import ( + "fmt" +) + +// VanityNameServersService handles communication with Vanity Name Servers +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/vanity/ +type VanityNameServersService struct { + client *Client +} + +// VanityNameServer represents data for a single vanity name server +type VanityNameServer struct { + ID int64 `json:"id,omitempty"` + Name string `json:"name,omitempty"` + IPv4 string `json:"ipv4,omitempty"` + IPv6 string `json:"ipv6,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func vanityNameServerPath(accountID string, domainIdentifier string) string { + return fmt.Sprintf("/%v/vanity/%v", accountID, domainIdentifier) +} + +// vanityNameServerResponse represents a response for vanity name server enable and disable operations. +type vanityNameServerResponse struct { + Response + Data []VanityNameServer `json:"data"` +} + +// EnableVanityNameServers Vanity Name Servers for the given domain +// +// See https://developer.dnsimple.com/v2/vanity/#enable +func (s *VanityNameServersService) EnableVanityNameServers(accountID string, domainIdentifier string) (*vanityNameServerResponse, error) { + path := versioned(vanityNameServerPath(accountID, domainIdentifier)) + vanityNameServerResponse := &vanityNameServerResponse{} + + resp, err := s.client.put(path, nil, vanityNameServerResponse) + if err != nil { + return nil, err + } + + vanityNameServerResponse.HttpResponse = resp + return vanityNameServerResponse, nil +} + +// DisableVanityNameServers Vanity Name Servers for the given domain +// +// See https://developer.dnsimple.com/v2/vanity/#disable +func (s *VanityNameServersService) DisableVanityNameServers(accountID string, domainIdentifier string) (*vanityNameServerResponse, error) { + path := versioned(vanityNameServerPath(accountID, domainIdentifier)) + vanityNameServerResponse := &vanityNameServerResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + vanityNameServerResponse.HttpResponse = resp + return vanityNameServerResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/webhooks.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/webhooks.go new file mode 100644 index 000000000..14263338d --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/webhooks.go @@ -0,0 +1,103 @@ +package dnsimple + +import ( + "fmt" +) + +// WebhooksService handles communication with the webhook related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/webhooks +type WebhooksService struct { + client *Client +} + +// Webhook represents a DNSimple webhook. +type Webhook struct { + ID int64 `json:"id,omitempty"` + URL string `json:"url,omitempty"` +} + +func webhookPath(accountID string, webhookID int64) (path string) { + path = fmt.Sprintf("/%v/webhooks", accountID) + if webhookID != 0 { + path = fmt.Sprintf("%v/%v", path, webhookID) + } + return +} + +// webhookResponse represents a response from an API method that returns a Webhook struct. +type webhookResponse struct { + Response + Data *Webhook `json:"data"` +} + +// webhookResponse represents a response from an API method that returns a collection of Webhook struct. +type webhooksResponse struct { + Response + Data []Webhook `json:"data"` +} + +// ListWebhooks lists the webhooks for an account. +// +// See https://developer.dnsimple.com/v2/webhooks#list +func (s *WebhooksService) ListWebhooks(accountID string, _ *ListOptions) (*webhooksResponse, error) { + path := versioned(webhookPath(accountID, 0)) + webhooksResponse := &webhooksResponse{} + + resp, err := s.client.get(path, webhooksResponse) + if err != nil { + return webhooksResponse, err + } + + webhooksResponse.HttpResponse = resp + return webhooksResponse, nil +} + +// CreateWebhook creates a new webhook. +// +// See https://developer.dnsimple.com/v2/webhooks#create +func (s *WebhooksService) CreateWebhook(accountID string, webhookAttributes Webhook) (*webhookResponse, error) { + path := versioned(webhookPath(accountID, 0)) + webhookResponse := &webhookResponse{} + + resp, err := s.client.post(path, webhookAttributes, webhookResponse) + if err != nil { + return nil, err + } + + webhookResponse.HttpResponse = resp + return webhookResponse, nil +} + +// GetWebhook fetches a webhook. +// +// See https://developer.dnsimple.com/v2/webhooks#get +func (s *WebhooksService) GetWebhook(accountID string, webhookID int64) (*webhookResponse, error) { + path := versioned(webhookPath(accountID, webhookID)) + webhookResponse := &webhookResponse{} + + resp, err := s.client.get(path, webhookResponse) + if err != nil { + return nil, err + } + + webhookResponse.HttpResponse = resp + return webhookResponse, nil +} + +// DeleteWebhook PERMANENTLY deletes a webhook from the account. +// +// See https://developer.dnsimple.com/v2/webhooks#delete +func (s *WebhooksService) DeleteWebhook(accountID string, webhookID int64) (*webhookResponse, error) { + path := versioned(webhookPath(accountID, webhookID)) + webhookResponse := &webhookResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + webhookResponse.HttpResponse = resp + return webhookResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zone_distributions.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zone_distributions.go new file mode 100644 index 000000000..f92d75790 --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zone_distributions.go @@ -0,0 +1,46 @@ +package dnsimple + +import "fmt" + +// ZoneDistribution is the result of the zone distribution check. +type ZoneDistribution struct { + Distributed bool `json:"distributed"` +} + +// zoneDistributionResponse represents a response from an API method that returns a ZoneDistribution struct. +type zoneDistributionResponse struct { + Response + Data *ZoneDistribution `json:"data"` +} + +// CheckZoneDistribution checks if a zone is fully distributed across DNSimple nodes. +// +// See https://developer.dnsimple.com/v2/zones/#checkZoneDistribution +func (s *ZonesService) CheckZoneDistribution(accountID string, zoneName string) (*zoneDistributionResponse, error) { + path := versioned(fmt.Sprintf("/%v/zones/%v/distribution", accountID, zoneName)) + zoneDistributionResponse := &zoneDistributionResponse{} + + resp, err := s.client.get(path, zoneDistributionResponse) + if err != nil { + return nil, err + } + + zoneDistributionResponse.HttpResponse = resp + return zoneDistributionResponse, nil +} + +// CheckZoneRecordDistribution checks if a zone is fully distributed across DNSimple nodes. +// +// See https://developer.dnsimple.com/v2/zones/#checkZoneRecordDistribution +func (s *ZonesService) CheckZoneRecordDistribution(accountID string, zoneName string, recordID int64) (*zoneDistributionResponse, error) { + path := versioned(fmt.Sprintf("/%v/zones/%v/records/%v/distribution", accountID, zoneName, recordID)) + zoneDistributionResponse := &zoneDistributionResponse{} + + resp, err := s.client.get(path, zoneDistributionResponse) + if err != nil { + return nil, err + } + + zoneDistributionResponse.HttpResponse = resp + return zoneDistributionResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zones.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zones.go new file mode 100644 index 000000000..f521fcfac --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zones.go @@ -0,0 +1,108 @@ +package dnsimple + +import ( + "fmt" +) + +// ZonesService handles communication with the zone related +// methods of the DNSimple API. +// +// See https://developer.dnsimple.com/v2/zones/ +type ZonesService struct { + client *Client +} + +// Zone represents a Zone in DNSimple. +type Zone struct { + ID int64 `json:"id,omitempty"` + AccountID int64 `json:"account_id,omitempty"` + Name string `json:"name,omitempty"` + Reverse bool `json:"reverse,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +// ZoneFile represents a Zone File in DNSimple. +type ZoneFile struct { + Zone string `json:"zone,omitempty"` +} + +// zoneResponse represents a response from an API method that returns a Zone struct. +type zoneResponse struct { + Response + Data *Zone `json:"data"` +} + +// zonesResponse represents a response from an API method that returns a collection of Zone struct. +type zonesResponse struct { + Response + Data []Zone `json:"data"` +} + +// zoneFileResponse represents a response from an API method that returns a ZoneFile struct. +type zoneFileResponse struct { + Response + Data *ZoneFile `json:"data"` +} + +// ZoneListOptions specifies the optional parameters you can provide +// to customize the ZonesService.ListZones method. +type ZoneListOptions struct { + // Select domains where the name contains given string. + NameLike string `url:"name_like,omitempty"` + + ListOptions +} + +// ListZones the zones for an account. +// +// See https://developer.dnsimple.com/v2/zones/#list +func (s *ZonesService) ListZones(accountID string, options *ZoneListOptions) (*zonesResponse, error) { + path := versioned(fmt.Sprintf("/%v/zones", accountID)) + zonesResponse := &zonesResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, zonesResponse) + if err != nil { + return zonesResponse, err + } + + zonesResponse.HttpResponse = resp + return zonesResponse, nil +} + +// GetZone fetches a zone. +// +// See https://developer.dnsimple.com/v2/zones/#get +func (s *ZonesService) GetZone(accountID string, zoneName string) (*zoneResponse, error) { + path := versioned(fmt.Sprintf("/%v/zones/%v", accountID, zoneName)) + zoneResponse := &zoneResponse{} + + resp, err := s.client.get(path, zoneResponse) + if err != nil { + return nil, err + } + + zoneResponse.HttpResponse = resp + return zoneResponse, nil +} + +// GetZoneFile fetches a zone file. +// +// See https://developer.dnsimple.com/v2/zones/#get-file +func (s *ZonesService) GetZoneFile(accountID string, zoneName string) (*zoneFileResponse, error) { + path := versioned(fmt.Sprintf("/%v/zones/%v/file", accountID, zoneName)) + zoneFileResponse := &zoneFileResponse{} + + resp, err := s.client.get(path, zoneFileResponse) + if err != nil { + return nil, err + } + + zoneFileResponse.HttpResponse = resp + return zoneFileResponse, nil +} diff --git a/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zones_records.go b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zones_records.go new file mode 100644 index 000000000..fbb432d5a --- /dev/null +++ b/vendor/github.com/dnsimple/dnsimple-go/dnsimple/zones_records.go @@ -0,0 +1,142 @@ +package dnsimple + +import ( + "fmt" +) + +// ZoneRecord represents a DNS record in DNSimple. +type ZoneRecord struct { + ID int64 `json:"id,omitempty"` + ZoneID string `json:"zone_id,omitempty"` + ParentID int64 `json:"parent_id,omitempty"` + Type string `json:"type,omitempty"` + Name string `json:"name"` + Content string `json:"content,omitempty"` + TTL int `json:"ttl,omitempty"` + Priority int `json:"priority,omitempty"` + SystemRecord bool `json:"system_record,omitempty"` + Regions []string `json:"regions,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` +} + +func zoneRecordPath(accountID string, zoneName string, recordID int64) (path string) { + path = fmt.Sprintf("/%v/zones/%v/records", accountID, zoneName) + if recordID != 0 { + path += fmt.Sprintf("/%v", recordID) + } + return +} + +// zoneRecordResponse represents a response from an API method that returns a ZoneRecord struct. +type zoneRecordResponse struct { + Response + Data *ZoneRecord `json:"data"` +} + +// zoneRecordsResponse represents a response from an API method that returns a collection of ZoneRecord struct. +type zoneRecordsResponse struct { + Response + Data []ZoneRecord `json:"data"` +} + +// ZoneRecordListOptions specifies the optional parameters you can provide +// to customize the ZonesService.ListZoneRecords method. +type ZoneRecordListOptions struct { + // Select records where the name matches given string. + Name string `url:"name,omitempty"` + + // Select records where the name contains given string. + NameLike string `url:"name_like,omitempty"` + + // Select records of given type. + // Eg. TXT, A, NS. + Type string `url:"type,omitempty"` + + ListOptions +} + +// ListRecords lists the zone records for a zone. +// +// See https://developer.dnsimple.com/v2/zones/records/#listZoneRecords +func (s *ZonesService) ListRecords(accountID string, zoneName string, options *ZoneRecordListOptions) (*zoneRecordsResponse, error) { + path := versioned(zoneRecordPath(accountID, zoneName, 0)) + recordsResponse := &zoneRecordsResponse{} + + path, err := addURLQueryOptions(path, options) + if err != nil { + return nil, err + } + + resp, err := s.client.get(path, recordsResponse) + if err != nil { + return nil, err + } + + recordsResponse.HttpResponse = resp + return recordsResponse, nil +} + +// CreateRecord creates a zone record. +// +// See https://developer.dnsimple.com/v2/zones/records/#createZoneRecord +func (s *ZonesService) CreateRecord(accountID string, zoneName string, recordAttributes ZoneRecord) (*zoneRecordResponse, error) { + path := versioned(zoneRecordPath(accountID, zoneName, 0)) + recordResponse := &zoneRecordResponse{} + + resp, err := s.client.post(path, recordAttributes, recordResponse) + if err != nil { + return nil, err + } + + recordResponse.HttpResponse = resp + return recordResponse, nil +} + +// GetRecord fetches a zone record. +// +// See https://developer.dnsimple.com/v2/zones/records/#getZoneRecord +func (s *ZonesService) GetRecord(accountID string, zoneName string, recordID int64) (*zoneRecordResponse, error) { + path := versioned(zoneRecordPath(accountID, zoneName, recordID)) + recordResponse := &zoneRecordResponse{} + + resp, err := s.client.get(path, recordResponse) + if err != nil { + return nil, err + } + + recordResponse.HttpResponse = resp + return recordResponse, nil +} + +// UpdateRecord updates a zone record. +// +// See https://developer.dnsimple.com/v2/zones/records/#updateZoneRecord +func (s *ZonesService) UpdateRecord(accountID string, zoneName string, recordID int64, recordAttributes ZoneRecord) (*zoneRecordResponse, error) { + path := versioned(zoneRecordPath(accountID, zoneName, recordID)) + recordResponse := &zoneRecordResponse{} + resp, err := s.client.patch(path, recordAttributes, recordResponse) + + if err != nil { + return nil, err + } + + recordResponse.HttpResponse = resp + return recordResponse, nil +} + +// DeleteRecord PERMANENTLY deletes a zone record from the zone. +// +// See https://developer.dnsimple.com/v2/zones/records/#deleteZoneRecord +func (s *ZonesService) DeleteRecord(accountID string, zoneName string, recordID int64) (*zoneRecordResponse, error) { + path := versioned(zoneRecordPath(accountID, zoneName, recordID)) + recordResponse := &zoneRecordResponse{} + + resp, err := s.client.delete(path, nil, nil) + if err != nil { + return nil, err + } + + recordResponse.HttpResponse = resp + return recordResponse, nil +} diff --git a/vendor/github.com/exoscale/egoscale/.codeclimate.yml b/vendor/github.com/exoscale/egoscale/.codeclimate.yml new file mode 100644 index 000000000..dc2b688a4 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/.codeclimate.yml @@ -0,0 +1,31 @@ +version: "2" + +checks: + argument-count: + enabled: false + complex-logic: + enabled: false + file-lines: + enabled: false + method-complexity: + enabled: false + method-count: + enabled: false + method-lines: + enabled: false + nested-control-flow: + enabled: false + return-statements: + enabled: false + similar-code: + enabled: false + identical-code: + enabled: false + +plugins: + gofmt: + enabled: true + golint: + enabled: true + govet: + enabled: true diff --git a/vendor/github.com/exoscale/egoscale/.gitignore b/vendor/github.com/exoscale/egoscale/.gitignore new file mode 100644 index 000000000..800fe1da7 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/.gitignore @@ -0,0 +1,5 @@ +.token +dist +ops.asc +vendor +listApis.json \ No newline at end of file diff --git a/vendor/github.com/exoscale/egoscale/.golangci.yml b/vendor/github.com/exoscale/egoscale/.golangci.yml new file mode 100644 index 000000000..da5e91dff --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/.golangci.yml @@ -0,0 +1,27 @@ +linters-settings: + golint: + min-confidence: 0.3 + gocyclo: + min-complexity: 28 + goimports: + local-prefixes: github.com + +linters: + enable: + - deadcode + - dupl + - errcheck + - gocyclo + - goimports + - golint + - gosimple + - govet + - ineffassign + - megacheck + - nakedret + - scopelint + - staticcheck + - structcheck + - unused + - varcheck + disable-all: true diff --git a/vendor/github.com/exoscale/egoscale/.gometalinter.json b/vendor/github.com/exoscale/egoscale/.gometalinter.json new file mode 100644 index 000000000..c685c4603 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/.gometalinter.json @@ -0,0 +1,25 @@ +{ + "Test": false, + "Enable": [ + "deadcode", + "errcheck", + "golint", + "gosimple", + "gotype", + "ineffassign", + "interfacer", + "misspell", + "structcheck", + "unconvert", + "varcheck", + "vet", + "vetshadow" + ], + "Disable": [ + "goconst", + "gocyclo", + "gosec", + "maligned" + ], + "Skip": ["vendor"] +} diff --git a/vendor/github.com/exoscale/egoscale/.travis.yml b/vendor/github.com/exoscale/egoscale/.travis.yml new file mode 100644 index 000000000..94b2f19c8 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/.travis.yml @@ -0,0 +1,49 @@ +language: go + +dist: xenial +sudo: required + +go: +- "1.7.x" +- "1.8.x" +- "1.9.x" +- "1.10.x" +- "1.11.x" +- "1.12.x" +- tip + +env: + - GOLANGCI_LINT_VERSION=1.15.0 GO111MODULES=on + +cache: apt + +addons: + apt: + update: true + packages: + - rpm + +install: + - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin v${GOLANGCI_LINT_VERSION} + - npm i codeclimate-test-reporter + - '[ "$(echo "$TRAVIS_GO_VERSION" | perl -pe "s/\\.[x\\d]+$//")" = "1.11" ] && go mod vendor || go get -u github.com/gofrs/uuid' + +before_script: + - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + - chmod +x ./cc-test-reporter + - ./cc-test-reporter before-build + +script: + - go test -race -coverprofile=c.out -covermode=atomic . + +after_script: + - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT + +jobs: + include: + - stage: golangci-lint + go: 1.10.x + if: type = pull_request + script: + - go get -u github.com/gofrs/uuid + - golangci-lint run . diff --git a/vendor/github.com/exoscale/egoscale/AUTHORS b/vendor/github.com/exoscale/egoscale/AUTHORS new file mode 100644 index 000000000..5c12a2a17 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/AUTHORS @@ -0,0 +1,9 @@ +Pierre-Yves Ritschard +Vincent Bernat +Chris Baumbauer +Marc-Aurèle Brothier +Sebastien Goasguen +Yoan Blanc +Stefano Marengo +Pierre-Emmanuel Jacquier +Fabrizio Steiner diff --git a/vendor/github.com/exoscale/egoscale/CHANGELOG.md b/vendor/github.com/exoscale/egoscale/CHANGELOG.md new file mode 100644 index 000000000..c222673c6 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/CHANGELOG.md @@ -0,0 +1,457 @@ +Changelog +========= + +0.18.1 +------ + +- change: make the "User-Agent" HTTP request header more informative and exposed + +0.18.0 +------ + +- feature: add method `DeepCopy` on type `AsyncJobResult` (#403) + +0.17.2 +------ + +- remove: remove the `IsFeatured` parameter from call `RegisterCustomTemplate` (#402) + +0.17.1 +------ + +- feature: add parameter `RescueProfile` to call `StartVirtualMachine` (#401) + +0.17.0 +------ + +- feature: add new call `RegisterCustomTemplate` (#400) +- feature: add new call `DeleteTemplate` (#399) + +0.16.0 +------ + +- feature: Add `Healthcheck*` parameters to call `UpdateIPAddress` +- change: Replace satori/go.uuid by gofrs/uuid + +0.15.0 +------ + +- change: prefix the healthcheck-related params with `Healthcheck` on call `AssociateIPAddress` +- EIP: the healthcheck should be a pointer +- ip addresses: Add the Healthcheck parameters +- readme: point to new lego org (#395) +- dns: user_id is not sent back (#394) + +0.14.3 +------ + +- fix: `AffinityGroup` lists virtual machines with `UUID` rather than string + +0.14.2 +------ + +- fix: `ListVirtualMachines` by `IDs` to accept `UUID` rather than string + +0.14.1 +------ + +- fix: `GetRunstatusPage` to always contain the subresources +- fix: `ListRunstatus*` to fetch all the subresources +- feature: `PaginateRunstatus*` used by list + +0.14.0 +------ + +- change: all DNS calls require a context +- fix: `CreateAffinityGroup` allows empty `name` + +0.13.3 +------ + +- fix: runstatus unmarshalling errors +- feature: `UUID` implements DeepCopy, DeepCopyInto +- change: export `BooleanResponse` + +0.13.2 +------ + +- feat: initial Runstatus API support +- feat: `admin` namespace containing `ListVirtualMachines` for admin usage + +0.13.1 +------ + +- feat: `Iso` support `ListIsos`, `AttachIso`, and `DetachIso` + +0.13.0 +------ + +- change: `Paginate` to accept `Listable` +- change: `ListCommand` is also `Listable` +- change: `client.Get` doesn't modify the given resource, returns a new one +- change: `Command` and `AsyncCommand` are fully public, thus extensible +- remove: `Gettable` + +0.12.5 +------ + +- fix: `AuthorizeSecurityGroupEgress` could return `authorizeSecurityGroupIngress` as name + +0.12.4 +------ + +- feat: `Snapshot` is `Listable` + +0.12.3 +------ + +- change: replace dep by Go modules +- change: remove domainid,domain,regionid,listall,isrecursive,... fields +- remove: `MigrateVirtualMachine`, `CreateUser`, `EnableAccount`, and other admin calls + +0.12.2 +------ + +- fix: `ListNics` has no virtualmachineid limitations anymore +- fix: `PCIDevice` ids are not UUIDs + +0.12.1 +------ + +- fix: `UpdateVMNicIP` is async + +0.12.0 +------ + +- feat: new VM state `Moving` +- feat: `UpdateNetwork` with `startip`, `endip`, `netmask` +- feat: `NetworkOffering` is `Listable` +- feat: when it fails parsing the body, it shows it +- fix: `Snapshot.State` is a string, rather than an scalar +- change: signature are now using the v3 version with expires by default + +0.11.6 +------ + +- fix: `Network.ListRequest` accepts a `Name` argument +- change: `SecurityGroup` and the rules aren't `Taggable` anymore + +0.11.5 +------ + +- feat: addition of `UpdateVMNicIP` +- fix: `UpdateVMAffinityGroup` expected response + +0.11.4 +------ + +*no changes in the core library* + +0.11.3 +------ + +*no changes in the core library* + +0.11.2 +------ + +- fix: empty list responses + +0.11.1 +------ + +- fix: `client.Sign` handles correctly the brackets (kudos to @stffabi) +- change: `client.Payload` returns a `url.Values` + +0.11.0 +------ + +- feat: `listOSCategories` and `OSCategory` type +- feat: `listApis` supports recursive response structures +- feat: `GetRecordsWithFilters` to list records with name or record_type filters +- fix: better `DNSErrorResponse` +- fix: `ListResourceLimits` type +- change: use UUID everywhere + +0.10.5 +------ + +- feat: `Client.Logger` to plug in any `*log.Logger` +- feat: `Client.TraceOn`/`ClientTraceOff` to toggle the HTTP tracing + +0.10.4 +------ + +- feat: `CIDR` to replace string string +- fix: prevent panic on nil + +0.10.3 +------ + +- feat: `Account` is Listable +- feat: `MACAddress` to replace string type +- fix: Go 1.7 support + +0.10.2 +------ + +- fix: ActivateIP6 response + +0.10.1 +------ + +- feat: expose `SyncRequest` and `SyncRequestWithContext` +- feat: addition of reverse DNS calls +- feat: addition of `SecurityGroup.UserSecurityGroup` + +0.10.0 +------ + +- global: cloudstack documentation links are moved into cs +- global: removal of all the `...Response` types +- feat: `Network` is `Listable` +- feat: addition of `deleteUser` +- feat: addition of `listHosts` +- feat: addition of `updateHost` +- feat: exo cmd (kudos to @pierre-emmanuelJ) +- change: refactor `Gettable` to use `ListRequest` + +0.9.31 +------ + +- fix: `IPAddress`.`ListRequest` with boolean fields +- fix: `Network`.`ListRequest` with boolean fields +- fix: `ServiceOffering`.`ListRequest` with boolean fields + +0.9.30 +------ + +- fix: `VirtualMachine` `PCIDevice` representation was incomplete + +0.9.29 +------ + +- change: `DNSErrorResponse` is a proper `error` + +0.9.28 +------ + +- feat: addition of `GetDomains` +- fix: `UpdateDomain` may contain more empty fields than `CreateDomain` + +0.9.27 +------ + +- fix: expects body to be `application/json` + +0.9.26 +------ + +- change: async timeout strategy wait two seconds and not fib(n) seconds + +0.9.25 +------ + +- fix: `GetVirtualUserData` response with `Decode` method handling base64 and gzip + +0.9.24 +------ + +- feat: `Template` is `Gettable` +- feat: `ServiceOffering` is `Gettable` +- feat: addition of `GetAPILimit` +- feat: addition of `CreateTemplate`, `PrepareTemplate`, `CopyTemplate`, `UpdateTemplate`, `RegisterTemplate` +- feat: addition of `MigrateVirtualMachine` +- feat: cmd cli +- change: remove useless fields related to Project and VPC + +0.9.23 +------ + +- feat: `booleanResponse` supports true booleans: https://github.com/apache/cloudstack/pull/2428 + +0.9.22 +------ + +- feat: `ListUsers`, `CreateUser`, `UpdateUser` +- feat: `ListResourceDetails` +- feat: `SecurityGroup` helper `RuleByID` +- feat: `Sign` signs the payload +- feat: `UpdateNetworkOffering` +- feat: `GetVirtualMachineUserData` +- feat: `EnableAccount` and `DisableAccount` (admin stuff) +- feat: `AsyncRequest` and `AsyncRequestWithContext` to examine the polling +- fix: `AuthorizeSecurityGroupIngress` support for ICMPv6 +- change: move `APIName()` into the `Client`, nice godoc +- change: `Payload` doesn't sign the request anymore +- change: `Client` exposes more of its underlying data +- change: requests are sent as GET unless it body size is too big + +0.9.21 +------ + +- feat: `Network` is `Listable` +- feat: `Zone` is `Gettable` +- feat: `Client.Payload` to help preview the HTTP parameters +- feat: generate command utility +- fix: `CreateSnapshot` was missing the `Name` attribute +- fix: `ListSnapshots` was missing the `IDs` attribute +- fix: `ListZones` was missing the `NetworkType` attribute +- fix: `ListAsyncJobs` was missing the `ListAll` attribute +- change: ICMP Type/Code are uint8 and TCP/UDP port are uint16 + +0.9.20 +------ + +- feat: `Template` is `Listable` +- feat: `IPAddress` is `Listable` +- change: `List` and `Paginate` return pointers +- fix: `Template` was missing `tags` + +0.9.19 +------ + +- feat: `SSHKeyPair` is `Listable` + +0.9.18 +------ + +- feat: `VirtualMachine` is `Listable` +- feat: new `Client.Paginate` and `Client.PaginateWithContext` +- change: the inner logic of `Listable` +- remove: not working `Client.AsyncList` + +0.9.17 +------ + +- fix: `AuthorizeSecurityGroup(In|E)gress` startport may be zero + +0.9.16 +------ + +- feat: new `Listable` interface +- feat: `Nic` is `Listable` +- feat: `Volume` is `Listable` +- feat: `Zone` is `Listable` +- feat: `AffinityGroup` is `Listable` +- remove: deprecated methods `ListNics`, `AddIPToNic`, and `RemoveIPFromNic` +- remove: deprecated method `GetRootVolumeForVirtualMachine` + +0.9.15 +------ + +- feat: `IPAddress` is `Gettable` and `Deletable` +- fix: serialization of *bool + +0.9.14 +------ + +- fix: `GetVMPassword` response +- remove: deprecated `GetTopology`, `GetImages`, and al + +0.9.13 +------ + +- feat: IP4 and IP6 flags to DeployVirtualMachine +- feat: add ActivateIP6 +- fix: error message was gobbled on 40x + +0.9.12 +------ + +- feat: add `BooleanRequestWithContext` +- feat: add `client.Get`, `client.GetWithContext` to fetch a resource +- feat: add `cleint.Delete`, `client.DeleteWithContext` to delete a resource +- feat: `SSHKeyPair` is `Gettable` and `Deletable` +- feat: `VirtualMachine` is `Gettable` and `Deletable` +- feat: `AffinityGroup` is `Gettable` and `Deletable` +- feat: `SecurityGroup` is `Gettable` and `Deletable` +- remove: deprecated methods `CreateAffinityGroup`, `DeleteAffinityGroup` +- remove: deprecated methods `CreateKeypair`, `DeleteKeypair`, `RegisterKeypair` +- remove: deprecated method `GetSecurityGroupID` + +0.9.11 +------ + +- feat: CloudStack API name is now public `APIName()` +- feat: enforce the mutual exclusivity of some fields +- feat: add `context.Context` to `RequestWithContext` +- change: `AsyncRequest` and `BooleanAsyncRequest` are gone, use `Request` and `BooleanRequest` instead. +- change: `AsyncInfo` is no more + +0.9.10 +------ + +- fix: typo made ListAll required in ListPublicIPAddresses +- fix: all bool are now *bool, respecting CS default value +- feat: (*VM).DefaultNic() to obtain the main Nic + +0.9.9 +----- + +- fix: affinity groups virtualmachineIds attribute +- fix: uuidList is not a list of strings + +0.9.8 +----- + +- feat: add RootDiskSize to RestoreVirtualMachine +- fix: monotonic polling using Context + +0.9.7 +----- + +- feat: add Taggable interface to expose ResourceType +- feat: add (Create|Update|Delete|List)InstanceGroup(s) +- feat: add RegisterUserKeys +- feat: add ListResourceLimits +- feat: add ListAccounts + +0.9.6 +----- + +- fix: update UpdateVirtualMachine userdata +- fix: Network's name/displaytext might be empty + +0.9.5 +----- + +- fix: serialization of slice + +0.9.4 +----- + +- fix: constants + +0.9.3 +----- + +- change: userdata expects a string +- change: no pointer in sub-struct's + +0.9.2 +----- + +- bug: createNetwork is a sync call +- bug: typo in listVirtualMachines' domainid +- bug: serialization of map[string], e.g. UpdateVirtualMachine +- change: IPAddress's use net.IP type +- feat: helpers VM.NicsByType, VM.NicByNetworkID, VM.NicByID +- feat: addition of CloudStack ApiErrorCode constants + +0.9.1 +----- + +- bug: sync calls returns succes as a string rather than a bool +- change: unexport BooleanResponse types +- feat: original CloudStack error response can be obtained + +0.9.0 +----- + +Big refactoring, addition of the documentation, compliance to golint. + +0.1.0 +----- + +Initial library diff --git a/vendor/github.com/exoscale/egoscale/LICENSE b/vendor/github.com/exoscale/egoscale/LICENSE new file mode 100644 index 000000000..327ecb823 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/LICENSE @@ -0,0 +1,201 @@ +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 2014 exoscale(tm) + + 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. diff --git a/vendor/github.com/exoscale/egoscale/README.md b/vendor/github.com/exoscale/egoscale/README.md new file mode 100644 index 000000000..bc40ec6b0 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/README.md @@ -0,0 +1,27 @@ +--- +title: Egoscale +description: the Go library for Exoscale +--- + + + +[![Build Status](https://travis-ci.org/exoscale/egoscale.svg?branch=master)](https://travis-ci.org/exoscale/egoscale) [![Maintainability](https://api.codeclimate.com/v1/badges/fcab3b624b7d3ca96a9d/maintainability)](https://codeclimate.com/github/exoscale/egoscale/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/fcab3b624b7d3ca96a9d/test_coverage)](https://codeclimate.com/github/exoscale/egoscale/test_coverage) [![GoDoc](https://godoc.org/github.com/exoscale/egoscale?status.svg)](https://godoc.org/github.com/exoscale/egoscale) [![Go Report Card](https://goreportcard.com/badge/github.com/exoscale/egoscale)](https://goreportcard.com/report/github.com/exoscale/egoscale) + +A wrapper for the [Exoscale public cloud](https://www.exoscale.com) API. + +## Known users + +- [Exoscale CLI](https://github.com/exoscale/cli) +- [Exoscale Terraform provider](https://github.com/exoscale/terraform-provider-exoscale) +- [ExoIP](https://github.com/exoscale/exoip): IP Watchdog +- [Lego](https://github.com/go-acme/lego): Let's Encrypt and ACME library +- Kubernetes Incubator: [External DNS](https://github.com/kubernetes-incubator/external-dns) +- [Docker machine](https://docs.docker.com/machine/drivers/exoscale/) +- [etc.](https://godoc.org/github.com/exoscale/egoscale?importers) + +## License + +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 diff --git a/vendor/github.com/exoscale/egoscale/accounts.go b/vendor/github.com/exoscale/egoscale/accounts.go new file mode 100644 index 000000000..9bcdec608 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/accounts.go @@ -0,0 +1,80 @@ +package egoscale + +// Account provides the detailed account information +type Account struct { + AccountDetails map[string]string `json:"accountdetails,omitempty" doc:"details for the account"` + CPUAvailable string `json:"cpuavailable,omitempty" doc:"the total number of cpu cores available to be created for this account"` + CPULimit string `json:"cpulimit,omitempty" doc:"the total number of cpu cores the account can own"` + CPUTotal int64 `json:"cputotal,omitempty" doc:"the total number of cpu cores owned by account"` + DefaultZoneID *UUID `json:"defaultzoneid,omitempty" doc:"the default zone of the account"` + EipLimit string `json:"eiplimit,omitempty" doc:"the total number of public elastic ip addresses this account can acquire"` + Groups []string `json:"groups,omitempty" doc:"the list of acl groups that account belongs to"` + ID *UUID `json:"id,omitempty" doc:"the id of the account"` + IPAvailable string `json:"ipavailable,omitempty" doc:"the total number of public ip addresses available for this account to acquire"` + IPLimit string `json:"iplimit,omitempty" doc:"the total number of public ip addresses this account can acquire"` + IPTotal int64 `json:"iptotal,omitempty" doc:"the total number of public ip addresses allocated for this account"` + IsCleanupRequired bool `json:"iscleanuprequired,omitempty" doc:"true if the account requires cleanup"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if account is default, false otherwise"` + MemoryAvailable string `json:"memoryavailable,omitempty" doc:"the total memory (in MB) available to be created for this account"` + MemoryLimit string `json:"memorylimit,omitempty" doc:"the total memory (in MB) the account can own"` + MemoryTotal int64 `json:"memorytotal,omitempty" doc:"the total memory (in MB) owned by account"` + Name string `json:"name,omitempty" doc:"the name of the account"` + NetworkAvailable string `json:"networkavailable,omitempty" doc:"the total number of networks available to be created for this account"` + NetworkDomain string `json:"networkdomain,omitempty" doc:"the network domain"` + NetworkLimit string `json:"networklimit,omitempty" doc:"the total number of networks the account can own"` + NetworkTotal int64 `json:"networktotal,omitempty" doc:"the total number of networks owned by account"` + PrimaryStorageAvailable string `json:"primarystorageavailable,omitempty" doc:"the total primary storage space (in GiB) available to be used for this account"` + PrimaryStorageLimit string `json:"primarystoragelimit,omitempty" doc:"the total primary storage space (in GiB) the account can own"` + PrimaryStorageTotal int64 `json:"primarystoragetotal,omitempty" doc:"the total primary storage space (in GiB) owned by account"` + ProjectAvailable string `json:"projectavailable,omitempty" doc:"the total number of projects available for administration by this account"` + ProjectLimit string `json:"projectlimit,omitempty" doc:"the total number of projects the account can own"` + ProjectTotal int64 `json:"projecttotal,omitempty" doc:"the total number of projects being administrated by this account"` + SecondaryStorageAvailable string `json:"secondarystorageavailable,omitempty" doc:"the total secondary storage space (in GiB) available to be used for this account"` + SecondaryStorageLimit string `json:"secondarystoragelimit,omitempty" doc:"the total secondary storage space (in GiB) the account can own"` + SecondaryStorageTotal int64 `json:"secondarystoragetotal,omitempty" doc:"the total secondary storage space (in GiB) owned by account"` + SMTP bool `json:"smtp,omitempty" doc:"if SMTP outbound is allowed"` + SnapshotAvailable string `json:"snapshotavailable,omitempty" doc:"the total number of snapshots available for this account"` + SnapshotLimit string `json:"snapshotlimit,omitempty" doc:"the total number of snapshots which can be stored by this account"` + SnapshotTotal int64 `json:"snapshottotal,omitempty" doc:"the total number of snapshots stored by this account"` + State string `json:"state,omitempty" doc:"the state of the account"` + TemplateAvailable string `json:"templateavailable,omitempty" doc:"the total number of templates available to be created by this account"` + TemplateLimit string `json:"templatelimit,omitempty" doc:"the total number of templates which can be created by this account"` + TemplateTotal int64 `json:"templatetotal,omitempty" doc:"the total number of templates which have been created by this account"` + User []User `json:"user,omitempty" doc:"the list of users associated with account"` + VMAvailable string `json:"vmavailable,omitempty" doc:"the total number of virtual machines available for this account to acquire"` + VMLimit string `json:"vmlimit,omitempty" doc:"the total number of virtual machines that can be deployed by this account"` + VMRunning int `json:"vmrunning,omitempty" doc:"the total number of virtual machines running for this account"` + VMStopped int `json:"vmstopped,omitempty" doc:"the total number of virtual machines stopped for this account"` + VMTotal int64 `json:"vmtotal,omitempty" doc:"the total number of virtual machines deployed by this account"` + VolumeAvailable string `json:"volumeavailable,omitempty" doc:"the total volume available for this account"` + VolumeLimit string `json:"volumelimit,omitempty" doc:"the total volume which can be used by this account"` + VolumeTotal int64 `json:"volumetotal,omitempty" doc:"the total volume being used by this account"` +} + +// ListRequest builds the ListAccountsGroups request +func (a Account) ListRequest() (ListCommand, error) { + return &ListAccounts{ + ID: a.ID, + State: a.State, + }, nil +} + +//go:generate go run generate/main.go -interface=Listable ListAccounts + +// ListAccounts represents a query to display the accounts +type ListAccounts struct { + ID *UUID `json:"id,omitempty" doc:"List account by account ID"` + IsCleanUpRequired *bool `json:"iscleanuprequired,omitempty" doc:"list accounts by cleanuprequired attribute (values are true or false)"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"List account by account name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + State string `json:"state,omitempty" doc:"List accounts by state. Valid states are enabled, disabled, and locked."` + _ bool `name:"listAccounts" description:"Lists accounts and provides detailed account information for listed accounts"` +} + +// ListAccountsResponse represents a list of accounts +type ListAccountsResponse struct { + Count int `json:"count"` + Account []Account `json:"account"` +} diff --git a/vendor/github.com/exoscale/egoscale/accounts_response.go b/vendor/github.com/exoscale/egoscale/accounts_response.go new file mode 100644 index 000000000..106daca32 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/accounts_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListAccounts) Response() interface{} { + return new(ListAccountsResponse) +} + +// ListRequest returns itself +func (ls *ListAccounts) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListAccounts) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListAccounts) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListAccounts) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListAccountsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListAccountsResponse was expected, got %T", resp)) + return + } + + for i := range items.Account { + if !callback(&items.Account[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/addresses.go b/vendor/github.com/exoscale/egoscale/addresses.go new file mode 100644 index 000000000..d828f52e0 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/addresses.go @@ -0,0 +1,179 @@ +package egoscale + +import ( + "context" + "fmt" + "net" +) + +// Healthcheck represents an Healthcheck attached to an IP +type Healthcheck struct { + Interval int64 `json:"interval,omitempty" doc:"healthcheck definition: time in seconds to wait for each check. Default: 10, minimum: 5"` + Mode string `json:"mode,omitempty" doc:"healthcheck definition: healthcheck mode can be either 'tcp' or 'http'"` + Path string `json:"path,omitempty" doc:"healthcheck definition: the path against which the 'http' healthcheck will be performed. Required if mode is 'http', ignored otherwise."` + Port int64 `json:"port,omitempty" doc:"healthcheck definition: the port against which the healthcheck will be performed. Required if a 'mode' is provided."` + StrikesFail int64 `json:"strikes-fail,omitempty" doc:"healthcheck definition: number of times to retry before declaring the healthcheck 'dead'. Default: 3"` + StrikesOk int64 `json:"strikes-ok,omitempty" doc:"healthcheck definition: number of times to retry before declaring the healthcheck 'alive'. Default: 2"` + Timeout int64 `json:"timeout,omitempty" doc:"healthcheck definition: time in seconds to wait for each check. Default: 2, cannot be greater than interval."` +} + +// IPAddress represents an IP Address +type IPAddress struct { + Allocated string `json:"allocated,omitempty" doc:"date the public IP address was acquired"` + Associated string `json:"associated,omitempty" doc:"date the public IP address was associated"` + AssociatedNetworkID *UUID `json:"associatednetworkid,omitempty" doc:"the ID of the Network associated with the IP address"` + AssociatedNetworkName string `json:"associatednetworkname,omitempty" doc:"the name of the Network associated with the IP address"` + ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty" doc:"the virtual network for the IP address"` + Healthcheck *Healthcheck `json:"healthcheck,omitempty" doc:"The IP healthcheck configuration"` + ID *UUID `json:"id,omitempty" doc:"public IP address id"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"public IP address"` + IsElastic bool `json:"iselastic,omitempty" doc:"is an elastic ip"` + IsPortable bool `json:"isportable,omitempty" doc:"is public IP portable across the zones"` + IsSourceNat bool `json:"issourcenat,omitempty" doc:"true if the IP address is a source nat address, false otherwise"` + IsStaticNat *bool `json:"isstaticnat,omitempty" doc:"true if this ip is for static nat, false otherwise"` + IsSystem bool `json:"issystem,omitempty" doc:"true if this ip is system ip (was allocated as a part of deployVm or createLbRule)"` + NetworkID *UUID `json:"networkid,omitempty" doc:"the ID of the Network where ip belongs to"` + PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"the physical network this belongs to"` + Purpose string `json:"purpose,omitempty" doc:"purpose of the IP address. In Acton this value is not null for Ips with isSystem=true, and can have either StaticNat or LB value"` + ReverseDNS []ReverseDNS `json:"reversedns,omitempty" doc:"the list of PTR record(s) associated with the ip address"` + State string `json:"state,omitempty" doc:"State of the ip address. Can be: Allocatin, Allocated and Releasing"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with ip address"` + VirtualMachineDisplayName string `json:"virtualmachinedisplayname,omitempty" doc:"virtual machine display name the ip address is assigned to (not null only for static nat Ip)"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"virtual machine id the ip address is assigned to (not null only for static nat Ip)"` + VirtualMachineName string `json:"virtualmachinename,omitempty" doc:"virtual machine name the ip address is assigned to (not null only for static nat Ip)"` + VlanID *UUID `json:"vlanid,omitempty" doc:"the ID of the VLAN associated with the IP address. This parameter is visible to ROOT admins only"` + VlanName string `json:"vlanname,omitempty" doc:"the VLAN associated with the IP address"` + VMIPAddress net.IP `json:"vmipaddress,omitempty" doc:"virtual machine (dnat) ip address (not null only for static nat Ip)"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"the ID of the zone the public IP address belongs to"` + ZoneName string `json:"zonename,omitempty" doc:"the name of the zone the public IP address belongs to"` +} + +// ResourceType returns the type of the resource +func (IPAddress) ResourceType() string { + return "PublicIpAddress" +} + +// ListRequest builds the ListAdresses request +func (ipaddress IPAddress) ListRequest() (ListCommand, error) { + req := &ListPublicIPAddresses{ + AssociatedNetworkID: ipaddress.AssociatedNetworkID, + ID: ipaddress.ID, + IPAddress: ipaddress.IPAddress, + PhysicalNetworkID: ipaddress.PhysicalNetworkID, + VlanID: ipaddress.VlanID, + ZoneID: ipaddress.ZoneID, + } + if ipaddress.IsElastic { + req.IsElastic = &ipaddress.IsElastic + } + if ipaddress.IsSourceNat { + req.IsSourceNat = &ipaddress.IsSourceNat + } + if ipaddress.ForVirtualNetwork { + req.ForVirtualNetwork = &ipaddress.ForVirtualNetwork + } + + return req, nil +} + +// Delete removes the resource +func (ipaddress IPAddress) Delete(ctx context.Context, client *Client) error { + if ipaddress.ID == nil { + return fmt.Errorf("an IPAddress may only be deleted using ID") + } + + return client.BooleanRequestWithContext(ctx, &DisassociateIPAddress{ + ID: ipaddress.ID, + }) +} + +// AssociateIPAddress (Async) represents the IP creation +type AssociateIPAddress struct { + HealthcheckInterval int64 `json:"interval,omitempty" doc:"healthcheck definition: time in seconds to wait for each check. Default: 10, minimum: 5"` + HealthcheckMode string `json:"mode,omitempty" doc:"healthcheck definition: healthcheck mode can be either 'tcp' or 'http'"` + HealthcheckPath string `json:"path,omitempty" doc:"healthcheck definition: the path against which the 'http' healthcheck will be performed. Required if mode is 'http', ignored otherwise."` + HealthcheckPort int64 `json:"port,omitempty" doc:"healthcheck definition: the port against which the healthcheck will be performed. Required if a 'mode' is provided."` + HealthcheckStrikesFail int64 `json:"strikes-fail,omitempty" doc:"healthcheck definition: number of times to retry before declaring the healthcheck 'dead'. Default: 3"` + HealthcheckStrikesOk int64 `json:"strikes-ok,omitempty" doc:"healthcheck definition: number of times to retry before declaring the healthcheck 'alive'. Default: 2"` + HealthcheckTimeout int64 `json:"timeout,omitempty" doc:"healthcheck definition: time in seconds to wait for each check. Default: 2, cannot be greater than interval."` + ZoneID *UUID `json:"zoneid,omitempty" doc:"the ID of the availability zone you want to acquire a public IP address from"` + _ bool `name:"associateIpAddress" description:"Acquires and associates a public IP to an account."` +} + +// Response returns the struct to unmarshal +func (AssociateIPAddress) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (AssociateIPAddress) AsyncResponse() interface{} { + return new(IPAddress) +} + +// DisassociateIPAddress (Async) represents the IP deletion +type DisassociateIPAddress struct { + ID *UUID `json:"id" doc:"the id of the public ip address to disassociate"` + _ bool `name:"disassociateIpAddress" description:"Disassociates an ip address from the account."` +} + +// Response returns the struct to unmarshal +func (DisassociateIPAddress) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DisassociateIPAddress) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +// UpdateIPAddress (Async) represents the IP modification +type UpdateIPAddress struct { + HealthcheckInterval int64 `json:"interval,omitempty" doc:"healthcheck definition: time in seconds to wait for each check. Default: 10, minimum: 5"` + HealthcheckMode string `json:"mode,omitempty" doc:"healthcheck definition: healthcheck mode can be either 'tcp' or 'http'"` + HealthcheckPath string `json:"path,omitempty" doc:"healthcheck definition: the path against which the 'http' healthcheck will be performed. Required if mode is 'http', ignored otherwise."` + HealthcheckPort int64 `json:"port,omitempty" doc:"healthcheck definition: the port against which the healthcheck will be performed. Required if a 'mode' is provided."` + HealthcheckStrikesFail int64 `json:"strikes-fail,omitempty" doc:"healthcheck definition: number of times to retry before declaring the healthcheck 'dead'. Default: 3"` + HealthcheckStrikesOk int64 `json:"strikes-ok,omitempty" doc:"healthcheck definition: number of times to retry before declaring the healthcheck 'alive'. Default: 2"` + HealthcheckTimeout int64 `json:"timeout,omitempty" doc:"healthcheck definition: time in seconds to wait for each check. Default: 2, cannot be greater than interval."` + ID *UUID `json:"id" doc:"the id of the public IP address to update"` + _ bool `name:"updateIpAddress" description:"Updates an IP address"` +} + +// Response returns the struct to unmarshal +func (UpdateIPAddress) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (UpdateIPAddress) AsyncResponse() interface{} { + return new(IPAddress) +} + +//go:generate go run generate/main.go -interface=Listable ListPublicIPAddresses + +// ListPublicIPAddresses represents a search for public IP addresses +type ListPublicIPAddresses struct { + AllocatedOnly *bool `json:"allocatedonly,omitempty" doc:"limits search results to allocated public IP addresses"` + AssociatedNetworkID *UUID `json:"associatednetworkid,omitempty" doc:"lists all public IP addresses associated to the network specified"` + ForLoadBalancing *bool `json:"forloadbalancing,omitempty" doc:"list only ips used for load balancing"` + ForVirtualNetwork *bool `json:"forvirtualnetwork,omitempty" doc:"the virtual network for the IP address"` + ID *UUID `json:"id,omitempty" doc:"lists ip address by id"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"lists the specified IP address"` + IsElastic *bool `json:"iselastic,omitempty" doc:"list only elastic ip addresses"` + IsSourceNat *bool `json:"issourcenat,omitempty" doc:"list only source nat ip addresses"` + IsStaticNat *bool `json:"isstaticnat,omitempty" doc:"list only static nat ip addresses"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"lists all public IP addresses by physical network id"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + VlanID *UUID `json:"vlanid,omitempty" doc:"lists all public IP addresses by VLAN ID"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"lists all public IP addresses by Zone ID"` + _ bool `name:"listPublicIpAddresses" description:"Lists all public ip addresses"` +} + +// ListPublicIPAddressesResponse represents a list of public IP addresses +type ListPublicIPAddressesResponse struct { + Count int `json:"count"` + PublicIPAddress []IPAddress `json:"publicipaddress"` +} diff --git a/vendor/github.com/exoscale/egoscale/affinity_groups.go b/vendor/github.com/exoscale/egoscale/affinity_groups.go new file mode 100644 index 000000000..61b979a28 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/affinity_groups.go @@ -0,0 +1,158 @@ +package egoscale + +import ( + "context" + "fmt" + "net/url" +) + +// AffinityGroup represents an (anti-)affinity group +// +// Affinity and Anti-Affinity groups provide a way to influence where VMs should run. +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html#affinity-groups +type AffinityGroup struct { + Account string `json:"account,omitempty" doc:"the account owning the affinity group"` + Description string `json:"description,omitempty" doc:"the description of the affinity group"` + ID *UUID `json:"id,omitempty" doc:"the ID of the affinity group"` + Name string `json:"name,omitempty" doc:"the name of the affinity group"` + Type string `json:"type,omitempty" doc:"the type of the affinity group"` + VirtualMachineIDs []UUID `json:"virtualmachineIds,omitempty" doc:"virtual machine Ids associated with this affinity group"` +} + +// ListRequest builds the ListAffinityGroups request +func (ag AffinityGroup) ListRequest() (ListCommand, error) { + return &ListAffinityGroups{ + ID: ag.ID, + Name: ag.Name, + }, nil +} + +// Delete removes the given Affinity Group +func (ag AffinityGroup) Delete(ctx context.Context, client *Client) error { + if ag.ID == nil && ag.Name == "" { + return fmt.Errorf("an Affinity Group may only be deleted using ID or Name") + } + + req := &DeleteAffinityGroup{} + + if ag.ID != nil { + req.ID = ag.ID + } else { + req.Name = ag.Name + } + + return client.BooleanRequestWithContext(ctx, req) +} + +// AffinityGroupType represent an affinity group type +type AffinityGroupType struct { + Type string `json:"type,omitempty" doc:"the type of the affinity group"` +} + +// CreateAffinityGroup (Async) represents a new (anti-)affinity group +type CreateAffinityGroup struct { + Description string `json:"description,omitempty" doc:"Optional description of the affinity group"` + Name string `json:"name,omitempty" doc:"Name of the affinity group"` + Type string `json:"type" doc:"Type of the affinity group from the available affinity/anti-affinity group types"` + _ bool `name:"createAffinityGroup" description:"Creates an affinity/anti-affinity group"` +} + +func (req CreateAffinityGroup) onBeforeSend(params url.Values) error { + // Name must be set, but can be empty + if req.Name == "" { + params.Set("name", "") + } + return nil +} + +// Response returns the struct to unmarshal +func (CreateAffinityGroup) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (CreateAffinityGroup) AsyncResponse() interface{} { + return new(AffinityGroup) +} + +// UpdateVMAffinityGroup (Async) represents a modification of a (anti-)affinity group +type UpdateVMAffinityGroup struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + AffinityGroupIDs []UUID `json:"affinitygroupids,omitempty" doc:"comma separated list of affinity groups id that are going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupnames parameter"` + AffinityGroupNames []string `json:"affinitygroupnames,omitempty" doc:"comma separated list of affinity groups names that are going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupids parameter"` + _ bool `name:"updateVMAffinityGroup" description:"Updates the affinity/anti-affinity group associations of a virtual machine. The VM has to be stopped and restarted for the new properties to take effect."` +} + +func (req UpdateVMAffinityGroup) onBeforeSend(params url.Values) error { + // Either AffinityGroupIDs or AffinityGroupNames must be set + if len(req.AffinityGroupIDs) == 0 && len(req.AffinityGroupNames) == 0 { + params.Set("affinitygroupids", "") + } + return nil +} + +// Response returns the struct to unmarshal +func (UpdateVMAffinityGroup) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (UpdateVMAffinityGroup) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// DeleteAffinityGroup (Async) represents an (anti-)affinity group to be deleted +type DeleteAffinityGroup struct { + ID *UUID `json:"id,omitempty" doc:"The ID of the affinity group. Mutually exclusive with name parameter"` + Name string `json:"name,omitempty" doc:"The name of the affinity group. Mutually exclusive with ID parameter"` + _ bool `name:"deleteAffinityGroup" description:"Deletes affinity group"` +} + +// Response returns the struct to unmarshal +func (DeleteAffinityGroup) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DeleteAffinityGroup) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +//go:generate go run generate/main.go -interface=Listable ListAffinityGroups + +// ListAffinityGroups represents an (anti-)affinity groups search +type ListAffinityGroups struct { + ID *UUID `json:"id,omitempty" doc:"List the affinity group by the ID provided"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"Lists affinity groups by name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + Type string `json:"type,omitempty" doc:"Lists affinity groups by type"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"Lists affinity groups by virtual machine ID"` + _ bool `name:"listAffinityGroups" description:"Lists affinity groups"` +} + +// ListAffinityGroupsResponse represents a list of (anti-)affinity groups +type ListAffinityGroupsResponse struct { + Count int `json:"count"` + AffinityGroup []AffinityGroup `json:"affinitygroup"` +} + +// ListAffinityGroupTypes represents an (anti-)affinity groups search +type ListAffinityGroupTypes struct { + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + _ bool `name:"listAffinityGroupTypes" description:"Lists affinity group types available"` +} + +// Response returns the struct to unmarshal +func (ListAffinityGroupTypes) Response() interface{} { + return new(ListAffinityGroupTypesResponse) +} + +// ListAffinityGroupTypesResponse represents a list of (anti-)affinity group types +type ListAffinityGroupTypesResponse struct { + Count int `json:"count"` + AffinityGroupType []AffinityGroupType `json:"affinitygrouptype"` +} diff --git a/vendor/github.com/exoscale/egoscale/affinitygroups_response.go b/vendor/github.com/exoscale/egoscale/affinitygroups_response.go new file mode 100644 index 000000000..12c5bd747 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/affinitygroups_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListAffinityGroups) Response() interface{} { + return new(ListAffinityGroupsResponse) +} + +// ListRequest returns itself +func (ls *ListAffinityGroups) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListAffinityGroups) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListAffinityGroups) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListAffinityGroups) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListAffinityGroupsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListAffinityGroupsResponse was expected, got %T", resp)) + return + } + + for i := range items.AffinityGroup { + if !callback(&items.AffinityGroup[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/apis.go b/vendor/github.com/exoscale/egoscale/apis.go new file mode 100644 index 000000000..098a03761 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/apis.go @@ -0,0 +1,48 @@ +package egoscale + +// API represents an API service +type API struct { + Description string `json:"description,omitempty" doc:"description of the api"` + IsAsync bool `json:"isasync" doc:"true if api is asynchronous"` + Name string `json:"name,omitempty" doc:"the name of the api command"` + Related string `json:"related,omitempty" doc:"comma separated related apis"` + Since string `json:"since,omitempty" doc:"version of CloudStack the api was introduced in"` + Type string `json:"type,omitempty" doc:"response field type"` + Params []APIParam `json:"params,omitempty" doc:"the list params the api accepts"` + Response []APIField `json:"response,omitempty" doc:"api response fields"` +} + +// APIParam represents an API parameter field +type APIParam struct { + Description string `json:"description"` + Length int64 `json:"length"` + Name string `json:"name"` + Required bool `json:"required"` + Since string `json:"since,omitempty"` + Type string `json:"type"` +} + +// APIField represents an API response field +type APIField struct { + Description string `json:"description"` + Name string `json:"name"` + Response []APIField `json:"response,omitempty"` + Type string `json:"type"` +} + +// ListAPIs represents a query to list the api +type ListAPIs struct { + Name string `json:"name,omitempty" doc:"API name"` + _ bool `name:"listApis" description:"lists all available apis on the server"` +} + +// ListAPIsResponse represents a list of API +type ListAPIsResponse struct { + Count int `json:"count"` + API []API `json:"api"` +} + +// Response returns the struct to unmarshal +func (*ListAPIs) Response() interface{} { + return new(ListAPIsResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/async_jobs.go b/vendor/github.com/exoscale/egoscale/async_jobs.go new file mode 100644 index 000000000..ab4b52cff --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/async_jobs.go @@ -0,0 +1,138 @@ +package egoscale + +import ( + "encoding/json" + "errors" +) + +// AsyncJobResult represents an asynchronous job result +type AsyncJobResult struct { + AccountID *UUID `json:"accountid,omitempty" doc:"the account that executed the async command"` + Cmd string `json:"cmd,omitempty" doc:"the async command executed"` + Created string `json:"created,omitempty" doc:"the created date of the job"` + JobID *UUID `json:"jobid" doc:"extra field for the initial async call"` + JobInstanceID *UUID `json:"jobinstanceid,omitempty" doc:"the unique ID of the instance/entity object related to the job"` + JobInstanceType string `json:"jobinstancetype,omitempty" doc:"the instance/entity object related to the job"` + JobProcStatus int `json:"jobprocstatus,omitempty" doc:"the progress information of the PENDING job"` + JobResult *json.RawMessage `json:"jobresult,omitempty" doc:"the result reason"` + JobResultCode int `json:"jobresultcode,omitempty" doc:"the result code for the job"` + JobResultType string `json:"jobresulttype,omitempty" doc:"the result type"` + JobStatus JobStatusType `json:"jobstatus,omitempty" doc:"the current job status-should be 0 for PENDING"` + UserID *UUID `json:"userid,omitempty" doc:"the user that executed the async command"` +} + +// DeepCopy create a true copy of the receiver. +func (a *AsyncJobResult) DeepCopy() *AsyncJobResult { + if a == nil { + return nil + } + + return &AsyncJobResult{ + AccountID: a.AccountID.DeepCopy(), + Cmd: a.Cmd, + Created: a.Created, + JobID: a.JobID.DeepCopy(), + JobInstanceID: a.JobInstanceID.DeepCopy(), + JobInstanceType: a.JobInstanceType, + JobProcStatus: a.JobProcStatus, + JobResult: a.JobResult, + JobResultCode: a.JobResultCode, + JobResultType: a.JobResultType, + JobStatus: a.JobStatus, + UserID: a.UserID.DeepCopy(), + } +} + +// DeepCopyInto copies the receiver into out. +// +// In (a) must be non nil. out must be non nil +func (a *AsyncJobResult) DeepCopyInto(out *AsyncJobResult) { + *out = AsyncJobResult{ + AccountID: a.AccountID.DeepCopy(), + Cmd: a.Cmd, + Created: a.Created, + JobID: a.JobID.DeepCopy(), + JobInstanceID: a.JobInstanceID.DeepCopy(), + JobInstanceType: a.JobInstanceType, + JobProcStatus: a.JobProcStatus, + JobResult: a.JobResult, + JobResultCode: a.JobResultCode, + JobResultType: a.JobResultType, + JobStatus: a.JobStatus, + UserID: a.UserID.DeepCopy(), + } +} + +// ListRequest buils the (empty) ListAsyncJobs request +func (a AsyncJobResult) ListRequest() (ListCommand, error) { + req := &ListAsyncJobs{ + StartDate: a.Created, + } + + return req, nil +} + +// Error builds an error message from the result +func (a AsyncJobResult) Error() error { + r := new(ErrorResponse) + if e := json.Unmarshal(*a.JobResult, r); e != nil { + return e + } + return r +} + +// QueryAsyncJobResult represents a query to fetch the status of async job +type QueryAsyncJobResult struct { + JobID *UUID `json:"jobid" doc:"the ID of the asynchronous job"` + _ bool `name:"queryAsyncJobResult" description:"Retrieves the current status of asynchronous job."` +} + +// Response returns the struct to unmarshal +func (QueryAsyncJobResult) Response() interface{} { + return new(AsyncJobResult) +} + +//go:generate go run generate/main.go -interface=Listable ListAsyncJobs + +// ListAsyncJobs list the asynchronous jobs +type ListAsyncJobs struct { + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + StartDate string `json:"startdate,omitempty" doc:"the start date of the async job"` + _ bool `name:"listAsyncJobs" description:"Lists all pending asynchronous jobs for the account."` +} + +// ListAsyncJobsResponse represents a list of job results +type ListAsyncJobsResponse struct { + Count int `json:"count"` + AsyncJob []AsyncJobResult `json:"asyncjobs"` +} + +// Result unmarshals the result of an AsyncJobResult into the given interface +func (a AsyncJobResult) Result(i interface{}) error { + if a.JobStatus == Failure { + return a.Error() + } + + if a.JobStatus == Success { + m := map[string]json.RawMessage{} + err := json.Unmarshal(*(a.JobResult), &m) + + if err == nil { + if len(m) >= 1 { + if _, ok := m["success"]; ok { + return json.Unmarshal(*(a.JobResult), i) + } + + // otherwise, pick the first key + for k := range m { + return json.Unmarshal(m[k], i) + } + } + return errors.New("empty response") + } + } + + return nil +} diff --git a/vendor/github.com/exoscale/egoscale/asyncjobs_response.go b/vendor/github.com/exoscale/egoscale/asyncjobs_response.go new file mode 100644 index 000000000..e4744e8bd --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/asyncjobs_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListAsyncJobs) Response() interface{} { + return new(ListAsyncJobsResponse) +} + +// ListRequest returns itself +func (ls *ListAsyncJobs) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListAsyncJobs) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListAsyncJobs) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListAsyncJobs) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListAsyncJobsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListAsyncJobsResponse was expected, got %T", resp)) + return + } + + for i := range items.AsyncJob { + if !callback(&items.AsyncJob[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/cidr.go b/vendor/github.com/exoscale/egoscale/cidr.go new file mode 100644 index 000000000..74c054b71 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/cidr.go @@ -0,0 +1,62 @@ +package egoscale + +import ( + "bytes" + "encoding/json" + "fmt" + "net" +) + +// CIDR represents a nicely JSON serializable net.IPNet +type CIDR struct { + net.IPNet +} + +// UnmarshalJSON unmarshals the raw JSON into the MAC address +func (cidr *CIDR) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + c, err := ParseCIDR(s) + if err != nil { + return err + } + *cidr = CIDR{c.IPNet} + + return nil +} + +// MarshalJSON converts the CIDR to a string representation +func (cidr CIDR) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf("%q", cidr)), nil +} + +// String returns the string representation of a CIDR +func (cidr CIDR) String() string { + return cidr.IPNet.String() +} + +// ParseCIDR parses a CIDR from a string +func ParseCIDR(s string) (*CIDR, error) { + _, net, err := net.ParseCIDR(s) + if err != nil { + return nil, err + } + return &CIDR{*net}, nil +} + +// MustParseCIDR forces parseCIDR or panics +func MustParseCIDR(s string) *CIDR { + cidr, err := ParseCIDR(s) + if err != nil { + panic(err) + } + + return cidr +} + +// Equal compare two CIDR +func (cidr CIDR) Equal(c CIDR) bool { + return (cidr.IPNet.IP.Equal(c.IPNet.IP) && bytes.Equal(cidr.IPNet.Mask, c.IPNet.Mask)) +} diff --git a/vendor/github.com/exoscale/egoscale/client.go b/vendor/github.com/exoscale/egoscale/client.go new file mode 100644 index 000000000..81c5f07b6 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/client.go @@ -0,0 +1,418 @@ +package egoscale + +import ( + "context" + "fmt" + "io/ioutil" + "log" + "net/http" + "net/http/httputil" + "os" + "reflect" + "runtime" + "strings" + "time" +) + +// UserAgent is the "User-Agent" HTTP request header added to outgoing HTTP requests. +var UserAgent = fmt.Sprintf("egoscale/%s (%s; %s/%s)", + Version, + runtime.Version(), + runtime.GOOS, + runtime.GOARCH) + +// Taggable represents a resource to which tags can be attached +// +// This is a helper to fill the resourcetype of a CreateTags call +type Taggable interface { + // ResourceType is the name of the Taggable type + ResourceType() string +} + +// Deletable represents an Interface that can be "Delete" by the client +type Deletable interface { + // Delete removes the given resource(s) or throws + Delete(context context.Context, client *Client) error +} + +// Listable represents an Interface that can be "List" by the client +type Listable interface { + // ListRequest builds the list command + ListRequest() (ListCommand, error) +} + +// Client represents the API client +type Client struct { + // HTTPClient holds the HTTP client + HTTPClient *http.Client + // Endpoint is the HTTP URL + Endpoint string + // APIKey is the API identifier + APIKey string + // apisecret is the API secret, hence non exposed + apiSecret string + // PageSize represents the default size for a paginated result + PageSize int + // Timeout represents the default timeout for the async requests + Timeout time.Duration + // Expiration representation how long a signed payload may be used + Expiration time.Duration + // RetryStrategy represents the waiting strategy for polling the async requests + RetryStrategy RetryStrategyFunc + // Logger contains any log, plug your own + Logger *log.Logger +} + +// RetryStrategyFunc represents a how much time to wait between two calls to the API +type RetryStrategyFunc func(int64) time.Duration + +// IterateItemFunc represents the callback to iterate a list of results, if false stops +type IterateItemFunc func(interface{}, error) bool + +// WaitAsyncJobResultFunc represents the callback to wait a results of an async request, if false stops +type WaitAsyncJobResultFunc func(*AsyncJobResult, error) bool + +// NewClient creates an API client with default timeout (60) +// +// Timeout is set to both the HTTP client and the client itself. +func NewClient(endpoint, apiKey, apiSecret string) *Client { + timeout := 60 * time.Second + expiration := 10 * time.Minute + + httpClient := &http.Client{ + Transport: http.DefaultTransport, + } + + client := &Client{ + HTTPClient: httpClient, + Endpoint: endpoint, + APIKey: apiKey, + apiSecret: apiSecret, + PageSize: 50, + Timeout: timeout, + Expiration: expiration, + RetryStrategy: MonotonicRetryStrategyFunc(2), + Logger: log.New(ioutil.Discard, "", 0), + } + + if prefix, ok := os.LookupEnv("EXOSCALE_TRACE"); ok { + client.Logger = log.New(os.Stderr, prefix, log.LstdFlags) + client.TraceOn() + } + + return client +} + +// Get populates the given resource or fails +func (client *Client) Get(ls Listable) (interface{}, error) { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + return client.GetWithContext(ctx, ls) +} + +// GetWithContext populates the given resource or fails +func (client *Client) GetWithContext(ctx context.Context, ls Listable) (interface{}, error) { + gs, err := client.ListWithContext(ctx, ls) + if err != nil { + return nil, err + } + + count := len(gs) + if count != 1 { + req, err := ls.ListRequest() + if err != nil { + return nil, err + } + params, err := client.Payload(req) + if err != nil { + return nil, err + } + + // removing sensitive/useless informations + params.Del("expires") + params.Del("response") + params.Del("signature") + params.Del("signatureversion") + + // formatting the query string nicely + payload := params.Encode() + payload = strings.Replace(payload, "&", ", ", -1) + + if count == 0 { + return nil, &ErrorResponse{ + CSErrorCode: ServerAPIException, + ErrorCode: ParamError, + ErrorText: fmt.Sprintf("not found, query: %s", payload), + } + } + return nil, fmt.Errorf("more than one element found: %s", payload) + } + + return gs[0], nil +} + +// Delete removes the given resource of fails +func (client *Client) Delete(g Deletable) error { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + return client.DeleteWithContext(ctx, g) +} + +// DeleteWithContext removes the given resource of fails +func (client *Client) DeleteWithContext(ctx context.Context, g Deletable) error { + return g.Delete(ctx, client) +} + +// List lists the given resource (and paginate till the end) +func (client *Client) List(g Listable) ([]interface{}, error) { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + return client.ListWithContext(ctx, g) +} + +// ListWithContext lists the given resources (and paginate till the end) +func (client *Client) ListWithContext(ctx context.Context, g Listable) (s []interface{}, err error) { + s = make([]interface{}, 0) + + defer func() { + if e := recover(); e != nil { + if g == nil || reflect.ValueOf(g).IsNil() { + err = fmt.Errorf("g Listable shouldn't be nil, got %#v", g) + return + } + + panic(e) + } + }() + + req, e := g.ListRequest() + if e != nil { + err = e + return + } + client.PaginateWithContext(ctx, req, func(item interface{}, e error) bool { + if item != nil { + s = append(s, item) + return true + } + err = e + return false + }) + + return +} + +// AsyncListWithContext lists the given resources (and paginate till the end) +// +// +// // NB: goroutine may leak if not read until the end. Create a proper context! +// ctx, cancel := context.WithCancel(context.Background()) +// defer cancel() +// +// outChan, errChan := client.AsyncListWithContext(ctx, new(egoscale.VirtualMachine)) +// +// for { +// select { +// case i, ok := <- outChan: +// if ok { +// vm := i.(egoscale.VirtualMachine) +// // ... +// } else { +// outChan = nil +// } +// case err, ok := <- errChan: +// if ok { +// // do something +// } +// // Once an error has been received, you can expect the channels to be closed. +// errChan = nil +// } +// if errChan == nil && outChan == nil { +// break +// } +// } +// +func (client *Client) AsyncListWithContext(ctx context.Context, g Listable) (<-chan interface{}, <-chan error) { + outChan := make(chan interface{}, client.PageSize) + errChan := make(chan error) + + go func() { + defer close(outChan) + defer close(errChan) + + req, err := g.ListRequest() + if err != nil { + errChan <- err + return + } + client.PaginateWithContext(ctx, req, func(item interface{}, e error) bool { + if item != nil { + outChan <- item + return true + } + errChan <- e + return false + }) + }() + + return outChan, errChan +} + +// Paginate runs the ListCommand and paginates +func (client *Client) Paginate(g Listable, callback IterateItemFunc) { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + client.PaginateWithContext(ctx, g, callback) +} + +// PaginateWithContext runs the ListCommand as long as the ctx is valid +func (client *Client) PaginateWithContext(ctx context.Context, g Listable, callback IterateItemFunc) { + req, err := g.ListRequest() + if err != nil { + callback(nil, err) + return + } + + pageSize := client.PageSize + + page := 1 + + for { + req.SetPage(page) + req.SetPageSize(pageSize) + resp, err := client.RequestWithContext(ctx, req) + if err != nil { + // in case of 431, the response is knowingly empty + if errResponse, ok := err.(*ErrorResponse); ok && page == 1 && errResponse.ErrorCode == ParamError { + break + } + + callback(nil, err) + break + } + + size := 0 + didErr := false + req.Each(resp, func(element interface{}, err error) bool { + // If the context was cancelled, kill it in flight + if e := ctx.Err(); e != nil { + element = nil + err = e + } + + if callback(element, err) { + size++ + return true + } + + didErr = true + return false + }) + + if size < pageSize || didErr { + break + } + + page++ + } +} + +// APIName returns the name of the given command +func (client *Client) APIName(command Command) string { + // This is due to a limitation of Go<=1.7 + _, ok := command.(*AuthorizeSecurityGroupEgress) + _, okPtr := command.(AuthorizeSecurityGroupEgress) + if ok || okPtr { + return "authorizeSecurityGroupEgress" + } + + info, err := info(command) + if err != nil { + panic(err) + } + return info.Name +} + +// APIDescription returns the description of the given command +func (client *Client) APIDescription(command Command) string { + info, err := info(command) + if err != nil { + return "*missing description*" + } + return info.Description +} + +// Response returns the response structure of the given command +func (client *Client) Response(command Command) interface{} { + switch c := command.(type) { + case AsyncCommand: + return c.AsyncResponse() + default: + return command.Response() + } +} + +// TraceOn activates the HTTP tracer +func (client *Client) TraceOn() { + if _, ok := client.HTTPClient.Transport.(*traceTransport); !ok { + client.HTTPClient.Transport = &traceTransport{ + transport: client.HTTPClient.Transport, + logger: client.Logger, + } + } +} + +// TraceOff deactivates the HTTP tracer +func (client *Client) TraceOff() { + if rt, ok := client.HTTPClient.Transport.(*traceTransport); ok { + client.HTTPClient.Transport = rt.transport + } +} + +// traceTransport contains the original HTTP transport to enable it to be reverted +type traceTransport struct { + transport http.RoundTripper + logger *log.Logger +} + +// RoundTrip executes a single HTTP transaction +func (t *traceTransport) RoundTrip(req *http.Request) (*http.Response, error) { + if dump, err := httputil.DumpRequest(req, true); err == nil { + t.logger.Printf("%s", dump) + } + + resp, err := t.transport.RoundTrip(req) + if err != nil { + return nil, err + } + + if dump, err := httputil.DumpResponse(resp, true); err == nil { + t.logger.Printf("%s", dump) + } + + return resp, nil +} + +// MonotonicRetryStrategyFunc returns a function that waits for n seconds for each iteration +func MonotonicRetryStrategyFunc(seconds int) RetryStrategyFunc { + return func(iteration int64) time.Duration { + return time.Duration(seconds) * time.Second + } +} + +// FibonacciRetryStrategy waits for an increasing amount of time following the Fibonacci sequence +func FibonacciRetryStrategy(iteration int64) time.Duration { + var a, b, i, tmp int64 + a = 0 + b = 1 + for i = 0; i < iteration; i++ { + tmp = a + b + a = b + b = tmp + } + return time.Duration(a) * time.Second +} diff --git a/vendor/github.com/exoscale/egoscale/cserrorcode_string.go b/vendor/github.com/exoscale/egoscale/cserrorcode_string.go new file mode 100644 index 000000000..4711d5425 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/cserrorcode_string.go @@ -0,0 +1,47 @@ +// Code generated by "stringer -type CSErrorCode"; DO NOT EDIT. + +package egoscale + +import "strconv" + +const _CSErrorCode_name = "CloudRuntimeExceptionExecutionExceptionHypervisorVersionChangedExceptionCloudExceptionAccountLimitExceptionAgentUnavailableExceptionCloudAuthenticationExceptionConcurrentOperationExceptionConflictingNetworkSettingsExceptionDiscoveredWithErrorExceptionHAStateExceptionInsufficientAddressCapacityExceptionInsufficientCapacityExceptionInsufficientNetworkCapacityExceptionInsufficientServerCapacityExceptionInsufficientStorageCapacityExceptionInternalErrorExceptionInvalidParameterValueExceptionManagementServerExceptionNetworkRuleConflictExceptionPermissionDeniedExceptionResourceAllocationExceptionResourceInUseExceptionResourceUnavailableExceptionStorageUnavailableExceptionUnsupportedServiceExceptionVirtualMachineMigrationExceptionAsyncCommandQueuedRequestLimitExceptionServerAPIException" + +var _CSErrorCode_map = map[CSErrorCode]string{ + 4250: _CSErrorCode_name[0:21], + 4260: _CSErrorCode_name[21:39], + 4265: _CSErrorCode_name[39:72], + 4275: _CSErrorCode_name[72:86], + 4280: _CSErrorCode_name[86:107], + 4285: _CSErrorCode_name[107:132], + 4290: _CSErrorCode_name[132:160], + 4300: _CSErrorCode_name[160:188], + 4305: _CSErrorCode_name[188:223], + 4310: _CSErrorCode_name[223:251], + 4315: _CSErrorCode_name[251:267], + 4320: _CSErrorCode_name[267:303], + 4325: _CSErrorCode_name[303:332], + 4330: _CSErrorCode_name[332:368], + 4335: _CSErrorCode_name[368:403], + 4340: _CSErrorCode_name[403:439], + 4345: _CSErrorCode_name[439:461], + 4350: _CSErrorCode_name[461:491], + 4355: _CSErrorCode_name[491:516], + 4360: _CSErrorCode_name[516:544], + 4365: _CSErrorCode_name[544:569], + 4370: _CSErrorCode_name[569:596], + 4375: _CSErrorCode_name[596:618], + 4380: _CSErrorCode_name[618:646], + 4385: _CSErrorCode_name[646:673], + 4390: _CSErrorCode_name[673:700], + 4395: _CSErrorCode_name[700:732], + 4540: _CSErrorCode_name[732:750], + 4545: _CSErrorCode_name[750:771], + 9999: _CSErrorCode_name[771:789], +} + +func (i CSErrorCode) String() string { + if str, ok := _CSErrorCode_map[i]; ok { + return str + } + return "CSErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" +} diff --git a/vendor/github.com/exoscale/egoscale/dns.go b/vendor/github.com/exoscale/egoscale/dns.go new file mode 100644 index 000000000..3d3af4078 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/dns.go @@ -0,0 +1,364 @@ +package egoscale + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" +) + +// DNSDomain represents a domain +type DNSDomain struct { + ID int64 `json:"id"` + Name string `json:"name"` + UnicodeName string `json:"unicode_name"` + Token string `json:"token"` + State string `json:"state"` + Language string `json:"language,omitempty"` + Lockable bool `json:"lockable"` + AutoRenew bool `json:"auto_renew"` + WhoisProtected bool `json:"whois_protected"` + RecordCount int64 `json:"record_count"` + ServiceCount int64 `json:"service_count"` + ExpiresOn string `json:"expires_on,omitempty"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +// DNSDomainResponse represents a domain creation response +type DNSDomainResponse struct { + Domain *DNSDomain `json:"domain"` +} + +// DNSRecord represents a DNS record +type DNSRecord struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + Name string `json:"name"` + TTL int `json:"ttl,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` + Content string `json:"content"` + RecordType string `json:"record_type"` + Prio int `json:"prio,omitempty"` +} + +// DNSRecordResponse represents the creation of a DNS record +type DNSRecordResponse struct { + Record DNSRecord `json:"record"` +} + +// UpdateDNSRecord represents a DNS record +type UpdateDNSRecord struct { + ID int64 `json:"id,omitempty"` + DomainID int64 `json:"domain_id,omitempty"` + Name string `json:"name,omitempty"` + TTL int `json:"ttl,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` + Content string `json:"content,omitempty"` + RecordType string `json:"record_type,omitempty"` + Prio int `json:"prio,omitempty"` +} + +// UpdateDNSRecordResponse represents the creation of a DNS record +type UpdateDNSRecordResponse struct { + Record UpdateDNSRecord `json:"record"` +} + +// DNSErrorResponse represents an error in the API +type DNSErrorResponse struct { + Message string `json:"message,omitempty"` + Errors map[string][]string `json:"errors"` +} + +// Record represent record type +type Record int + +//go:generate stringer -type=Record +const ( + // A record type + A Record = iota + // AAAA record type + AAAA + // ALIAS record type + ALIAS + // CNAME record type + CNAME + // HINFO record type + HINFO + // MX record type + MX + // NAPTR record type + NAPTR + // NS record type + NS + // POOL record type + POOL + // SPF record type + SPF + // SRV record type + SRV + // SSHFP record type + SSHFP + // TXT record type + TXT + // URL record type + URL +) + +// Error formats the DNSerror into a string +func (req *DNSErrorResponse) Error() string { + if len(req.Errors) > 0 { + errs := []string{} + for name, ss := range req.Errors { + if len(ss) > 0 { + errs = append(errs, fmt.Sprintf("%s: %s", name, strings.Join(ss, ", "))) + } + } + return fmt.Sprintf("dns error: %s (%s)", req.Message, strings.Join(errs, "; ")) + } + return fmt.Sprintf("dns error: %s", req.Message) +} + +// CreateDomain creates a DNS domain +func (client *Client) CreateDomain(ctx context.Context, name string) (*DNSDomain, error) { + m, err := json.Marshal(DNSDomainResponse{ + Domain: &DNSDomain{ + Name: name, + }, + }) + if err != nil { + return nil, err + } + + resp, err := client.dnsRequest(ctx, "/v1/domains", nil, string(m), "POST") + if err != nil { + return nil, err + } + + var d *DNSDomainResponse + if err := json.Unmarshal(resp, &d); err != nil { + return nil, err + } + + return d.Domain, nil +} + +// GetDomain gets a DNS domain +func (client *Client) GetDomain(ctx context.Context, name string) (*DNSDomain, error) { + resp, err := client.dnsRequest(ctx, "/v1/domains/"+name, nil, "", "GET") + if err != nil { + return nil, err + } + + var d *DNSDomainResponse + if err := json.Unmarshal(resp, &d); err != nil { + return nil, err + } + + return d.Domain, nil +} + +// GetDomains gets DNS domains +func (client *Client) GetDomains(ctx context.Context) ([]DNSDomain, error) { + resp, err := client.dnsRequest(ctx, "/v1/domains", nil, "", "GET") + if err != nil { + return nil, err + } + + var d []DNSDomainResponse + if err := json.Unmarshal(resp, &d); err != nil { + return nil, err + } + + domains := make([]DNSDomain, len(d)) + for i := range d { + domains[i] = *d[i].Domain + } + return domains, nil +} + +// DeleteDomain delets a DNS domain +func (client *Client) DeleteDomain(ctx context.Context, name string) error { + _, err := client.dnsRequest(ctx, "/v1/domains/"+name, nil, "", "DELETE") + return err +} + +// GetRecord returns a DNS record +func (client *Client) GetRecord(ctx context.Context, domain string, recordID int64) (*DNSRecord, error) { + id := strconv.FormatInt(recordID, 10) + resp, err := client.dnsRequest(ctx, "/v1/domains/"+domain+"/records/"+id, nil, "", "GET") + if err != nil { + return nil, err + } + + var r DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + return &(r.Record), nil +} + +// GetRecords returns the DNS records +func (client *Client) GetRecords(ctx context.Context, domain string) ([]DNSRecord, error) { + resp, err := client.dnsRequest(ctx, "/v1/domains/"+domain+"/records", nil, "", "GET") + if err != nil { + return nil, err + } + + var r []DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + records := make([]DNSRecord, 0, len(r)) + for _, rec := range r { + records = append(records, rec.Record) + } + + return records, nil +} + +// GetRecordsWithFilters returns the DNS records (filters can be empty) +func (client *Client) GetRecordsWithFilters(ctx context.Context, domain, name, recordType string) ([]DNSRecord, error) { + + filters := url.Values{} + if name != "" { + filters.Add("name", name) + } + if recordType != "" { + filters.Add("record_type", recordType) + } + + resp, err := client.dnsRequest(ctx, "/v1/domains/"+domain+"/records", filters, "", "GET") + if err != nil { + return nil, err + } + + var r []DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + records := make([]DNSRecord, 0, len(r)) + for _, rec := range r { + records = append(records, rec.Record) + } + + return records, nil +} + +// CreateRecord creates a DNS record +func (client *Client) CreateRecord(ctx context.Context, name string, rec DNSRecord) (*DNSRecord, error) { + body, err := json.Marshal(DNSRecordResponse{ + Record: rec, + }) + if err != nil { + return nil, err + } + + resp, err := client.dnsRequest(ctx, "/v1/domains/"+name+"/records", nil, string(body), "POST") + if err != nil { + return nil, err + } + + var r DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + return &(r.Record), nil +} + +// UpdateRecord updates a DNS record +func (client *Client) UpdateRecord(ctx context.Context, name string, rec UpdateDNSRecord) (*DNSRecord, error) { + body, err := json.Marshal(UpdateDNSRecordResponse{ + Record: rec, + }) + if err != nil { + return nil, err + } + + id := strconv.FormatInt(rec.ID, 10) + resp, err := client.dnsRequest(ctx, "/v1/domains/"+name+"/records/"+id, nil, string(body), "PUT") + if err != nil { + return nil, err + } + + var r DNSRecordResponse + if err = json.Unmarshal(resp, &r); err != nil { + return nil, err + } + + return &(r.Record), nil +} + +// DeleteRecord deletes a record +func (client *Client) DeleteRecord(ctx context.Context, name string, recordID int64) error { + id := strconv.FormatInt(recordID, 10) + _, err := client.dnsRequest(ctx, "/v1/domains/"+name+"/records/"+id, nil, "", "DELETE") + + return err +} + +func (client *Client) dnsRequest(ctx context.Context, uri string, urlValues url.Values, params, method string) (json.RawMessage, error) { + rawURL := client.Endpoint + uri + url, err := url.Parse(rawURL) + if err != nil { + return nil, err + } + + q := url.Query() + for k, vs := range urlValues { + for _, v := range vs { + q.Add(k, v) + } + } + url.RawQuery = q.Encode() + + req, err := http.NewRequest(method, url.String(), strings.NewReader(params)) + if err != nil { + return nil, err + } + + var hdr = make(http.Header) + hdr.Add("X-DNS-TOKEN", client.APIKey+":"+client.apiSecret) + hdr.Add("User-Agent", UserAgent) + hdr.Add("Accept", "application/json") + if params != "" { + hdr.Add("Content-Type", "application/json") + } + req.Header = hdr + + resp, err := client.HTTPClient.Do(req.WithContext(ctx)) + if err != nil { + return nil, err + } + defer resp.Body.Close() // nolint: errcheck + + contentType := resp.Header.Get("content-type") + if !strings.Contains(contentType, "application/json") { + return nil, fmt.Errorf(`response content-type expected to be "application/json", got %q`, contentType) + } + + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode >= 400 { + e := new(DNSErrorResponse) + if err := json.Unmarshal(b, e); err != nil { + return nil, err + } + return nil, e + } + + return b, nil +} diff --git a/vendor/github.com/exoscale/egoscale/doc.go b/vendor/github.com/exoscale/egoscale/doc.go new file mode 100644 index 000000000..0d9997efa --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/doc.go @@ -0,0 +1,180 @@ +/* + +Package egoscale is a mapping for the Exoscale API (https://community.exoscale.com/api/compute/). + +Requests and Responses + +To build a request, construct the adequate struct. This library expects a pointer for efficiency reasons only. The response is a struct corresponding to the data at stake. E.g. DeployVirtualMachine gives a VirtualMachine, as a pointer as well to avoid big copies. + +Then everything within the struct is not a pointer. Find below some examples of how egoscale may be used. If anything feels odd or unclear, please let us know: https://github.com/exoscale/egoscale/issues + + req := &egoscale.DeployVirtualMachine{ + Size: 10, + ServiceOfferingID: egoscale.MustParseUUID("..."), + TemplateID: egoscale.MustParseUUID("..."), + ZoneID: egoscale.MastParseUUID("..."), + } + + fmt.Println("Deployment started") + resp, err := cs.Request(req) + if err != nil { + panic(err) + } + + vm := resp.(*egoscale.VirtualMachine) + fmt.Printf("Virtual Machine ID: %s\n", vm.ID) + +This example deploys a virtual machine while controlling the job status as it goes. It enables a finer control over errors, e.g. HTTP timeout, and eventually a way to kill it of (from the client side). + + req := &egoscale.DeployVirtualMachine{ + Size: 10, + ServiceOfferingID: egoscale.MustParseUUID("..."), + TemplateID: egoscale.MustParseUUID("..."), + ZoneID: egoscale.MustParseUUID("..."), + } + vm := &egoscale.VirtualMachine{} + + fmt.Println("Deployment started") + cs.AsyncRequest(req, func(jobResult *egoscale.AsyncJobResult, err error) bool { + if err != nil { + // any kind of error + panic(err) + } + + // Keep waiting + if jobResult.JobStatus == egoscale.Pending { + fmt.Println("wait...") + return true + } + + // Unmarshal the response into the response struct + if err := jobResult.Response(vm); err != nil { + // JSON unmarshaling error + panic(err) + } + + // Stop waiting + return false + }) + + fmt.Printf("Virtual Machine ID: %s\n", vm.ID) + +Debugging and traces + +As this library is mostly an HTTP client, you can reuse all the existing tools around it. + + cs := egoscale.NewClient("https://api.exoscale.com/compute", "EXO...", "...") + // sets a logger on stderr + cs.Logger = log.New(os.Stderr, "prefix", log.LstdFlags) + // activates the HTTP traces + cs.TraceOn() + +Nota bene: when running the tests or the egoscale library via another tool, e.g. the exo cli, the environment variable EXOSCALE_TRACE=prefix does the above configuration for you. As a developer using egoscale as a library, you'll find it more convenient to plug your favorite io.Writer as it's a Logger. + + +APIs + +All the available APIs on the server and provided by the API Discovery plugin. + + cs := egoscale.NewClient("https://api.exoscale.com/compute", "EXO...", "...") + + resp, err := cs.Request(&egoscale.ListAPIs{}) + if err != nil { + panic(err) + } + + for _, api := range resp.(*egoscale.ListAPIsResponse).API { + fmt.Printf("%s %s\n", api.Name, api.Description) + } + // Output: + // listNetworks Lists all available networks + // ... + +Security Groups + +Security Groups provide a way to isolate traffic to VMs. Rules are added via the two Authorization commands. + + resp, err := cs.Request(&egoscale.CreateSecurityGroup{ + Name: "Load balancer", + Description: "Open HTTP/HTTPS ports from the outside world", + }) + securityGroup := resp.(*egoscale.SecurityGroup) + + resp, err = cs.Request(&egoscale.AuthorizeSecurityGroupIngress{ + Description: "SSH traffic", + SecurityGroupID: securityGroup.ID, + CidrList: []CIDR{ + *egoscale.MustParseCIDR("0.0.0.0/0"), + *egoscale.MustParseCIDR("::/0"), + }, + Protocol: "tcp", + StartPort: 22, + EndPort: 22, + }) + // The modified SecurityGroup is returned + securityGroup := resp.(*egoscale.SecurityGroup) + + // ... + err = client.BooleanRequest(&egoscale.DeleteSecurityGroup{ + ID: securityGroup.ID, + }) + // ... + +Security Group also implement the generic List, Get and Delete interfaces (Listable and Deletable). + + // List all Security Groups + sgs, _ := cs.List(&egoscale.SecurityGroup{}) + for _, s := range sgs { + sg := s.(egoscale.SecurityGroup) + // ... + } + + // Get a Security Group + sgQuery := &egoscale.SecurityGroup{Name: "Load balancer"} + resp, err := cs.Get(sgQuery); err != nil { + ... + } + sg := resp.(*egoscale.SecurityGroup) + + if err := cs.Delete(sg); err != nil { + ... + } + // The SecurityGroup has been deleted + +See: https://community.exoscale.com/documentation/compute/security-groups/ + +Zones + +A Zone corresponds to a Data Center. You may list them. Zone implements the Listable interface, which let you perform a list in two different ways. The first exposes the underlying request while the second one hide them and you only manipulate the structs of your interest. + + // Using ListZones request + req := &egoscale.ListZones{} + resp, err := client.Request(req) + if err != nil { + panic(err) + } + + for _, zone := range resp.(*egoscale.ListZonesResponse) { + ... + } + + // Using client.List + zone := &egoscale.Zone{} + zones, err := client.List(zone) + if err != nil { + panic(err) + } + + for _, z := range zones { + zone := z.(egoscale.Zone) + ... + } + +Elastic IPs + +An Elastic IP is a way to attach an IP address to many Virtual Machines. The API side of the story configures the external environment, like the routing. Some work is required within the machine to properly configure the interfaces. + +See: https://community.exoscale.com/documentation/compute/eip/ + +*/ +package egoscale diff --git a/vendor/github.com/exoscale/egoscale/errorcode_string.go b/vendor/github.com/exoscale/egoscale/errorcode_string.go new file mode 100644 index 000000000..19711257e --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/errorcode_string.go @@ -0,0 +1,37 @@ +// Code generated by "stringer -type ErrorCode"; DO NOT EDIT. + +package egoscale + +import "strconv" + +const ( + _ErrorCode_name_0 = "Unauthorized" + _ErrorCode_name_1 = "MethodNotAllowed" + _ErrorCode_name_2 = "UnsupportedActionError" + _ErrorCode_name_3 = "APILimitExceededMalformedParameterErrorParamError" + _ErrorCode_name_4 = "InternalErrorAccountErrorAccountResourceLimitErrorInsufficientCapacityErrorResourceUnavailableErrorResourceAllocationErrorResourceInUseErrorNetworkRuleConflictError" +) + +var ( + _ErrorCode_index_3 = [...]uint8{0, 16, 39, 49} + _ErrorCode_index_4 = [...]uint8{0, 13, 25, 50, 75, 99, 122, 140, 164} +) + +func (i ErrorCode) String() string { + switch { + case i == 401: + return _ErrorCode_name_0 + case i == 405: + return _ErrorCode_name_1 + case i == 422: + return _ErrorCode_name_2 + case 429 <= i && i <= 431: + i -= 429 + return _ErrorCode_name_3[_ErrorCode_index_3[i]:_ErrorCode_index_3[i+1]] + case 530 <= i && i <= 537: + i -= 530 + return _ErrorCode_name_4[_ErrorCode_index_4[i]:_ErrorCode_index_4[i+1]] + default: + return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/vendor/github.com/exoscale/egoscale/events.go b/vendor/github.com/exoscale/egoscale/events.go new file mode 100644 index 000000000..c6adbfd69 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/events.go @@ -0,0 +1,76 @@ +package egoscale + +// Event represents an event in the system +type Event struct { + Account string `json:"account,omitempty" doc:"the account name for the account that owns the object being acted on in the event (e.g. the owner of the virtual machine, ip address, or security group)"` + Created string `json:"created,omitempty" doc:"the date the event was created"` + Description string `json:"description,omitempty" doc:"a brief description of the event"` + ID *UUID `json:"id" doc:"the ID of the event"` + Level string `json:"level,omitempty" doc:"the event level (INFO, WARN, ERROR)"` + ParentID *UUID `json:"parentid,omitempty" doc:"whether the event is parented"` + State string `json:"state,omitempty" doc:"the state of the event"` + Type string `json:"type,omitempty" doc:"the type of the event (see event types)"` + UserName string `json:"username,omitempty" doc:"the name of the user who performed the action (can be different from the account if an admin is performing an action for a user, e.g. starting/stopping a user's virtual machine)"` +} + +// ListRequest builds the ListEvents request +func (event Event) ListRequest() (ListCommand, error) { + req := &ListEvents{ + ID: event.ID, + Level: event.Level, + Type: event.Type, + } + + return req, nil +} + +// EventType represent a type of event +type EventType struct { + Name string `json:"name,omitempty" doc:"Event Type"` +} + +// ListRequest builds the ListEventTypes request +func (EventType) ListRequest() (ListCommand, error) { + req := &ListEventTypes{} + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListEvents + +// ListEvents list the events +type ListEvents struct { + Duration int `json:"duration,omitempty" doc:"the duration of the event"` + EndDate string `json:"enddate,omitempty" doc:"the end date range of the list you want to retrieve (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")"` + EntryTime int `json:"entrytime,omitempty" doc:"the time the event was entered"` + ID *UUID `json:"id,omitempty" doc:"the ID of the event"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Level string `json:"level,omitempty" doc:"the event level (INFO, WARN, ERROR)"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + StartDate string `json:"startdate,omitempty" doc:"the start date range of the list you want to retrieve (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")"` + Type string `json:"type,omitempty" doc:"the event type (see event types)"` + _ bool `name:"listEvents" description:"A command to list events."` +} + +// ListEventsResponse represents a response of a list query +type ListEventsResponse struct { + Count int `json:"count"` + Event []Event `json:"event"` +} + +//go:generate go run generate/main.go -interface=Listable ListEventTypes + +// ListEventTypes list the event types +type ListEventTypes struct { + Page int `json:"page,omitempty"` // fake + PageSize int `json:"pagesize,omitempty"` // fake + _ bool `name:"listEventTypes" description:"List Event Types"` +} + +// ListEventTypesResponse represents a response of a list query +type ListEventTypesResponse struct { + Count int `json:"count"` + EventType []EventType `json:"eventtype"` + _ bool `name:"listEventTypes" description:"List Event Types"` +} diff --git a/vendor/github.com/exoscale/egoscale/events_response.go b/vendor/github.com/exoscale/egoscale/events_response.go new file mode 100644 index 000000000..2af10cf45 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/events_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListEvents) Response() interface{} { + return new(ListEventsResponse) +} + +// ListRequest returns itself +func (ls *ListEvents) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListEvents) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListEvents) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListEvents) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListEventsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListEventsResponse was expected, got %T", resp)) + return + } + + for i := range items.Event { + if !callback(&items.Event[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/eventtypes_response.go b/vendor/github.com/exoscale/egoscale/eventtypes_response.go new file mode 100644 index 000000000..073d9648f --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/eventtypes_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListEventTypes) Response() interface{} { + return new(ListEventTypesResponse) +} + +// ListRequest returns itself +func (ls *ListEventTypes) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListEventTypes) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListEventTypes) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListEventTypes) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListEventTypesResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListEventTypesResponse was expected, got %T", resp)) + return + } + + for i := range items.EventType { + if !callback(&items.EventType[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/go.mod b/vendor/github.com/exoscale/egoscale/go.mod new file mode 100644 index 000000000..c31a038a2 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/go.mod @@ -0,0 +1,3 @@ +module github.com/exoscale/egoscale + +require github.com/gofrs/uuid v3.2.0+incompatible diff --git a/vendor/github.com/exoscale/egoscale/go.sum b/vendor/github.com/exoscale/egoscale/go.sum new file mode 100644 index 000000000..f27a0746d --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/go.sum @@ -0,0 +1,2 @@ +github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= diff --git a/vendor/github.com/exoscale/egoscale/gopher.png b/vendor/github.com/exoscale/egoscale/gopher.png new file mode 100644 index 0000000000000000000000000000000000000000..16420a6182749705d4fbf20d89baecfa266aaad4 GIT binary patch literal 63065 zcmdpd1y@{6ur2QH4hfpz?hu^d6Br=4ySuw<5`qV}1b2tQ-3b!hZGgdD?j+y6??=1^ zvsj#S=ssP&YuB#oB3eyF4ik+G4F(1V^P{}zf3&g#{JypI z1}+9sB8H~p9p#KXO~;DR<)bOvmz5QAIJz%km)_alDBKWx?#qc=(S1>fAPq{$|Bv5{ z?_z$yNeFEEbC4gvW58?$*>}0n5HG?WxMUzm;2`Af;vu)g9Aid#oHgR7!DFPT)Bm*t zYm!|qN8A@=N5U=^LG!@>>93bjG_(VZ4{O==9TPl&{bE=fP8>kk_VN(3GC7(ZdD0Xk{ zbgnpu>|H<5Hm&CCj_s-CcVamW9TFhq@i7P@hB&QwQIKf*%2_C&<%m2JoY&OkF6d+x zgX73JF+dBWA-l{W>x`&Oa4Ey@2oW}6O8+jGjSh}@el3p)Z9(7dO_q@RPv$-3Gp`oU z`FK6IJ<@JDf(^~CcO^iauqA9H37m|a*kCQ#Z2bh3bGd2oizgm09+%2_SfWhO5fO0RBm@HJ z;5tG)*MwXde*dPp=|^+AdAEHyUn6yvC$NDg*bzb#m5bhU{w6&4s=^crlTJ+Rw0iy? zc7~fmKgPdq1zjxI>9@628pki z|3(U#68S;hZhDm)9N#zrJH=D`cx9mt66==B4;prXdH{|DaoFB|xzL_Zn+M&%0L6XV z@8;%5PY~u>nUPsSY|1PP%G-kw8Xjug4}K?+{pj;z)$>Y3$9;gO^(P%01r{+?T~1E zNy_y1B|13LQ-~5)Vo38ZiE}1J>Y96B5&ICQ1({Q%a2R@2)B18|^7|eEbAf zno}4t!=I9@@2B)t+WsOUWU9Uo2_pZ|>aE1>Bk6pT>Q7qhAfQUefA`#em*syWpkC); z^91Eo>bK1=+jFIVgUi4^=9E=H z|Bb<;Erse+&fR*5unH*&ylq{o_|SJ)AZJhnrjjuP$yWX^oDhh7Ixx6!adDMzQ8P5z zOMC$zQO`L!Q)};2d5S#6TmD0452p!gl#f0|LUG*`Z~U>x3HW49>l0e*3rA3PomOSo zzbTzC(j?J*)bqh^Cu)XMp2Rx^;0N=EJ>Fpjix@rBf7`W5@~D}`d!V2m7*aefRuItt zd!-{hczc8r=3&6yh4+8WcA)G2kUD3Bc*XFH6WbDyms+wO5Xsu+89K}ZT&|w@b#+Xu zCG`(t0t(+ZUd;K@Gj%4NTlC*xc*f6Gwnsca-deuLy>WJV_uqgF^;4`w>azhM{XK*0 z0n`_2D%}Q^E&B$@4hwYtlUQ|nSpU7;!E~tdO>x~T;gbWur|66HB7-4|_7L}LIyWNF zeWVB{tT8ce1u@Ti3T|1#FQ6jYry@P3mTTgv=sBxxuyMe*OMsGsR^t5QOjLSy^ z2^J{E6J`=BX%EC+Ytj!bxTWRly!z2pKsQ32`mM*+?4KK)@n3y>Cq!X1>*Ch`!&E`d z)U!LQ8+F=PZfP!$vdV+MZ|LS2qgqQv!Fm-D~`^HiX-=C0?eMR;?d^eHa12>E0{ing3OSF3IwPTAnGri zKk}{^unQt0+O4$4=ge2_gZmYk%6?)z8gouhmp^QXZvB{6YJX@d*9N_59(FPMsYe72 zBN75!La@S|aNA@n8o;>0Ov$b0eoRh;kpe}um{1B!`CSjEs zHL8!3kv$s3p9vnP^dN_N=>2|dR4^|bxnrnHqY%bXHx<59eG--2{7jK+p=&) zi`9W2lOPna3+xT77N!5ZzSj@+2f$bE$Lz4Ls)($n&3oY796@Sol6rM&i2oxK8*@Q^ zX$)BtISddOUA-Kg82yIzUG&7~bh`e2T(H|W5@N;gv)11YuOG1=Wm2kiCx;Z-2DO?h zkgJEy@xmG-S(FIFinn=;q|YXFEhjeW&$qjP%#hZZp&GYp-arJ!$ySf!uI9YZdy9`* z*GHNgCPoQ*Y!X(wLqcv6R;}IVjzMWl!oHTCo2R-KbA*@hlB;PaBvH}v<~?VdKd+Io z1HX*Y|6{B*p7-N;vw3mh*I#yxUtGRrtpWeqd4v#$~#+V!~pqfs$SIQN*`AEE&i z9j$H-zx_O2QGH%vpFhUMVv3o-sU#~h{2T1|{?P^{_oO&--LRVpC^_G0{?0k?;aR@L z>_4MD2WZIg3Y(ctF$zES1#(xVzB3*Co#dU{rpNc+JZ#rW8&D&;O^gVguaE6R1DQl# z0v(LA%i({nDiv30`tlyFqpl7>OTqY(c_@U7dM>?q(k*9#l5zPTuc~-F%pYpRNWN07 zc2zaRIhI(v*=SAb;=oFe6yg5^0oFAAq9o*dI;sykuA4sNyUuLSRW$9L8PtE=87YrO zbhUHmRnYl)RLza$y5IyDaxsqnZv``nNAFv|j>$N_i>XxGc0q<*!Hc!H{kJ&nd%Ev3 zesI1mBQe+HA-An?nKb`dSW<5A|JttJgo6xMMaQuZ6N4NUDP z!Vjcs2n0wk5V+Fd_qlkztL!L$-@je}E$9aMT5n-^y(zJC1eL%oDLOyjU(auuk{~rX z+@^-!C{H+;Dwvhr3b_#W7c8vm&Z4OIBm7o2_72=~@OYPwQNfDXza_DTS9DdwzfQYl zWeK*#S9!1f)~?vu+u^vmNVi*0!Y>V{!Z|DYAlF5;SU!Fgj|ZolsPl+5wy6ah8-yL4 z_|@D0@1};~4?PIk`~uspG-CeVrpV7{@)9*zdwo)5Yk5}1Y($X#vEk}rgoBH&glz|d z9<&h5&arYm=i>WsGbq?okkKF5g*_=jLI;}6cYb4!#<;4J-jS-H$Ig3kbzrv{+#Es% zH4o*JaxI#Jp3x=zWpGtce;1d|)JVX;=^KZ!yMY1~W-XnGkhWB96>^m$e0v ztF6)UrS|lg(o&@H3t46p6EwGDq;yJ}0!q3fDHARM({3}Ys1_R~=7ZLn`{w~oeb`5| zJPvFZ&z@|`YI|-1LW8TkQ+h^4C8kFjg<%b4S{Om?bp1$W5uq0_?(5i1xU%C_GJt1 zG*+lJ5XE0nMgxO*#U&=NhW>cdL2llhaYZP0N;^pWr+$oR&RkC@OX5ie+KF=pf2VB- zBn>Z)SyXGE9WPH_xP$MUuWeE)4Mr>5MLhQQ!gWJ56U*2I5EeEX$ z#b7I)?Xt#rGL9hP(@fdquVbjW%z5mE`jHpX2lZjA6539Da6O-lppHm5;JRgF!~^2pSZI=AH&(%dReq zjf|0o9>;W`p9eq1HGn`UGD)UE;(_fKXb}k%us~o0)4bzYnxaLu)$WK;o2sBA8A$Bz zeG6}Pio2|`MfD#{#pepk&E-iNPvYMil&8tULCZmo@Ne1wQ4R&}zEN|)iTn38yKe9$ z-yyO&9i!_&+Vl@DHYj;0Xx0jo8 z(VX3p-!4+9wNh)c@UYxWt|KlOcYqaxEQ9%X=L!DGcLBV&oGYiI8QbHtNlEDe1BZHE zdxvh2sjn!Jlx5={R)4fjtN%oS#nWbDVnW*}h`70_eSS2lbbNQI2xq_6B%t-G%Ewsq zMKtica#Ba6GQ#J8r=2UOssF6xf`*Xy@o`ouPUJu?{Eu1BX7zSl9G#$8Fe+_?>uB7l z_e9E`u|m3IK4ylb!y#6iI?`3}Zf4Oa*6D>cS%E3#4pz>G8XN0-%g?}W zD%jq^-Xi`F!0^o&&$b@@B#n)SAlN!0)F1eLlEes`9P{_%B;W$_w3}u6`{@$Nv@AWFt~4tB9NAti z9p%athKiYRNHKN!x{#~LEAKimWd|J*sQS{#rgs_%|5|RSM;;)AM*`Cae@Id!hdl%G z^^CZMD7JG)TwWn#_OewK09_3Q=mQFoBSl*bb{gtf!%1WxjziWZS;m+TM86BF@Ib9fGX|I|F z#|B?=r2OKQS90S)6!(i2eVczOa*K*3G8>$_{u*QpX=$2x(PewU6n?$Hpl(&FKdL`u zNcw7VGhw^2-!D7RHf7bt6NkVXGIa#lB|wpsKPDMAsYF^EWV*cPbpo39QEYq_UyE6_ zKriHIZm!V(iIif zFH)1I{*Z3MqC7fz-OIecs&33n7f2-E!rzP$?|My<9IV{b@fi5Ichf9FjQE$*{rlkX zIrR=RgX=iCI(dIup*l}>pevCf&z6t{A2ihHR6L#bSYtAJTf-6^-{pmZchg@TrW3EK z>${mNz+dKY#SGyW)*Pe<76#*LK5dHTcDP~xdqJ_UT@_uaB$d~wk-id-7|j=wUgy+j zhql#srfIjNaU>dsO@o-EN;ZQD%5`Jqq=^2~uK_qM0DgFAZ{oMUm zJE1SV;nHwiw{bgLrp2zrfWM|giw7E%I-EF}a)z<;S#F2-GdK_?$-akKd*TKh6a_ zbL$ARk)_J>tpND@IqULj08CkO=V~qZsC_~4JX=55ebt^sAGr)O;Fi(r3R7MlYi!u4!avU!)GK!cyHXAi%uJfywD{nmYC zq{oj25ghTVAWUrD}A;@Q3dda;Mow5!nv70guy#B z!zu9ftny2>#dTePX@`7{&Lz#=SN#u%qbuZ~nKRo--O=fc`$!7AWX=jQ6^Oh&J88S} z{4sv$mK+i+OvSfyetn2g4lk?7j}K*%Jnus!5oABCzA&3FILKQ12)3OOB{^_ySp{s< zdDanFzn#$qC@S{ttjP|CG0T$!@0|r4hw_%TH}UK0Dg6wZA2hvOu-IGjO?S&vyRlm7(wk+;e&FKZJ zO1>J9I9xL@FYv}xcerL;}$r7rFj1&Ir;oQbiUxdrWuVGy%e z_Q>NtAyu?~i~n17VGYIYa@Yt_L*6#s+$%F4#3SLVKBR8*VD3XAZPxXKIEdb4qt6 zDDG$FsIsz6gVcQ4!#q;akSG*+)RCJ`n{5l7_9sew2@EYO1~N~Co8~08o(a?#O?}gq}YdGbbqQdaa{Mm-kyL#UX9XBY-+6|n%#`O=DQ}3 z5*lma8Z{s-@i=Cbq-;6YdR<{k*;HD~$PQXNEyrlS_E~K2iV{W{ErE0)_8Px1;!F=T zC|&jzEp(eYM%Z$qYGY{^#iIRXc&`UI5L|&IUz;;Sc_#Mr1MJ-3A^9PPpV4zybCcNf*wF6U zOz1X?1yQBm=Y?nE@JdQs%m_WFHNk2Rv6TQ(Y1uIEs@F~oP!5tftJU(?Glx{b@7)&c zH>}JWu?bxwae8O}^pk`LYP(X@!%hrZP6w9i%Us&*fUgKEUz)%G)6%ERXLIxR+g&|c zj7}NdA42PF&%Y+v$_Q(P0iO1q=q9Gn5Y*d)ohz5h0cm=%yxYd`I#3lBn5S#|h2#|qHn zU~-xE+3ZD%w*?`h9pBpH5%ZJ8uhRi6@iBD?ThIbl1FV`B_O}-(g5()$>ynLE!hJcXnOMl2 zcdPv&Pf<(2@!QuIkHZlh`w_)>6t5=oh&bzlrc$i001gkXavivE?{3T=T^ezBi5)Wy z;T9)bE@)vyvV0uG1vs*l$9#8Z^a9)8Qx;+yPlJwe=!Io5$%Z0TMO8kTm^}AE20xE6 zzi0N|+12{{Irjo1lcyF%(%pXx%Ts$KpaWqbXby0b;@yeZ4qF)|w^y=8L!epx(~Sw|L^UI*0_Qa5)KswGR!O>4~k^sg+9 zK=K&kLa1<5C0QhoxC;GA*F}uuAs!!_%inA1x_O+A$zP{iK{wFva{m3Dp4c_Z!_}!d z#gxr+T5oz^sgKp=0-INFjHG7<LRK%rA4@KRS_|E zgDOZ`Kxi)({vcVn?L-a+D(MGhZmhJi2=o{1z+nDY;$r37&a+g;yw~c+!w}DfuIHw% zR7kjx4%!%u7^X;U5k?s_%GL|{z=Dw35b$)CQ~A?r*an8&#e7io{Mdd7eGRp(pB5nT z)2gLTsR$9K4w)lY8M{4MLal70C{_u%GINsV-7vO_V2oQwRs|u|Swvdn?}iD#!V>GD z0txMpQOiQs(F3y(b0$#ddf@fY+SwETsxd3fv|#xSzm3Tc`vrKPfc=Fe4pu+_fH0h? zEUP|E;8VV7bYfJ`p%adAjj^V3nlb~lKurZoRcOkb$#{PQOit3$Q8ES!>U70d90~;} z_g2{+$Q?d3EXR2tfY~D1DB}o98So<+E>5bC<-Bf`y&&AQSQFd!KB}%XYzci{X=1!* z{&+y3vf4=Q0;;$bk18b5$?fTp?*)=rA26^rRpz5Yc@{_vy zJ0>O+Zx$h;jF=cc<6iqNFrtsJ-UAy&7 zJ~|rSSGvNgxhw23_-8YGQ}ZW99)kYr3?6adZqZK4iKXYcm#10eO~e( z!>$Mprm!NeBRQc}B~VaMn`-qJWK1xhLr6M*?**^%lAaH|ULd2iaC{M(J*skOBqZq8 z5YxRL>5g?k0UKIDbFAp=>(llV0~r8;q&KK3DJil60RgrTpBIb^?N4kMOX9cdEByuO z+lZx>%#-%w=s8C|N=ox+w$ake`#d|{6m&i&2W>1Y@rawxB_CIn8U+Fog=5k0jh7iZ zAKfX*(QYXISPeL6gH0o#8A|R#S5Wn%K(nTSr<6l*O+-gCfeRW94HrVwMt6P;Mvw28NhcUPj#xZ3@z^!zs3N>D)!gxmP}2`8sC5qj;5$6`=6hK`9TpY5{>xb3@%P4KG{dPJ{4jWHzncr09w5NWFv93OrMq zYCx|G1Fw@|C)O7Xk>4TytRW~5!xFNxI&wguBOC*)Xy)CCVvu?3MBwe|xbG@>u3?a> zEos@|@iF?Lr3ALgly1c8i}kY{SH-$hgy(_6lTf=;nKWgaTV3p!%f52pHVA2F|YXO zj$%w!9;=@4voV)FbKoo}Ayppbv%amB1x#;Q-yT$a|Nfoe=5*Ef!3>K(`5E@rK$@SbnZd9J<=&9y)ggZ?D2k<~&w)jsJ?q+H2t1!w+ zdtMD9ksYuWwp`;7co@4lKB^#I(#Yh2@|pDAvdm~y032YU)_k=hFad0vgl>WL!`8QN zAz8eF2x`fu&zoHqE9)9FA5mP`W=iQ&V^|c%>A4PT1&|3R^GE zZUMCbvYX>*S%fx|tsSS<_iCR}X9JKgJF#aip3kmvUT(`|A zVOT^&L^HF(>rVu`tTKQH-ib6}we@ z_KEdUAnBuiIg`Te07}c?c7AC)-cdmFPUi}?W64*xO#OIb|6V7xcPv#gd_#qgU@w-ul;3}SRUnvKN&6o0W zo||J_0I`JQo5GS3DDwpx)wd}DzUN`umWNb=we7GTu&9QooGqt175RUhqb?pN=xDYi zlnuzpSaS*rH`UslHS{d1x5M7#wZxrlbwKG-)hel22T7G56FLi$1~cI*E0Zg+U8+m#hS}U5Wv36s}UCx6-{mzp^XO0 z%4R471k?e)ErY*rKY`KQ^m9(n?}&+rPVG;BNkAbv1ZDX^qVM1y%3JRafwu*RqFxBJ zDw&e&-34mOL@Sl={lutSHO1$C<})#s#tfSc>^T{IQrbCQ>6wA-)jD5uH9G3V=D$xH zPw7Sd5MK%A-`UyeAR_silmohz4>V!l_#Agpd@UapxA!n@>2zCYy=d1sUvpeu^x2Gv zeA&hG;%Teu&ShHx>WN~jW+LCmxTNMgO#m<@r9>SQ@(bfC!A)A4nqmez zI;X_M?I=F6G_ZzBnqqS<>UtRjSmM_2@&$)xc~4RmcgN@&CZ zP>WfOYCcS;G(QSyw+IxnnIIG!Bz`rnq=H650wN+R4zW|XT_UpdvyT9bs{DoRfo+fN z>t+Cuu&zJG=F_x0C1^5oVY}as)3jl^<_`t3;R4Fb$+hOHo|@Ww%^;MAXj)cQ%%qPW z)d+S?jWm8HY?M|OPkxzRxnCS5fH2$5@TRvGZ^x-_w5h(1mZ`2p&e;gBJU+VX2Uge4 zcp91&%8ZVW+m8+E;X7P8YAUbzKOjDN&p2{4^}i)!?Q_WidGmq-Au<81W5RaGRAM*= z0T@1JO`EPJ5oL}MT5G7TE2PMd6OlJr%PA#8K={BHO21d{W};ZQP{>Rxk{nt~i|inSaNhROKFzbFM&|v%(re0FjDw{BO#uk>CM&B5^iQutg1yozf;h^fB9|I z7ROWkoQ(bv4WL}i@JiKMxfvBz%n^vqF6M(R%vaHCQ%AMO``|7p=soEPS<4w2ncLY3 zv$H^^LU7ns8<-7sQ&8GGcdarz`r^D%nnIrcnN^*e>1@6ha<_n;Q^)2>JQo?Q+H8cj z;=+n?1b-tRC*5O@$|&-}^t4N@Mrh*=>V>@(MaM6u^38rFx(w5dvw8uoJ80OT+duD_ zXxQp%+T-cCkMP%0<@}Gl7pumYC!zcBOAR+vZpug)G_%+ zb;3^4(!p?`O2huA#Jy_kaV~{ev>NRS%ss3r9(x@JhnH8MtAoB`<>jJv>NY7wD;7dR zSsT@o*?V!BUy#;M1c-8GJPT{*Fbs91Md>WsGJv!Dc4^r`j*H*Ji?mtgI!}~DWxVAL zl}saMCEP-uk2kDkCZ@ulG&RXq`a%GQhZ$<29hZ-o+ga&NT=lN1rtdPQ+7HOA$o!Yx zH)FcDNmeSk4aV1vg42|BH{x$MOXiGtC8|1usn#?xH2LF5kV1WWwa_J_S|^d$17Qix zIXu2Oqc?^BqNyVtP>v|%(Y{drX>P9)S5(Ls+56HlxlhZ@?f<>Blsa^#BCqMjyTeO_ zDk4ER^wM%|NHFy^;iY%L#8p~N|MN#>cS5n8Tcew%4a_dcB|u$2ysR~5u~|AIE>rq7 z&$L?b?Vt7=OC<|+smWT`{DOkcrA~iU2MY_b-QDDw+kQ#$04Q{nfdtpvQ}Zp6?}!b? zo4MJ$a7o>NH#8&?0D*u1`sI3IxmtS+Q?yU7wK6L+DM`Faw~6iPVsw6KP}7Jm`RCyH z_QY1rrA5Ai&>(({>SbM7^OsC9uW)ugo_3dEo8W|#%|m2p4-728k=Yn4c+7=%BA9a1 z1mzJcIPiI42)U{uSp-F>To<-U4~hPF=9UgI_91hYqUFN>bSK@1}`eEZv zt8C$`OX+ON*}DBKjbPKwoB{ zHS7MP=3LKXTfe!q%t>07668<`HuE@^)UjaHWYrI<4A)s2r=z~p#TTKG`WpIT&3wu>FCJA8jp+->KY4$npbOoOW6y>cbz3}03_T9VW zccRG7_g`u>yjROd{@~uw3*UCFKsLs2C0u)>BuKvES1i(2WEibD3AodZ-7`rCwJpFa zf+FL~jK}&KH}j`>Og}H5sptAS-rZb&X*uaIV4s_l%?<9|%q?yIz9uEhxm_%7>M6bD z+*YkqA>H4{tLt7554c4A_)A(^w#IlD@Ap)MY)EBYL4Ll8jETwHxw(8Wbibu#!ku0F z`ve?e9+1&n+ln(j?&~X<*a#g6wHD*z?uxvjM{w6?d_zy^D@~BOz=BO`R0>wp*5>&Q zS>TfTya#%^H*`}_Nov@wD1x>uo#O(OPWVI0BH}F7jj`@`>Aj@JK0ojl+}vrQZ>(2I z`qkI0j2DuPZt60h)NNc?pIu|C)rp%AxM zf}8amMn*?Sc+XiX+s*mrk|RrVWTXXa1S!VX7Tom!@5_v63a zgDy|P;4cW3#*tyUpo$`U!%iVCV_GlRf(u!QK0e7JFebd1d z<#L_IsQeH;Xnycf(&hac5}bj%axZCS*HTV^(PTn}+3k^>GH@5bI(+Tj;Wl(S9FaWA z^nOTCpou!HrM-PC@a>-5Vf|P2DS_JBna5zR#M}_1*5a>oMdZY;I-1Bl z71ju=W_+eK+SAkL&3e$rp23rWrJ&?IYqFSpm;Jf@tzW+i+w;HG)?WCW_g7T2rTQX!Ysm z)yGIJY=YQ(lj^!p(3X{W)6+cqua!FP6zqaa6S}1ZO}#d$Z_iE!T{+T~+^7XYd|$7r zM{bCD(>RLXbpO%%K1rFH^-)Q3h@~D;ET_yr;3eSK1s##k<))jgrv|~ULKl%8uVp=0 zDe*-rL=PauP=^>h?lI;dnz`D&a{JmF+BCKi>uEq=XG)CsY33IbtAmp_H04iIV)(?h zRCBlN4Gn|8ZIkdQN5AR5sAx*oMtPGD*wk`(Z^&1Ya#2<7SsDTn>E||+ya-MrJ;lTK z*Esf8?KPv^f>wtCggXMbbS2&Hsa@>L#-leJb@J$YJ;l6JEy#t1P4UgRGMwet&Xyle z9hgS=zn%V`_0PgA3ou!egKS(rM8&Jp2r*PnTo$yJhA_Uk(4K!BUOdL~urnB)s!4Jh z7@(fx;@4mJsHCzxSS8-Q?Gfp+ZX1(7!OC9sJqB8W8JBZ&bJLOmurdC0sIEa0$*lB8 zn)4=MiV0cYr`;l1D99YMxbT4N{Q6TDZKC=q+f8JhRQ8t%#|sH6m#ci zpvTKgF*+6z5>k9$tsUnaR+{0|X2UeL9$K2gw7Txpd3RK*VBmEurpJ4oW5%xU2Vdd= zVK)ij%Cp_L{sMKgxn5P%Zsps{?eRcUHO+k_Lrr~n@yejV>_~3*$goq6OP#y(!Jx?z z$Us4Uv)7J8R4nS{cFe`*OQx{~ zQTr9i@fy-xazt~}-cd*l8vbOsOxtEmW*n>{ie9CSo3a#uAm+lAX=K^;%=;72VBnpl z^5AZ%*dBe$#A35kwhTT~^bB|6+7SWSrN|UvQ+^nm>*l3byj#qhW811hDQjok^XPXH zt}3#eb?`FSY6N<7Krc}TXd&UD``!-G(oST$#<>}u*0OAMVqV#nlrMmbs)=07ofn#x zISgf_W+&VsJon$^KO7O~u8v6D0)4PBQn%$_XuOWd%X z1c0E?K}T^nn0LE1A-^;(nHE_RvKz=aqnIG2KL16zoOC}lMN!c+!Rwa^Ptzc5T9$D)N3^NX>1oAs z@Web3GOu&KR@G+V)0pd9TUkZkuhsze1J&aPPkK(Hx=y1uBE54i{GK$ zKuW&Omx=@xp>bPudpr20V{^O&+JNNLKdwf=7T2{MLBCF>>xR+CK%&^o@QQ?#Ai$Gv zZLPSjF<0FKoWnWyGzfARmpXi@_FuQ~bh?q@u356P3W!%OOWC^g!mbpD2pW-0Pmq+B zm8vC7pP2Avl4rcHSFj|IaI`?rdM}fQ7FEW*q>)=&i=jN*Q^dnFQ|lvoyqqZ|=^{k` z7}NZ+0?^RXobsJQsqEO6*uqPSR#ocPSJ!7;lm>J`uBTgk#WmUWqxwzg%$V3&i;FeC zU%-0$DFf;61>3w|uPx6JSU*SCFM02NTgN9p#7KYt2?s0TZE$mxe1ylr$nwGyHM^$f z*?}kZ~yxnFlhLAiknp+=+{6)C{hG6v9Cq0@Aum|+_^o7P>Gz9QFUAj zv1p>B4!=8IdqHoSOdH$a#3ylH`h0c3PokyFJC{s|Y`E{SF!f80`bmsE#zcA^oRQPf z;wwLFrN!9XXV<{>I(s{`3Irj{DH0p1La_A7^)lb1T=%Vl-^@5z-uxa-_urH8>#!!w zDc7A)ZELE1Z|OTkP=~qc(M!BeLjJ)F;p!Brqg4`e`XvM5@Yfdt>313myyB`(L)zK!vwZvSZh85N*HyGXiqnf14uqHnu z+SVLGwHdEYVBsGn7ZRo_xa+|v0&qR2*m(D}gnpPzk?I582gb6%)<21)e=ZZESjpp0 zMsMS2TA4~}WMqSB@xINz>45hAlPQjD;n8p{kpLDcB3XRLEw%rM<#47N8ldgctJM>u zxzLCs-w=KP(rW-o3__8h%`H7P4bCIqFVkH%F=pz7U}QZ$PI2lgwZC4dOABGkU==rk zrTtuV(zNqvJCfZ>-;bU@`lW%9_wR#E4xON2RR{7X1!(8y=d9Lm zb=z8FM9dj`B^=`WxoONXl0b9BDzR&)jzr3NvCPlgli!|>CGq1O;(ggTxib2OtdPt+ zb`qlZ>p=N&O`1<#nao7hT$a9FFrq@XmE|joSk)%1?H3NKe5f^FR#98sI2x}shEVLR zhX+1%`5~wZXoUl8=1+pHElIyVy>ac~M*>lgD8yA1xtDzk8PthVU^|EC&pA;qJ@x)4v%&68CZ<2{QV^lW}%;ic$BSXAePnrR`z&pmOt< zD%;OVZJ`~z<^;eLz-ejsx-=>3ZEDX;aOnNvGC&U9@*TVNo&{=16i9z9g)IDNdTKWZKiA;X5^yugH6!4Tm4JzJ5<^BTw$HLg* zFsw8nVcD>qodq{v5@OkK+^S8#Lj&ok1J;4P#n4ZPxx zO3`TLe804Pnte*s;P%Na_^knSnX9;+u2k1D@OpxsXR8uEOeM@5Iz=`py%uYLv$xS* zh=DU;_hnXmSIWWit0%?94cYYq zllD-(?d`^4&DTU<5^`>`$pV7!1WVoBmjZN~<}?AetBdb9kZ_Yl@o2)1MI90+@1C7K zjr~uXL%)QrJl=clNbHF9tvs$(EnGGj2Dl;lpGAaxA*9#LZOXasm`v5YnR_Vo#U1Xn zNP~aP48r-)dpp8WcDLi6G4~*vUbkA$&lO z6w+ljuToLF+p|_n zmCZu<<+j!8n|L-FV<)5&9$Zo=|A(fl0II5a`!tuX3tSqcySrOJNu@gk1nCCJOLqt& z(kd+>-JME^beD94H2nAdX1|>1f%CIKn{%L$ zr2!$#{hXJf5~0sG9G32^tkO>Prh?iqCo+L3k4Rt~iyS|q50Q8v?K<&uFNSR7SnQ?e zhsKR1y%Up|P*K@J*8AJ{k(M5$zyPyRY7vt z3#N}ho2vdUnAZ_^OZu>g%^RMq%$UgtkRLfcXqV}k!_Z_q@UQ~i$iC%B&~S{DaJ<%{ zg@^^5+@4?GZg{tlN-5G47+>uVBsqI~M$Qa%u?nJU;!`Ai(Az;7a7(gL@pO$XV5!nS zKRwvET8-U$icl)j!#b1DF*5STA%3R1(}vWrAew_;^QcMHPYXR+>qmczyO-Oh3(X-Q z*u6OMsJD99(>T41!CO7|@QR$r<7KcW)5?@}mtUfz;rLnz9sXpYWj7kKl!mOAK+NU- z^9RjaP6gLMx`-{}XVPQoBAfaTh@5OMaMDqI5Cw4reXM%k-rH^n>$eq2Y)O-8iQ(Fs zxQM>_Wdu=4$31;R7J=Hs2ksfWClo)_yb}*heF+n)6Hm{sg(<|2nXurMNSV&W;IT0C z&O{fMsOKzkE+QzrS;8pn zLsEg#DHW2vBd5nkj_6&Mw}iW2<+^H!Ok{A5xLw_C=~H8a8DZIUFq?sGkV0oCVCPia zx4`{`V-|Ezjm>1GddClitiq!wUH+zg9c&O?uM^_Eten`>thSNNd4Es+kt5w{!}8~5 zroPYG@7Wta2}n2+z9NCP040C32rk^B(^aAzHGCD7Q(wsITVLTYJ}xSrKnyWzKPCHj z39H|TJwI^W9Mvl;-d#6VRpA5w;?*~n{42~7XC`=@mVbrEy2s~^3pBXA@(i`o`m_tr z&cMRcHG93YF?!g9NANQ`c<07x-j7Ln=``w#y}DKe&ViotNvrw1wT}jT}$PHM}u_aks4Zt^zT~h6XaiM0;j82vicI@SJsDG z0ud`rv)+DYgBnESO<4`SZpiboW-UnOf%MRlV{Am5nc#G%IB^H#BULQp^PBhXglNfa znWNF&iQ;2g8-%bnAS6m%O(Ux13y4WhS3W{DBwhF~&y;QVgE83;xyz_PBj$g}l zq~o6n*Uelg5pi|gJR<+Yq``qI$~xuXE>0;&+eyn5VU*OCA)sB z2JXI`vx*^)C20qTeQvLoisFi|6+3C;{)j}(2}(LTw!A$&Wr(wQfs&NC7G1s>mbdn{ z*3fh{RD*Pjn$0}70g~3ogX6WsJ%o`O2nv#&!~Wp&aZu?53^@hJso>YS&JCs zb^?Yw*h)JaW@3c|eqk7XVFZTRQjh!|<8M7dEjtNC$RX`Kmk==}D)W2Ef>0+UP`6Jy zM!_WXQ^gWGVF#UXfvvgVuW3S(HCZ0t_dV=iw(tgGwT9n?^%;h_Cla3um`(sm>6JTQXb>jnWvy{=3#QWA>u{<{%jI{6KjKeYTuoE&q7Ci%4$u+^_1o zG|Tnx`UnB$br(L`FPu7`_0cjbWXD&5+=|JzQ`15LiqbDZRYlACg_e*?mQI|5I;bs} zXqaNX_>>VuM;=f8u(6!otdDjStT2;LCv~xa|5urR9HA?o$Nw6WiZj<`lv`Ltj zkc%l>7OrlKFmhh)MU;R{`jqqf&N*lQ@9O(r$|t8M)qf9gZBdeC*0~_m-jMt$IAYaP zu1xuFA#xmg@@QH@40>{0dhnAF^BEMopsoZFr_O&u-zfa{Q(JMxd_^<+V2E}cR?azyW{)qC4UtpB>5jNRL*`)Ha; zz*l_Y!{1DMPruJWbDkf?{JB0W%F94f9r1(|@sj;6kKFEepO#QMisKFL(zDrAX5x(4VW+$h>EzLn*{E`6yA0vhg{LcUlz1W>l7i$M9dpcwhdZ{{Z>jJg${}f{Z|D zoj?1@*3mot*VU*FrNeYKlqR%;KZw_vGae|~eN)A$%7vNVcql z2B1&OGpp+z44C)2V`Bt%Sf3$+?06^-Z)P$h#*LSrH&h0ZHuhOT3M65plaC`5G3e?A zPH-3U47aSU5kE``EVDe0jgaPMF+*QfjJC1oz?@0CiKJxf>0Fo!DRX+lQB{Y{NPgJ0 zBjz5d@!4pSF0efJHh&dk2BCw5hkgv4H_-PRd9QM}cJ+FeZ%Kg=7nJ}5od9E?b>2<@ zo0mMCMafFC{*IXJFj1dZt6VX1L!?RqFK5O>4;PD^vsO$JmLAS=JmSy(V0VH=_od}m zl#M74c36En)2no6#jS*j*(NJ~L-IW^_Av?dBvBJ~iH}cen3Ukr$!n=gEsE+kx}UAp z>RbG=%iBWT5kUmdt@Cu1j6`BU)?B|TdT%$(kiv#hSC4j>upk9q45hdric!J`wKOVX z4J&ed=TO1ZAB%0_Q&m|Vf%vDl69gwTr*~B?=oULs+MnI}ML+VL*B*tk$H*TWc|Qz2 zYJEc%;G2{FSGV#4eJj{5(@k^JG1s_ee5cmu?}Y!!gI+GeX?I6j2dR9L*-rnTxpN-Z zeo8w}Ke&9CK5;vPg;}yWhnuZCl*%&dsIro<5`&ymxAGbx$bS=eQ~&%=T#JxFf2OCW z=gRK|S&X)svz$NK9hoW`XweQ4_Fkv8SHTn&px|K;#3`)C!V^08b(M2|g|PB#bTzW_ z^E6sBd=87D8{uQnlB*Y1@5ff;%0aWTLQ@xs`<@`=(>zab;)j3YOMrPxfQg15Ule7n zxQiR+&VkPJ!qMkNYn^(Luv}T<(1)QEEO<T0eSgl?V=#Hy8B(b;N!# zeq5po@uwIw%Y!sB$Te=q!Pm}RbqDU|ys7n1ip(KaWK+;D1uQgE)6=;snc;+fK_|bD z>EIGy{(WLm;yp}5{TOtlsI0ydgQSx{Ow;~IsM~(Wy%Wzgl}n6?;<9HD>$)b`AeZt* zKU}P*;70|Sc!QJ7>ptBB)|Hs_Z+?R*vz*s4ztuQJU4PSIBPVQiI@GdIyCNwiWQS^P zFco&L9sOIpd+(zQ#*7atDn#V(eWUC65XdR?aDwCIv?Q|HGcp}O@#d!}5i_?w%64A< z5*mG9`zU^d&BVlX=$?tVW`j5B+p7aPc~8cGWiFN)D7~3tg8v*wF6od18=?Kjht^vK zk2nh$XvolJwES^FnAa7)2pUd!OCyS51vT74)666~(y0;Bs`R|cm=TJ((cBV<LFQf1D4*>Baf<5q9Oy~XyfyQZB)lcCqWQzQnnZ#(z>*^G3d`rA##~| zhnH7YNaa5)Y;~3Ja<<76xp{uUGPMYX#zAyWcuT}OoB~nQGUsIJ{iwohu{k^Bg2Nip zWgW6?x0l1dl$#8h`ay}Vs0F-_5TLeLfbsjUyeJ#-cjx1G=j+!!o)Sh(?_G@V;(!ke zxfrDtb1qzkIUD;b$s&n?Rj8a%E%J~dqKBm>4sZs|&dBfex(D;^1h2&#EUy0jI`I{= zMEON20^6RAN+mr1d8HQ1ikXz<+_RdZ#X>ELcH>2w<9lEVLCUzeiu#&m=yI5yXs$2^ z|FSD*kOHWh-1uH9IUV*$LDP3~yoWPOms5i?wvMae`T5%>`3P*e*RKUx!0?I2#C%pm zIO9WD8>hg6_sAN*AE1YcxnUy(nkmUGO)o}m=d|K!e)*DP#z5XT$V&t`RzdYQ%$jEd z%9>1Q))zr6HI!KU?3h16)r^fS^x1@AQ%I8Zs4>fo+a*#US?H5EN)UHdaon5Y%^Q+W zEdPclOp|!j*5$Q*C8Mf%X$Od?tv`FS*nFa$wTnhqN>-#q78R-&vm>rBX0{V_)}*Q> zW|f5;J9`?gvrb>y~l-7WC|QoSN3C05;d925QDN z2VG}_$#N8eZ2*<4T0*;1Ey2M{yRArbvMSbwLLS*xK=r3!-w%04tZOiwPYhMd6pe%M>}?l zuc?Sy6W@C?ru%OH{%Z1tiTg6W;S@pl4Ofpk^~&6c$6j9vM&QNMi<66q!T+kimd~IH zL3^;XFPArRrx#lQ(Wz4js&^o%2)S*oCMXItGkh}3AvNdulrKzXF;8WtF1jX4q zFQ|xdRSQ~Iio+o_O7FRZk1SEvS8Bb*In#V~2;#sg1odII@t;~i+Zl4L&>uS3iI;yB zI%zl#iUPd_N7Eij+RMxkO`hTcBPfJCyHq{ZhV0knl+R9oZ2rXCRMg!ZLdBa5F{+}2 zIeFo4+H%L}E+Uk6c6Py2Zw1M*n=ug*tgRhJhkA$`BvG=}J1RTGF+efT@mqZ(@JcUq zBYgSmq!a3QO2U`on#HLd%aaj`j*mjI7?T?PtXM%vku9)RTI?73*0`Vhy;m8eeoOw` z2;SR)<`xpJ2sAiTH~yw7c+FzLY~?DWg&z-}c%>IFSSHo$ZT4M;XBBxtqxE>1#~O^4 z%O%x+lf3uKnzw9WI3st^ipeV|?5AksrEO8q}DDGQVKq-b{dt_Nv0q6#t~lVQeEyBV$01;9q(7Yba_B zhdi{;N3azsTOA#IDs-{Jx)9oy5x_6m>R7Vl9>@CX9JSBmOoRWDYG$upx6Bjog!dh z{gFrx|KzUfdN_;c&2JTR{qHSDHY<0@vYj%8lOY?vAKlMRZhv$P#CV&AFI%gpSm`~! z($NVbYI98+zhgwhVUzRp#94IO{t8dpMsV57`3A{ejyumVOFi}dUp+ll z^RQ>o25og8TY3vKBvSswr+IvOI;6BzQorL7-EpBFXKHF{XKydG%RE@AP=!4^?_Z97 zf_z{;(MC~rT+_BOxD<$1-0zX+t_r< zeHtAuG1g-_6y9eUGUo{PyHUHjxtR+YnG5vC*~KeOR(!HTbBE?@B1oAbP-~FRFDy(< zOduu}VM*oUnV6WI__dv8?--s)1R?BRp-k{|U|p>ee&*R#NP8)UVc52YpJ<{51?|hx zpaacW>TW=v?(<%h-q*||JC&C&V`sM56ild=N|i9$XnMebq95?xOwP_3lNbrqzPA(8 zt1`>PkdmQ3NR^xYz|0N0$Svf06I)>em4$Szc7^e}ZL++`62h_SPoonSCS^)xbuxdh zT&MhL+jqx942B)yM8E1{_wJpnq9STKw^>4E$0Me=cmG?;oJ^x1 z<+*7UzjcQu{8egwn*T9d^$&}sCg4whElZ5K0f|!sMPHx1macBZ@88-Yl_Mug1sbpA-;wE;~1 zV{IYw_`xym;E}EFC<1z(zP6rR~{y(Fq+?)G)OVi2rfAR2#L z$C@toCGqdyHvzZ1Mfz>G?2dCar~vWWIXfRG;C?BxvsR!dNJ~o?*p+UF(f7YV;kMgZ zbiwrO8{na(Ew23DJ3l7Xtw+-l>%#NVanwhfELw@)97aMC3wAi6!UXJil;U8~H8p&3 z+}Py`(M~qwYP_d z`SvJgz};cP^=jBvwbK&tF0tOFs2bF{69|aKab&?!rJJDg$_b)86|%{ft0L4U+3)mk zj`$q)&shQR-)K6&u;wN~!s~Ksu)4k2{V3u}7=c59mN9~wI)t6GO{a1<&oh}Up0nK& zZw*%DyPyB8PfY~K6^)E2O3TWs{jazjms`oq-d{2fj{wCY++2X1|JjuS)l2mpoUcUR zx<02ydYj&ed!WhJ1Zn59oVCu+N4$;g3;q6`%a4pTp9U|d8Ts-O$3+D5l5*gIs z@`sIq5(~7u%A&{RsA=2cXi;=Y?hf1(&d7dGsbK+1Ex7|UZjkz(Z(rAbKx7E;#q`}iQ~CuI-MdfVDVu4+lw`|H!j z>vc8W!24^b9#I|NWE(Qdfi63NZficz5fkU(i~<&*stO7UUT>x*o({8Df^m+CduDYf z&WxZ^S4daDGVBS~33uaCI8efT-Bou6SYu+0xsk6~gXv>5)KX9qHq7e`!S|zZn6{#9 z^vB2gUU!)rQa2W`EGcB4pe1}`sc4v(osA+j3qU+>yW%1zC&!Og_^mAl#EY6C{;Hh< z2Xk*y`iXYMWSf`-eBh3(huMs6EQ~#3B}fNci)o#dOxT$>EbzMj<+#5d*tWPnSv$FV zi2By_g_)P;8G-7|+d7`CU-rt`eneYaTl)0}f&r&}q{S5#A!FP7k4uS!$J2lQWXn50 zW4zb^r3SgK4(IeZyMq>f&q}1N!4fx=%DhoK`PcmRB31L10HgpG{;}WX6MP#?$aPM; z=A+Mxr!nd2BphasbjtzfIOQfSLY!d?){u`y6n_`jOujm+9pvcx!6_yl1U8_Bqj6(bU@(thEGEWHI~` ztB2c5{U$d?sarcyHa0d|NOhOIa&Y`wl|Wfj(}Y^veTzcdbr~{GsMjXHE z)(5?AC-30cu^o-8c81L{MxLn|Xq_}J$@hvfxn2i_tee_xmx`9zwX75Q%HPH3b)mWtqSS-&rheVEB z&t2#3t3}Z={|8QA~)m+WY$ySD0zwMH{{byn!oZLa0VAMLFIwuWIVeMTLvv)H1qIN@r3XjYa=LtO@Yk=GEmJQ5UZ^wFuh6xt zn=h~2Oi*~H|Kp9|QS-j~D_z}h<;1{N4^@h#F>yit%h9~rXkf3J{OPBSN_UNIU?feu zDJn0yN)wkpR1r+=MUTl}BA0(A&4scina)tE$*|Ej|Nf;GZaU3@4{US^uatN7;7P|F zE;M{K+T7NGZjFJf^+vv%4`B5}eyZ2 zri<2!BNxt$SV?q;ha$G#1|_aXPL<)d_-blFdY>h=l>oU^X{B=@zZP_%DAQylE;o;$@nfp+Vk^i3cM{#ei ze+MOU!2A*``>bIOdjs~88lU%(I?S7Jp+gy`O=N)1HU`!lB7&k~LK%id4!UO2o^QuW zA}SWi>QT#a-=C7n-|d~z6W_rgfv|($roB1nC?9#P(1hO2!*6eIzvxuK(iMS3?b9Nr zDddYL*|?z+;z~)r|8G5fWhwHEQ(ERZuaGD{#C$l7wejf@-SupU*%oT52So)ZLxXQ+ zN{t@Q#dH*+AmNh0;>y4>3%o&<%O7838pEN7-w#^zRj#x&H2aOylFrYI?Z{H2?o>!% zGB9;F87Gv%B78ABEnfaJa%v*B&8}nlfftPr=7$IOtNcOi_H2N_PgRW}Mk%v6~qH|I~ zO%02y?Sjy8wn{2Hv`JU7%eSu1(+vEHyszP0j``Gn+}&F>J^Pnk-~*s_oW)1d>i>^?9zTqkRIzy3cb+B0cPL%zI3`nGJhBU^frlL8G>KUk}hIp{wvW=`= zdRSguv;M)_9{`9BXaqi|cvppQG*DqmCLe}suq$+9W4YT=gqN>J;*=ToJ;WM~xjroq zcMlcPNb8~Y~jcqVJKYPtn!s3-cAKe~`4zi)NT%gy3)Z|dYGphWJ(P;SsNb*Ob=|I+EJwK_(d9@qv1=~%&QSny=*Nm@aCZWuxz z^Gsd*9qv)bQy`Q?j5cPM6&hi&>LOzI{Rn2h-mAjG%G#CX+@8#L-|n!W1f9)>33zN0 zaJJ`*crmP9`JJrO91Sd+ETod~0tV8ulrTUOgha%wuIlj0ZGFX+5*=W^!incwmFOz}-V`Z` zuS5u75s8z|u<_js`vwK@okf!>@&N<*^vVgnjjkIfk9Wt+75$9x)w@bP3!hz-&4ujR zuNAp6aY`qnBTtdPRsuhy!K@9GEG+1#{SPp(X{6Spw2cSO+ru8C?(YMB<_3wiKi;y} z*42IGOA~;vLVwI%8B8s_sZ)XN*M8&-+1%MF)U$gPfH6vzt_rU_1AT z=>B%b+j}fTeSjY{dKa;5?(xmTy02tX72@I zOb->Npi&8C9lE@uhDt{9S`CA#ce?CSE}TkpL+a>=wmtoc`vv$M1D#YLp7U*AYkj&KlCwIzdYcd=YH;yY02UMOX>R#hea z-M>Wu5H_;Qyf=n8x7ZIGj$bP@Et_rwgpd!^`ZU2j*j`RIh|Uss{?Aj2RsSL+rKZM4 z(gdRP_4Sd3&vBAqot>YT++Pw3kmIO}ZoLA>zfb|3Q9@mZWL-Yzc(3v9ojik9hk`7| zL)4m^==kz-$fEIxBs^&(Rgx4plGp#Aqr~;9vkXK<{HGINCP2NrvR8E9)Uz>j$H1St zmTk+9x2blxQ-X@2=iALbAFNTps~}xFbR6h-Jk|oxxg<~uNJ2%EYwdTBG~Zrie$qnx zJm(nk>rG+g;>fB9uI*=6rs;}1k`}MS7tMt^_I{2bX8tNB{{*;;#|($dnDf5pf1 z^@u%c1N6d`_%U+qEB=b7=Sa(bYh$ywJ>*lS=kT@rLHdq9fbo7iVSTV61J8|xg(WX? zG4e~hc^BDi`+EwngV|)ZqQI0n$I_KLhhsb;BWf{m$%~VeV5YbfzrS98riD7UYVa%! z&fc#`YDEo6x~&cdpjL^m65SWZZq* z5OYYY{QB1gp-sZ!iBw59*tmQcG@1MGRSY9|t`tzxc?*`}K$c zexJK=_*wh)Yvha(S-b>7zc>E{v?lE*3A)=+WHMgx0-&@0Zz1SIvK!!Dp!L=w6y?%M zOVd=g-x@j+84+%2x8L{&JWZ+k=?@t4@^b7s{9Bdgmipi^7sD~~Uw0d9~-UsDB;fK;fE|)Wd(mO z0=F5v$9?JP|Jn>x3q?gmpNols{K;Lux2&}bhqYs^G{Z|f6U?j9PrmGH$z_sn=;1C* zsVC8MpUcMW-O|PC4#HP0mp}jA^y?Rv+QqGtS)tkp&t0=+|fJio$)p8>voPmBIp(NmC|5Fc(qXZ zwdGK|NcSeu$@AEao41~iE~uRE!jtS{y1xVJP?`VwI5M<9;7a%jx7h1-4yw79zj_M8 z&uno#+uZl+N1XzH`fKbskI9TnYP{jJ8WcG<)SYCSgx$GCu?VAt*!D!H`r z)K2S|cq7jiDm?-@b&Y?55V|^5pv0;2ZG1G?S10K&^mjBnL+g_oJ_>;1ew_~w=i4HSe*5oO zxTrs|#jmgXK0YDjwYMizlQVjF9xR*SWQ_1e;r|V>9zzL}HTK>5z`{zFGeh;JwAjP0O}ewig$=Lj;eh$htFw`Opb z7?IOnqH60Q)F_2+dv>B9b1&rI53o`PoXBo&ZIzHa$2{98OI!(GQMPt1WUs{QcY)z^y|zLN!~Xj6FOXw*J$}~?x<(Ocd`hfQ>weN1fS!Kx7+m}YJL~==4S!$%; zDQ6_)UDm=$JGb1*C>%r4*q42AOb#n(|JaFJMkVu1m*0bY4i78uiswuvLG+hgVOv;) zx}`({!QIc}hzUD&#@xgvW1;r?^nc%UeIS7(3v!0BTjpD3WIB}mU>cf-I~#}x#R38OOYBnb46B9Py3%A0l@!-$gIFG) zlhwEaT7V4=E7GY?T;p`qMN!?iM^$zc3A&e%dX+qN{;Ts<95?c8+=q+qV8e$D18`bZ78dz4&ko7;Xc^IVg zdhQ9tk?Ew@dvlHOff32>7m?A_)($PJY-j3A7qqm2ov9%dS2`EKb3kURLW5=B0ik#_ z6zCw0hxH4S)aC@|{|vw~(NUo^|0o?Kr7q$6Y0ppHAie6QW$MJsb3AN#P~5gUU=B-V z##X6N%h>AS3_Q-k6nzv%&4o_p`rn|##|tRQ^Pq5LaEB9=M14b z8rfl|8v{j>y&we(PU9Ib{f7u%i&N#XOT4!S$A9&~SyuiRwVx)Lf~1$@HOWgAZQ?Z- zSS(4lCrmN0*jpW41V;j2&Sikg``f%{5K<3M(cGcex|fdJn5sy&7m_(O!W28uqg;j< zGr(qtq6%7{oFd6>WElUOp9(4}DujH=C%;M)?dtqLCD~w5Ob2Gx)|lW6{KpUpu+e@$ zW`b!jyn@j8S=3!qH=XTL&S|w#7eSsi-m}%{3HJY+2rtD@$6aH+iD#F^1j`o+=S53&^WdQutMV# za5Oh35 zQjdTAJs*0jlaBAEQ8N>#B(L;-J9^k_FB>la(0trNrFh+6+pZFkmu8i60_14L89BzM zJlO3I2OTPAG(zPlU@rdLvHiU>+Zj2z+uI#(%UEIm4F1zyP-j!+h7p^I6KXBHG0Z^p#iBt@1V+c1lw%3)urO5h^v#cucZZg0A$Sy_E4 zV&~?N4qxdjJ!tr_S^6rVmZ}C{e%AbanKu3d`F$J2( zv?En6YX(E-EiqvKMLVjDq=%r3MB;IWafpll`z(@yQ-B$qlv+l?P%nW~30+!ZtL!EW zR4)1HtP^^)K7ME#EBBx)pO#3#cT1ml0BX{7xd9-vWS8xKH#ap^M))`k+(P!M=oGc8 ziUP3irJBQE;?yu$ffd(TdXb}+0te99@?f@FKujqa3U2UyDT$EqNX?J`hU3D|LIPom z4h3WnV@b`D_G&1R;+2qP^At7bB5uyNdIT(BRp=K&jHAy%bc*KMd7DRXf0oe`4A2tmDT!4hJZ`9#Wcc) zhDRNzRj6dMNd1uXojtdST*OfrQk(g6cCj{R+W zP-J8YZu5g#*U|~H2#ZwQmqTxS#1|%BH3;wSyZ`<9(jP&@?vm8{Tnes zCuxsbq5L+*C5IY)4wzJckJ1ks4>782?2NBK{!=uVn}uG5bD#wSZ$fnk83$NL7=k?P zbNslGR9qSC@51FE`8O>b1HjXo65b~Wea--1S`ZGgu@`@h^y{(?Qugyrh7B1o?D+Rc z@^`snevCDAsdUV}AXR7V*Z8OQf0HO#6x)Vy3_BOFeL?A2#_bl*$=zd{?69 z6OgxMUUUt4_=D>tLJ>AvKU$Dd7(%t?6pAM7G`0C84sY-%2PQ1|pa{WW`h6+=>f-Xb z9@gmv?h=KU4;?~Rit3uL3DGIafvBizWU|D7h3x)nYJ`f4O26rh2>2T$;@(GcIy&?q z8A*VvOshf&p~FW(1bQ8ABr?5HT=!?uqO~~w(J!wjAFxAd&96@gu7OyHd)bSjsaHp| z@$FXx3a`Uhl!g95$!zIf2zyK@c&X#gC7MEEa_y!@+0^f1bW{X$pfI>J8QZ;mtKC9G zF2@r=c#9A=X)lcAQqo2et>E%oh54(b6JLIBB3yre@9pWVRpL6J{YoN~5ezCxHe~Q5 z`9M=1m;x=njFlC=kkevR!?GWdqGH%dFOkM-FHw<>%8~L%J{vaOO4Ij)q4-Fl&21kH zG^BtwI#Z8h{`zb?8q-^Lb&~1AO7Jc}KOYe&kBsg2XIOv0p*C%8$Ur}o7^7z%`0v{P z)5Csd3F9#l;oMwd5yp<;`93{dO%;42mm3@`7mYnQ#fJ$88w+j$WQbKXnfZ^8L=NJU zGZr;oR#tX;F&Q+#KPG{buz?GUNLHOY*0`wQuo}ye1Wk<#1R_Wq0S~gbFqQ5Ck{m&_ z0&YbaEegmSB`NThjVY%v{5h^b>7n+UDV$*GPoT=0;QNxJ>aF;U09dc)H)p`{awHRS zUjAc3)5G%i~~*;_5J#`d^Rp;WFfNZ>bSkdA1BiLX48dn9Co1Ph%xIy&=urIAgEuzdhWVZE_d>_v-b=QsQGIk?qf)*S0krSU|n+iya$K zrg^Uro{yK5k%1n|$Q*s7OwiN0>4tOv%fUc)N7sQG`GaQ(hO=<0Yb6GrlkG7V>u_EO}y zoxtF)*Lo}kFxm0rU-Lhbtub;Eyoym-tPLW1)&^PR`dy9t;nbMnC*$&XYu#Af!CiLU zX1TtI9qo5cAoe>!jM}PYe$X53b5kdLnu^6GQSem^WEZ5LZtAW9=PH)D-~*x>IQdk- z#F7CH+uuWb{99K(n7{84iW^+&%LG9JVH*B_ajD@N?CjnfxBEc}-@ku%;>%#b=uwT> z@DB3B?CVkPvW`-G6qiIyb6$=za&9N66P!}66;uUwVQVlD55S4yzrOw0x`S|xJmcnW ziljcV;m#i^fN0oK{9*bF_PpHRBTX&(X>)JpS=M;~Iv~9EaJ3SqM8A5^NV5mL-rdK?E7)ph_HX&67EMW)% z%90m|2y!qSgx9;j-`0_7d{+IN4RDzMaT_|2==O9)s^cA*?(f?0c;EgMfrO&1vEV24 zch_zdsSm7}`Cv3n7gD@z1m+RQk%X&ynHls`qL)pTs_xV<&_OY+8zPtIzN`Op#gjA$ zlq9-Qi(vn*AJee%hzE-R%T2%a8c8A5de)kZXJ4>!wLop{>Ml`c2H$b9k)X2e9~*Iu zsbH}vlw@8ffD85sXFG{e)I$*=Z+KpU+q$)y)xhT@oHVBg$dW#tDC|I=yrT|)iIV92 zt}CZk`mnAXJ1Sbb1U9?l<-Y&N%9*s!E^GPm%LIW+3O-I`az)mJjh4dr@$1V{kbkHfi4p-av&w*t83G0D9j4sGD{F)o z9|g9G{T#?5^5M$^aGAmsMfZSU^@nE#dK|-o%A@l zqg`lk+tqT5e#6m%ymiVp>it8Bbbi|svY>MAMsT9u`v^~m8A`3>y+G;@COxawWmQ0P8}+7|L zj^yR^uBb6US7;OUVD)XL)A9}ca#j@aUsnS)RAs(R4k4iaEu+x8*GGs!+lkj?SC6HDmsf4s>X=R zCwwvYGskb{C}OyHF?8-S*70~-(=%#C3(qSoq}p$PKwBxlxed0^k`yhN**@3m+F|^1 z`x7ICiDH!2NWvqA=VQ5?p;OXYa|84$CH+UlY4iK!bTsMf{Mb{cM}i|9;d*T z+-zg@(DUnH;6jC4B*({b4UEyx)x~A&jVW@4cG0r2Pnzjv*;5#6ko!UQt8`uh6E({}#Z;pY=X@X;d7CZK4ENPxmNW?NqpZ<9DxO#~d$ z+x!ax?K*6?&j=}BdA;2}dgtsOz+ag<^S};-f4~Uk-C6w9NPk>l*KEFLD@l|8MqF{n zt+VEf3qCjjra1e zc=OA`?;sYPrvcL>eXbl?wI^x#q2IYQlqU?c-BHLN4RaoM3L0B+h zH$8)I6FZWWR;{QtY?p^chf=_Dq`V`cs-}T3!uLKPQ}IP6U!57t4@WqI%Fe;TtJf?b zIyt_V)K(fHgI}w%HMDX1r6P)0QKiXg)^bSJ$;qjs5igZl1Hh24-4kkgI($DO$NR1` zF!N*a`!24MXI{PC5o% z{8C{#&htJVY~aN4ot0~E4dS3711|r2+xNnpC#o-&`%CD=h;0rB_BWQ8G#uNcm+tDggYygGeQYFGCCz?4JMjG(tAk^I3-BlzEXj2i0oWMluOYRiZWx&@!L5$ z4Y6znR>{8S0d`H)=g*&|&VS42;{)I>20?mfu>aD-%j-+C@*yCoxX*?-YC#?yZ;G-h z5*I=GZcY)TGF^u6m#ceAigF@8f2L%cdXLhvlIwBsJ#V7hyvBN~2_FI5!V>LF+bM}BW*a4XW{?_6G$v0%o;#=0*1O6SW>jDQV}&k1(v-p#q78OZIZ!Ze#- znOxZk*tBTzg%`Yekbb--de7(g8aRL;%a=#E6nWw!v9qIj1zx0$1@1?@D1tyHB=mDY zRx^?%3@{z}lrOby9x5rg`|r&>r=~y@v+d|Bk(|qfBI%@4s+5e8ky^}{qJ05eO49?A z&LY@@>3qCx`R89wW~{qkIg%6^rhfL7;miMZlY?F=??sFsKpTeb4xyoy6bYcDU*R%>=W=3@+NlyxI_dk zDm8&X7y3tAj)oR&B#1$3U1gPAg@vYfkQ$D{>S}_avPBhQ#tXzP#ym1M4jMOS83wE<20BP(DCy?T|#OtvS#%EEReeBO5# zGr_15;qV;8`U9#E<$%S^_n2A-Y^b7&cm*Q_$<$|!(b!{xF-pNN=MSR_eCllp~{0jRBXpeiCYv9*dIsc14QvvuNMDS z*nd=UTlxtVWM%l+h8_?=a8Aj{=q^8*P!W+E;(|k+-Udn@2$jWf^k}^*7kiUw0Xvwl zqey=4$3T_!loLo-2AtQzM5&0C$A1&E$G_#zV9^Soh}s3*pJM*}B$$OMM*}#y6&6vYdry+c4SI-MW?AeD(To@Usyho{x6PcNKG3L=*Sd z<$e7sSaG4%eCA!X7I?FzR_%4@{ZabK1L*r6iOIhh_>!I%&K=?|0)MCa?Nm|K!r`m` z(R9^OQFdR~Lb_8x5Ex1t=@g{9Vdxq{x*J3g1f)w^kPuM1^QB|xk?!v9{;t2ZKG&MR zTrQvIx%ZxX&OUqZgK|S+XJ-dg19BJ6!cUBN(mzc6R@Nj?lScXcWB{2d^x|R)Yh9tq z8f3x$IK=sxPqZ{Nf&(6J?V9dRh`tM?Y_6Ur(HyKQIDDyg{1M`C2$gXa`g-_8*$;SOx!Tb+< zbz1E<1Mu;`_nk?dh#namdzQto{XY)0^w!y*U zCBNlRieZgIjX7_#wm3S~-%m1xxT-i3dHSj)3~$0GJ;$@Cr`B@}zeE_UwG%#N49|Wc zE-NmOYd14w&oi69U!~sCDr#XlZEk5H&x2EO+GNPIv^SJ~owRxScbF!4T#qob5MwyA z+5=8f6}%P+e^tIh^0_>qik10c zt*eARU$J(jqZ7gLbc>r?v#P3!DtL-UcI?wz&c^v6rqZSX0LXAMzmM)R1w2ixYkoO- z`TCok;(tGA?SUeN_ZAg^XYv-_-Ug!C9L#y?gB_*sJ}vFY7p|TbB{dDm8poc>O0;Gk z4M1NeGQr>>*jq7|oUCQX^CE?)+x4wjU2(h)L_(SCa~Xzh(d+0%9~mk> z)BYCulnmMKUBB{aK2;DE_(mogwx2e+{>^iLs{FaZWGF#%93;$~GYn^?>>GYE{0n?N zr>H2rP`!W%`|OrrBrP?S9fOAQ2XA%Ni-=GDzh&g*DP>10|GN%tDX}Kqoh+r~fv3Ts zovX*VUZ|&=Y{n0FNbmE-EC1Mu9($5QwSb>O*G2MWSkuLf4S&Hos)?$)C{n?!AX+un zv%!P^@@K+aJw|4lLNAgmbT7HfYpt2=27R^;Z0RW?s4GUFK*jqX+A%mII%#4d35yS)WYR`Ky{`;vnt^ zb7IUy9fy>psLDM1nrGi5KDD^-r}`S(KWXgg*PZGf>z0qJMoUPiP`0sQy1lH$LrK7x z*6SN`rm&u3W5Nmz3JK|68T8GP8PGg8Pdbr@Nog_>RROx^3$*@hQGL|fjEaTok;y}oqYVxBs!iSr~y)Ao3Uf>C#+Xk z_tZb4?ZPCe0Z)m=$ei99I&nk&gE9yYZQJ4HGdW)NH@JUxU+zx)0i0u(5Xt#exx6yw zVwnTZmw7*b1`Ve1ZZ132zVqtVhgh3$ipQBlUQyf+1|0u2qJaD!Sm#W0%Qm33+j;2`<`)r0t9LG&Gr$Z_T9X;R!8_@cEP1 zocDJQE%iy$m6q7kzm(|W{UmK9U!|Q)=;>{3ZFTORZ+P>wz7PbT{o5-7QeJ!VQLBQd z)CJWRwKl)?>z#Yg;-MUhE>nn^aA(`zi9ZgN9*3FfpAOIyR5?ogrw$9JUrRIyUiX*< ztZYQ5w;2WaP=+gdO@3t1(3Bk4c(`fIa#@v(@Y;x7jQ!f9!hQRzN>;$Yu;?S1_v*{% zqPJO(cRgkQK_|~I&EKf0Mo~cPoncfF&X)4>Ha55;(Hz$M^XgQdT(#1W(Z7Es7`TKU z0&V4?s@<7F7gJ_l!hK-F$uWf(BAWp1Q)zMm<+bpo@4D2(xvvUyrZ=v}%!~iEj1`}^xz^J_nps- zLMhqutL0cu)$h1N-)#Yk`>d=neAH!UpAa`JTG@U`(HC$lD8M_p27_Lve9IjfJaEL@ zx8J0HJU+bJkG@We?rK&4w7G;-!c_kQn15? z=Dqnww$i5z!JZ_>yA!V^--}L|w|(Y+A{dOr@A7tfC4Bj9i>rX2glA5K^I1RT!;#?1 z@!a@Qg{j#Bs=PB6^{b=Cif@pW;z3redZOOkKMn(mWngyOgUUHGb!_D{?qgQZMe_rVC3I% z%^q4=T~v&(ZQt|zZq9f4cYjxg3SBcYWvgtJ70*YUJj5D3-e~hT%fKrDcPzKYgfoQ0 z)1Eg&?ik@PC;savVFBC#N5Aq3=y5vnX8`FNkRYTMnN~9L8L;l90^XiruUX%-pE%DD z>@vFo#}c1Cg_M+)v6p3nWw^p2vQsCY+(O)SmM z4VI{OE1NQ6Y_3TZbFBDNiaf_}Xr=emgntruiB9@Ep0zK;hCk}-`7OUID;Mb8w8^`S z`>wxe3=lphc5i8>NE=Kd9;ke;ucZr^#p>UuMr7PHxoHERD1|;(M1UAxm#zeSg-`-b zNc=>n+ku}BPP3t-q!)iACZ<*r(c~UeBJACW#;U7%OB%a7^3K z2J4`^uB++zTRPosx?JIo&hs}Y^V0! z^OaKCr!6yOCB3{BT0I)(eqYUI$#$EucZ$80!!nap)v#dGPj`9!6yycnATJ21X3JLj z<;m9*1GHta7Z(@4yuXn|q z{tmR++ihs_n`>(P(A^vN#-EOcx+uPZY7~A)mc7mkrW9Zw;ggbC+kTHZ9=r9b6h|?K z=2um@>L8i8E1LBTWiT`wH<=*l7W8YeI@oW}wl;=RI{q@MJCm_|0@K7U+TU4SWUt@a z_5bIElyAcB_khZmULv%h9W!3MNHVbiu4q%I9THpw7qt4LW;RDdX%NBhKd<%TkGdg0 zYHNEis5;fJpWK5Sv!J-xX3DSuCuanuHK*y3M(}ReXt>;Av1M+dxCj2Z%MxQ|hV}_m z)pI>7deyb@G|1}%4OSzK1M9-!Iu1xkKcp#Yf~)E|jPNgy(vWqGOdRM23S~|P4O^?c>Mq;J zC0@U0D%bh8nPsH zTl-%%m9B5E#}wxa*$yCS1gdt0I_3(?d6Ln<`R*wUJzuMWs=zzPQBJWH`+!7&bg#@uOxt==FPW7OJhsLkZk_2lJA)16K z;K!uppAY($f^mCgAIFPKLg#5^a~c~PxAG{>@WLeOc1sR%P+mB<9569jwlP{_6kh71 zpcl+$#Lvqltt%M)(YX2s-B^yqOzb^#P)=umS_}UIgX-k>1zxy=AcEjZbwBJ*>JUtV zgn>2rXB94MjT8qVeBmw|Hv+Qx5HV{>LiJ7NcCN^D8=&H}e|Wg0cj5~nVu^>PfC|Qx z^`0cDrslcOwYmQZ6;Wac~_bT zMxRH^>Ej7rA4$W|t4*Vjo?Xhgo{uSX>*Li^`}NnOU~d*TI$}!eDo3LUrkara{reYK z=@k_@|7Zqm@a?UwH+Wbyn^!Gy%$23qWQ#X<^mV5p@UM~`b;2#5?L1O^eWDIim0V`L zfH<=zy>u2ROYSyBvEaKz;sl3_9L$#sw}{W%bcm`0vSOQe-A@g+{(FAi6h3Jb5D8FG z+@?|q>R5)FQF59JvmWY^-Lc_xc0co=aRw@h(=8OCe1lzxky%pH3DvD&Af*5aZELB zb{~M{rCGeWmBMpxms5Xvl!uqWE{yXvHTS=Dj!R8y%V3W!jg3A!KXpI?5N4fvcTw94 zh6O?Mf!CT*gyML}9>?r!rH8{>QTn;@sDuJLMPSLpa|pl9OyTL{+jhMvlfLwxx8E2{ z>DWtoXKia`yjf!Kfz*>a_3X5FSLc&{JVE$?AVQySR2fL{>0lI+UaSk~XgI^Ebr)`mIrO*kkh} zy#!76XXA7Qy6O62#?{C*G(UN~Seal~T~S+Q;iXG;0|P}%OM0N&>hKYza^y3R=r9nv zE2caSD)qO2AKifStN@-^%k$s^?`bvEo}R{`m>SI3@By>Bi> zl0XpAit95!aLOv`XS6i>iV(ii;D)M}F-Hs=xC=Ox24JQQ@-SG*#YyNYS6=^N(aBFK zSRrp;X76UdsXi4p^6=m-Egf2_zyF~(Xc|9=wZK^ zXTQ75na&xC)<@bzQr>Tc0% z!uUzDkTc{!9NAa^Y9hokCoJl>#Pw^O2 zdudZxF|Fb5Fx&noi!aNS6SSwvo&QQvtBbYxZDO^@vWHV+KXHdwZ0+n($I6(uFLj(v zRPx`B+f1&wZus-aqsToIDSF%gRqEZU+^JvqyuIao5#im|E^mDJtu3)kDm_MI4@dMgT)Gy*)zBe3iTEWMbg`6m9**tw%7^?_S2>p;) z?k{68oC$hfJ_=dGWT3`w*Kai=5vX8xS_z}ajHoYa<&=ZqS*7x<@efOSIlw^iIOo)} z?RI!)nmmR0$=YmsioxF)Q^LV zZF3cBkjg$&R7d9K;?k7l#h7rIdcXT{@5K~K3v$G;lg8VY9xuy`{@>g2UVi&@;;{@- zLe2lB&Wma5p*xg#$4bf%cON*Ot3TMtWyxUB zM%}pF^vLdv41;vX_G8cH7Tf?W&Xmr5_vo+7#SDj;ovTgC00 z%Gz3E3~OYT&sAr%Z`=^qNK+fB$zWzn6xGRu{mD!tlvmNjjgEX+r*)& zsXoq+SWn_}F?wb%^64fV=Dx;07rG5_{3Y0acyLQGt_hQ=7`U4GSaQ83dDe+rBgpcI+AaT93#1ZVZ+(y2puUU%aA-fRNa3{8d-(S|;%( zRX`B~-(dHg!X4K{b;0lYte|uqTq4&OLpb7hdJsI!iN6{+k=+rWM3VCI^V26L>=B!% zQna!S43mehZf>f&y4`@pD0Ro5ZyhHC0dy%z718kZ;eZExu#JXYyj|KWj*$B6j+s0N z&n^hMq?+jawM&{`C~7(rS3eCgQ3Ew+B4x{`(;@x#sQKHi1FUQUPX}m{Y+hWIM->7; z`Z7Nk2?Z6J6k}e`CXpcnVP`>ySBxO6frsE=+ncl+TPkua?45Gb{JspMra;M4i?|(2 z+pUncl!DCO;2Yf<+gVv{kAq79`y@3hcA9YzWq9*|q0Fjwkd=D=Nfv~;z8}qPY7Op= zt+aqdpnRMJ07k-d$~=!(Oh%h54zqez89(3L$~;`u_IMt(A*1i5csA76uTvN+1bN|( z_|W>G_=+eOLu5CfXx1le0eBjSqp_FHy`?qkS!LC5|3*7|0WL=UaW@&x=XAqjX1MRw z%rJrvWz`?v`Q23{Dv^mc$DSMwM=t_=!tBin8n&d~xBfdwFR2_;6oUQ;i$hr9zPR=2u^Z z1Ovf36K_B&tbm0s@h81VtO7@Qc~l-fTTXpmWWMm=ubuZQwX?5nXX}UpJ9E^B#g+3$ zBDtg%M0`*KtodhoTT|l2hAb-onOTsM(X-o3{HChplmjGO62I6A>R*)i;4z>rce_Z^ zKT`ASxJV#ZIw z5Nk7o1WUD$+^wIcJulf%oS6vT$cEUU=m9sW-UvxN0ibVqCxG7zZs|eLE0oAl9TM^5 zAkOk2vYy|1hw}wzAcG&wW#yc(o%+lplcvQJfMtw|j^N_J0ASxc(U1jRB5pxvx3YK1 z+sjx^kI}7zeLcg&@a@c}GWd$)e5Zf$r|&M@1sa^=8K+-kEg06O0tZo5{t^-Vwy%<> zAvf~<#ajnfKUwN{m0w6Kk82y5ZI9)>covvV{OaOeQM2KpN$oA+dT&2qKDFInJ_;PB z5Q@)HV$>{TISquzUxa^J0GWJ<3{Y~|gYj0Y?`2tO#{k^ockgL2@SP*)S^aNwVWecZ z=8N;6??HwNK$}g_=r?N%glPL66ennEtRvw-Rlj~|sK33~b=)kh1tqp6n{W#HFn^>> z?&ceBO^`%l2F;|twNS{AL1bFsh5h|nG#Sbyj-r6bsVVwwbbpn`H8Ht{bQ&nat?#=4 z6}oIMb`24qawZWf${(w8dqdx(r2CgD#}FmAP>RgBabpY-}m{K9lrB_yj@&JV(S>W-a0ojJvf#}BWkY~ z7HM%`T}OfU76vOI*6Qlt@gMHxb*`eCL;F`Hbzj^WZVYEeA(ofkOA{~4xJvx~5|kzR z^&C=W!vmsVm+x}7^3tW(C^{kh^+${+`6kY7`~~G72fb$m1d!9Mfh1+X~s%>3hs%AKRoxTjDb@(|ybL*IQO@L@v6 z%9bNrDW)HXmp-b5 zU#iKFYwl&^B!q~%I2AUsd|$R#$k5><(N}AZbC(4y+KXo(zjQ@6k1PY-;aF=#K4NN$ z&(^H7g4wiOr#$bB0eBX7M)DdOIksowtTcjTv}b3hC`=;!6L@X%xYshvr(O(kImP$fMA-e4md+^5qy z#I1P>3kKEGj*aOF$w}TaeqYgt_#^SMk~Q86f870;LUd}OY`I=+ zvxSAp?2FjL;%U7W*fjJe3|Ev?GmrCNKz%2^ZRO275cNV1D+U=t=A|M)vO+42;F zRC&@Z1EDM$xsLHjZaW!;Jtm^Op#8)ZVm+_<*tyVpJYRZ?6+ zd>-PRBcld}B-`@TI2iV1`TG;gWj^BrfM-$B%7Rb8P@U5_jfES=i)RVIMTf1==M5Rp z@69-QR#q;7sWN6KHTJ2B{F0IokPxoq5DK5&sp;ze0fir}@d();1~e8HF@08gK+hzt zF8tVMj%P6G)HvT&lS=aj{LK*Ptv56@oP_9L8f;c5&kw9rvNE7-#1sNp+)G$lWD9m>?I^4kr=5Du5}CKD}6NH>3m7YJu#|d^kKhFu3ujM z$ZHO4{cviU&ZQtNsnzR#xO|wDk4`IW_fvXn4nuHbqfXPFZ!nHks#e*1B^@Hd)sIem z^R}~1JeDHDf_?|rn~z<{qMjmAh7HrP5<3_j|LwaIv%wn~K+`6IwISx<;GpSJ4aJ{2 z_^NqwxAJov^>^Z@emIPb$2TzO4fWEi{zJW_u76z%$7LtLwf+_!m+-H#Hm&{CXka%o z({`pR7S4LhZeWn%wM!U`!z_G>H`I7HBPI+W9gzS=(c2B;(fF`*2;MPIYynDdFZ;?`~;pH@&DACJ;(_wasy1Sg`WNo{C&iyvy-G!BpgirlQ-plc`|5kHJ8|-fJyREz4 z7{<09I(Gzs+Qs3bvb40clMB{|%zy_kk+W=hG@$iC7`InJeQ)F!JGY%T(`WsD)d`7Y z`ki6dHMgXH(#1RCaFe46;c$M>s~DexpySBSu5sv}iS75JMCJEyvo)6-+IBjeuRs6c zc8Vl-y3y-XEl^~!8BXR<&{RQpD9~G>ppHH2q zc?RgMAP0FJ1$?x(zh-(5XeLgh;h#j-X!}sN^0QYj)`kP$hPMNDD$pi0Mt?0p%+D*b zlRz?*h-R ziuCZEnWj~n%F2<_hMiSFl|LvG-vs&;V2JVBeI}Oy8JJkE-RzcH=^X+U(FYphUXNK`{JvGw8n5h&fIr7|E=N$V{*#(d@|O= z_Xby7Mcp6}zD+K}Nz(_eS@hH|4uYNTHdnzEhQC~MDLO`tFO zi|S4)J=m>p$OnYbv{2dr4djE?Zyn%EMd_wI&yE3564aMLk`CFQK)L7yOtOyudwxlL zv4oj%6Nb1N*k7bm;c3c|>as91LTD{m--+;XvX^ILNxr%!EM{iQ>pbk>`g6H2fP4SkSMbzb_I#^$$8WLiFDGTs1u+JO0CIAa;^ z*OJ{izspO{gZcn0Gi-_2?>|wtXyPjLcd7eoTF7teZcz1a`i6F>T?Kgbap{Vxa z9rs5vy7fQYpgZiy2Oe>=Zapc$a=yV0WdFE6yI~Tafw^QuVLK%5wAb#h*UoZ^qD+tQNf4NErr)gtcMkrCQ&eUnTh0>+s~$jWio+;kyM< zXPk&GAkfJJ4{#6V<3_8npHKUzu(>-c5EYv||BU2VX#N>S*$~cD(hB;R!lolt%n=gG z%0sQS(**kV^fX?U9bDi}Gt=#nTBH3_5O&__qRUz|A4?U6du{i$b~w6&yRHDV;s**KX3^*PVg z$bak+Y1<>YiC*B)xwp`qCIjKLXg_KwIRz)j1vm$uT+BL9!JSQ_<>TsZT#VLpic2WV zEf*G7-?<7G5SR3#?Vw!hRWrJ}hp0pa^3TUXM#l;1Ch#fCCX#SGeFF!Y8OkiG+pU zF2$C|d!MTgN`FyL3CLyQnP5hEab29`d&(%QHIuKEg`}zT{7ZOQr_06AioKlAncwG2 zj=R|W12;2oH-F&{6R3Se#v%tU2jCz@LDx;8L~PAx)Rfn~usLTqaW4jLJQ@Q*&{+S+ zlE!^KW|7UD&+i69%coFG2tDoA9Ohq#RhUg0#`S5G2EH*L{(^Jri4;yLy?70oGF>_uV9=P{r%;F$dlV4nHw}&56>c!4fuZ0vJ#g8()q6M zNxb&y8A2I^4QX3XOX$wU!Mr>Ozah)F+qqzKzFNFpxI|m9ESL>KtheFuPY%9x29;kd zb%BZK@wJelY+MOa;ls$JzCESyV#>&5>SsaWd|aG9zA z*^+dXxUe4PA_DQDBAN15Cv~aDMjO9&(Vq->Zbbt!$?%WmMh)trIeew{)U?*_;KE8N z#nJxo_6bazsmjy+r=P69)4eND%7HAA9aBi1WCZtP^-;Y{V z^_FSA5AUeOZu#c^rr_lSIhICR(kXjUQHD)xSvq+Ajq1`3<|KH?V!+u?%7598eIqEP zb*a*t`9Kr~y&DDsY8;fM%iG1;+js@K`rVSotE|WRR_w1KYL1?xn!FWzanUqP{lB~w z!*f8_B*uk-5zfAi6&jm+gByAd+;zAVy;o2ncqp9-}!$pWT-94+a%Bm}O3@FYQ~d zPnq@Hv49cd>wnQvvYzu&_+MLP+3|aLIGTP*`MNP3o@~oiSHNZ;eHJsxdD*lE>;0PI z0KW+%Q>HKE5Q@|OHtN5BVY4LrrJB-vZEisx79&Ne?%Dd~sK&ZSWcYN|&HA&-3_HLN zHUb3bwFy0kpSihf2B?FtLd1N01n1}HUp#v{XMgz%@t1;ey0tZtkV(t&a(@2{@gsGyg z+1A(So1wEkTMUyfn(aS&uy+b5{9|e-TcfPEyn3oEFsm&yy;8vi*r&)l-?`Ey z4@y2#4x<(m5W#z2HfKjWtUXV})2 zoZM-CxjD3m*;E5}Bov=ogBJDjy$u=HpkbLJOYxGZ|EiskZ)<;Q;&Ap_xtyjZtSdZV zbix0Vp8Yj7Ix)p%35Ibj1Qo&cueC~mw(Q6UfO6noL!(vZ!B+v!Keq6hWv2HIV~y?f zxA_ASf&mt|coHlr(}S_V=m@vy;|?f-lCqPu&lurOT=#Yc7-;8avJ)V74noK~8UP__q!dK(AfXESk?o+0QWe zJza(bkaVuZ{tC4nn;uYGb|i#hDx{6|c7}M9r%G`q(#0y6LMH@cKO27NC@HF&SIYF+ z=5Bd3dJIb49NH=*h)7CTwDuwtF7G{>Y_D*v7iI_-hx|1d=^z&WG5uQKb^Tl+RV0)+ z%R3>e=1oyj>#2n1c+1z3vuyY?lW=vb*eNkehPQO5WYD z0Rju(*}A_gj3?#ue_)PE6HH5WA_UAY0%#i^QJ+K{H(Bk`Y^%`F#OsvfeEzJ$%P66v zOYY8`P-Qb)C{gy1`uI!f!0_zuVz1t596bK)+E?GP4axTgF$r3v*lD-G z4o;tyIPm?_*Xrt)*^`kE0j5AGcy@M%F=KZU2rpUwjV?N~dG#wbLvvVoh^^Iw-q7ex zkBE*34{xo1!B-7%mB#@}Kza_t7&^HwGlT4ausxy z4<#kLAFPu)?@BJf`|>FgL;CgWqoMwjTZ-R(HPB2zvs)o{Sz;fuR@4a01y0FY4V-! zIP=A`Bky_sU9^fZe9X$b)(3_A&O$H71nHc9>Sflr56jSGh;32-OyZ+?S3Gw7)+=vU zg-JJn#QIpg#Gaxly2A2vKf3L`F z1mnPuWUKA8_jp&Qm7bJP#0gGp;T>)O3W#+Im1VR=D=-xi%**JrSxI zY4?xAKOafwGm!rsw5g+Rc?kZo@A&xh1L?Pk?VG2-kqhr16a!w#9I*Iu)e3RvrynFU zl>nAU6K|-ddH!ptR+`!b&>L|5ui-{xf2%5u)6@aRjPQt&vdUw@HUt)5+(v^$Y{`vWx09oengL#{_=D0}Bp9cy*t!>K> zN#Qv^b_Lj4?>M7{FSI904CM7@{ei}9(Fa@e`c=bFReg^Wm@Su6;)LcNdMdnIUpuW~ z7_bcWf5@0UMv`+TB}jsqsN24HCK8p#8=s<1ud20js5$Wrju%X=dU0T5vfo{6Wi9-k zGee3OBcZL=Ii$)0Z1eL#hsS0i0*$C(0F>m=4}I<`aJhD?U1DPtG|jS1eOWH^)m*u0 ziDY6grG_~In5tw3oR}==UcM}{pd9m#SXhx)L;!07%Z-5)eeZ1;IHNf&>DSAy7`+wW z1}%WKGzbt%1*gLBda{twOB#udR!Z+J<-6nP0Q2F@dBFQ-7fiZ+Ivu3DkS;vz-Z zij3@MPvvyUg3Q50-UTc?K7HvHEt&=VpY(X7&ab}YFxW2M(G5Q=9-?@7U^d?lS9 zT?0TdhyhELlTP9Lr%^H%zI30odqGgt&)b6wHpiMYH6Qb62^qn5oe8SYpihDsN&rCw zy!1oqBp853+5#Rg*??$|;>4@)SIPQM-nsD7+;4GX;ps>n;wW*)B(=V_uUM6p+J}0; z&NkHe-_9QY&}tBu`_xq`$@*k;*J1S=x`@zTj8A}#;M{!I;=>X8f-ejyqy)S0O%InM z=p`DKCez9%{qrb!=XGLURNMo!^P^mt29wfrYVSxXe0VUjWFTL=a)2~&Y-Xk(FjAqd z{?CELfrcE5Mi$S#(NBj$zPpU0Z1(kE<<#yR^`VX2%AuYENAmKW^Vl4%(;+*dqg98o z^43?Hn&=18?wBtLs!%!1A1;||0lwwgEYc5W`UUuFJAb!@&PK9s-UH88m&^G}$Nm-d zuk?8L6Gq~b2tSvW%Y%715E8ryVtElX=;y;TR%t@|(px~$%Z(nd*WiN-yC;8=u^h*qB9J*WB`XxQ_L$b z52Te>f(@nfb8&I07#apH{#yc9gTs9Sl7(i%Py+G(iaBCh_{JjkAHTi_e=TM6*DpKR z*%d1f`LPsh0ljK#%XqTHpy{}KSLpojA}E7Dd~C*V7gx1a$O?Ey*>tDQH&4;j@}x#c z70_zN3JGcr-B^qA*Jp}}FZR(h4ga@vgd>MZknI}%PY(cF>B^zCjFpRQs^E4BLo`(% zU}j#e2H?+CRvPaPWG4dyDRXEy=$$~Jl3-GZdcFeeV6I*voiFy}#95zJ+vsb{M3-+vw4L51-_8bxa2kX0hTg zrL}kb2Y)NA(uMG&**?Kiq-nMN-linGFfRoAr`n`g*~=F(VA0UJXo00bCv~ z7GSm*paZA@&x=YcrGlxMdc((N|InSIi={zUgh?8dR@YwrgFqG1T*xW1vNWgzOLH-5 zCoc~UvTz{rsNOlt3%W^d9Y+;8BjD<`nYCE(JchbEEPhi|4K)v@{1~H`^aWVPR#hbw zf#i61H-+DY4xN}ax1}X>Y|PnJcop*!d2)Fnr2~qvl^Xyqaj8V08KYI|4~mC?j6Zs{ zV`FizM1C^#$57iOS+BVI@ZH8mzq4631y`%Kt`=}KLcu^R)hMSYvyGL}#iC@5jN&rI zt#7`QiI8`U(O4I`8ls5N zzg6+XhMpAg3Lw5qNJvoA)9V2DPKt=105^B_m9NO1zo=3{Wi)lQXdR{g$eGfCV4~b8 z00#hv9*}^60Tw_b;3Wov(=C32$XHeQky0RlJ$Ekm3x(%LsXXfbN)3u163VJ%eIUsr zO!SkR;)?uvaWwT>iJX-;>#-aAdezUPa(z(K>SFZgJ?PO`amhiU{6MBkD4(1e)nPIm z(|vYOP_mngc$u1iPG||^@4nSmwoDlS!R?jD=&&`bCUVf$F}y(8GU?6M-Y5-Ybp`WrFFQ)FvzC zR$^rY;>M&e0o?TJRLOYbbNtj~RU)CXkc8vqkcpq`;c zrR&R()K*^1pzgxTs}b(3uKnYmQ?>~S+E|%rZ{GctsT7pibWcwYU(ujSdMmC8YC3Ad zde$%))YJDtm8HSCK}g@J!;U;)re5g$C}?k?f&Zsf2=oc9EM9mHV9J7p7@e7EFVZZQ zDL{Z571&nWd;G9|>)tpa4_WPAcBGcY<4OC&yO-3La(>ns*5fnc_H)>#cVnyq?L8=h zViuM+^uOSsz{TTWLWZJ*t2^I)+VP@9_x0tNie%~IuaSR{+bx$Y-1$!i-ute&7@4eB z2CR=0D&rq~JX|fNC?p9HGcXVaT2znkU?+u1C*g9qgRc0E(edsL;`G#$R+OeM>cwVKu!A6;G@Um2I^~Y3!R*xfuSN2A3i)!OiX<7j27&9Aqs4e^Q9^Fu_IlO zVvJD*txFy*y+I7*{;nu&l!1uzk>?Z_M*y4{#56F`7$1NX5gN!LIyD3RC=%?ywTVzaT4#gme_BRyK zi1G3H-NDyFn9Rw^na#%c&9|yI7vJ;0WEVL3_;M*_^nF93=P=n(*r8YGI&cLSS7GO^ zO-mIH5mo`dgY2v25_cu2J4a=dV2T~tWQEf?d~dEI(^VkSq84mN;QpZ!h1gMyUF+u{ z4QT_`mn5S8LSR&h7omCgfAPoO&B5Z?B0;4;e>M-J$QK}(b;{nbeYgBXmqnb$n2GM; zW||^}l{d?#%p$9k6b9e#&{hivQN4`<)s`pn{l9K|oJ3Qo2DQjml?a?mHiZr|-h$nK z45MM@veL4L$lV?~JXFgYvlVu}zwLNvo3A-2c@a(p6Wg~MMUYeBCH_YfABOtL^ zty3Si*to+#2I1lzh0&9O*{(89AdcE`q;8+Df9QYN{#1fN4jjEV^~zPhmz*1-QFgzN z+bk=maA%<+EGqXtXrFYW51*Wf0;d)|oGuG8u1(&*Dsw)HTCpsS>UM7<<1HQAw>LTM z4yf;F*QdOj9~9(uZ~S~dDInVS&rP=&@yZ#nl0&`dSz!;d1=+g-iVhBIf80t(D*(i% zLcG0T$})KHMnxA~dj&8Db&AF@QkAyM;k3)!`@QMPf?>qY-kwApkVEjDZVt1dY&;pY zqR3|pTWG+J?Ws(>8LIww0~HaC+f(8i-Qo&`J+X2}F0$x3@(la(Ay=($A&}?G1P^{a zNRmmh@z-7xOXj; zob@sWx+3K*Mj+Wn%&)|GRC9|6*$pr05Q>aCjw)fUzbC#sev#eGEnm=Y++XD$)R57ry?NcI< zM<8MekxWouXt81R|4QxF+g)4=r1ZTnD}s}elJZ}##e1zr^4mO->YjD0hd&g2|3I-bJa^TaxDCUrFFJ2sHEuyC;outas_Cvz65PBq+%itVsVJesRjQv-?Y~)c>{!TIKr6g@{Eg ziSW!7P4-zMB65*#&!C({>gD|rs080hInCoNwA#W{<2-z!aaAnH@%n~SdAT0I(1&B zw~^`=YP=?L`8M8XeifX>wAfnq9&9&ZGj^CL*eC zGH8D~xNfRINC#K5;hgT9f^xGJ3jIah+1BnaUM*-NxE4#(Lf*uysc;LjM#~B$=F*eC za$VaI?2eq)zEw4Zet@~LR7UB2%TxkFj4dmhJlHT+jRREL$0o)+2iXMGJdYPS>MT=o zu>z?m-}(&`kM9E>-C%l8!ZbRGw&>GF#Fu>7*BFJ4|F&4p&Tj6l+&6#W7(zjdbb}i$ zoaz!F7t=x-E^XB?)IEE8wNm1{OoOV0=Le1r;N256G&q2=3&Qw(Zq$*N<<@<4epCvc znNhW8M@_mzm!V+ZD}CllmoR0Md-mAV)=Pcv9f1~J1ncfDawk_J{@T)CPEI<1``Pe6(KTw_2_5@agHM7x*1NZlW8@%Vk_{YV+f9~*ILV#@8RBtkPlfx% zQ2>w^85!yKxOjDp*?S^r7xs_X7c%4w#tAu#W)+!Ea{lpb2R(T5(0u+IG?r*uRRVy) zMZ))~5*5Y}_-!(ne$=Mj9fPi-U=>s61ADaFJGWi_G*QG#8aaC5$DB=A$d7TgiP_=>lT4;w(A4x-IRJPdg@^S2xCcJ)*ZXk9%CgB*n^MZ&x)nJMxRH-078)$-rjpA%3HxB?hqj zmN;kMKs?)`kW4v~?^5~uWs9UT&FVXQO7u$F7DV@3`1G(V@)LqC#y8UuGr1s}ijAA2 z;zBRzNmi{RZ~p5&jpnTISo*3Bgd zlD_mD9@^Nrdfkz)>iCb`e^!u#z-3KHoAoinUTkapUq@E~4|gBN)#+xsPK{w=YH|+K zCpRXhySt{&IW;wHP9J7+Om}z9^rj}KnVEe5ULTy#onQQa`8?kzz8(tuE&#NK`j%Nr z1Z=pQFd+=oBVlM}Cf*rAn9Ghq+dHyibF(*@cOfIfSFJWzW7SH-Gm?OLZf35^MZRVM zu%%IcT$CIaOMW?0H&v`$qJ!DdfJK~65IKTe%hPfS$`!fN#+($szIQzu#r#z^Tz8-C z*cBqt`!0rhu(=`4U@(`Vw28fpU(FmiC;!kH{TUPSG86 z3hX3Ds*a1NcF`t@Ja6}P{+shGWO;Az;HN4@z^A?7U_&o&k;%20PiNWN(%V5R)qjT2 zgh5D{OincWHX>qdczEO%gS@Ya(wf>t+L3C-f+DJH5oG7$5IT!LWuQ{u6~m;hH6Xwa z_}O5r^mM&sEc{eer4$%wRGHHihB>xzRm&(oDO_wemY0|QO79;*q;-!wE6AkDRcNI} zuED{Os-Q-^?zJ*Uvhw*~aIy;X-LCuvgK6N;3|6V>+-LUM}EF(EL3m6?<~lhP9{+PA|cxJGuOy&CQ@DRZBz1^NWkFvsU@Eb0;UK7f({@bX$yY!=_L10Wh&sxB^ys z^V(0Fnh4C!Iz_`eWl)bQ`zU?pQ@g#A>D1qy*s1yI%J2{h5+=02)W%-An3&g~Ks+~C z<-YdSkT;m9E3ZBgsH1A#gvv2b^lRyZ4sxXD6#W%Bj1yo`PT%~mPB_y70v*A4S@aj( z3{)@w5|F609(PN$o*|Fu+$~KIznHYdb=vBWlpN}P-JY+VK#urA=WNuh0Y4JwX zLQ#-8!R>1ERpgUeBL0G3O|%_bK@voBW1XHR_ddQpJEo@SpUjn<79@^}cTMAK8R*ke zokQrfIxHmkpW{cpgFTH{<@3eAx-8bQ*1A**d^)@}8nJyUDwesg!2wY8q%nK4-d+5< z@AS$h+fL=+Kmk0l+5pNNI5jsXRy_B|4zc3Fyr1V=%5V}EhF)&kA)|H9H_~0erhgn4 zU~+U)oz`3bte8G`+rRzeU*l3Io>!axO{3)Z7}-p0Fi4CsT^5)FZoV}ROuz4laK8^x0b<2bW0Jma3@xudx@tT|a(;WT~OcCbPVkSjV1c09=(R2c#FmZNvjLu=-CITft@Cqq# znoK%(%=ie9f!TqxD_Gf)(jaACfR85aKx~i0>WNIs!n@UumSdA9&r>qbX#s#&3IVvb z#a{lKI8stk!2`lU2X2CZT#h}Ebh;@!-sje*17@@ja6baJoyO4^=Ze?@z!Dr(gxD&D`xa62Y z=x5UkfC(y`2aHOPY92Y1^Dg|pF z+uV>?p?(sBpf8ErXfCC@z?#SHP%(WKuvw5m*&FeO&2WRpvL2sA%HA*mGI;AdVt`C_ zYGEOX!V8Rb*!Gv{-Sv_$25Gf3kG@cS5j#^rdyXo~ZKz`z4JF){tsY%KpGGS&2Y;ci zTG>l^exuCNI8nJVpE$jWo5XFKS4Dl)cw;*CeJWn|ey@a!`4!j&?p(tN;6T4z#C*N# zaEfabS(5}erR4cX?Bh6;Dten-1OJwnFF=cNs?NFY(ZH;}7jyRy=R?$g&a}~ z;Ct>E#zxH&Hf?(r*D`?>R-b%IMKH#m!Xz^f|3#}+wUKSVJ!irNbAIKH8L#)_<3@%r z1)q}cE2mgMi}j{ZNprRmUOQep|9nMs`olS+5f?^mr#AeV<04Q;W&72(xgg4s1ZngT zlUo5%S7U;SF&6SzW*;S9utMbr1Bp}xiPY}aD-OSJwA<@2Uz7L`(?V%doVt}e2z$g! z#R#)OV2uufbbEWKrtO5Gkq~^y40@ax^2CPMupXlVhwh~NS;CsD<_%s@+Yh$_K?T++ z<5HdN;n0|6YiI=!mfHG0R$U@OU4jTVuc(e;0Qrs+D)IZ>sHq=T*%rS7J6-rd9B(Ez zVb7>9`T{!J2ry5?CVl9Z`;8^7EJiAg-QVR>ps6@_w3j!B|!`_}?$ro(ZCNv=7&Jz}R zmj-WUaU9Q=ugmg}eynq8Pm*x#hS~0@@+hdOuKF|S&MJ51r9gzKl!V{HyoAE8P_CV1 zBd=d%aV~q&?Y>{}G~(Ix{qq5vaAf#GBmLO8BbgeW8^cKy=4THg9D$um#XQfPHTj(K zGADL$kqkzRgyn>g_rc<=Q*;24pf)|Rbf+jW`~8Yvj}L1#GHOLp!;uDoHxm7Vn`Bs5 zYjMPT?Sl?PxyLowJR|tyn3J?$#h;?L^=wwl1y*#4th}!b3{-1$7(mketW-twhTIC4 z99l61jNE4CO7+QEqyj~~$0#?iE5pgn=RTTjps#dlY^IASFxHPpAZb~Yd91ZT#8XI& z$}t`{6=4rt021q;scMf{mS62eBgII15n1UiN|GMS3WlpkbI}T!qQrG^$EJ~#=dJVL zJM1L8_l5GfU|kMXNH=Z;C61b-oLos>WT6P;baJiX{jUmB2yP}F9G9qx0A1cOCtr8+ zY$CVQ0|p`Vsa?MT!xKNfNl>heHA72Ff%$fD?f6GyY4Uck;5>XnaV|wvLl~OA&b9Ne zM9XZ@L>c{?g*huwp^)|m@|S+$RJsr1lQh4C)>ja_diWG0@DU^&1eQ;Djv_5zQjwd` zT%~OmE;7~6AcYK4?lujk*JFd(y<=fHzSyALd^J3K0eKiHq*!a>jLG{6s*wxm9=YF{ zMog>ib2ur4^X>H6jK^c(E}__&n6Cy`aR93bKQBJ1o8JtT`2bxtV1e+;SEVOr6YN?7daNq~96ywo~5>JmV^(Q=h zEa`Pg`w|>L49ak+*X-mSBG( zs4m?k_{`9;>lB!~>S#9Wyu9B|rf=!aGi#5i*IxbmI?KjHb0_^WNOpfaykM)DwkR2| z=z~g;PPF+%vT_OeVA1rT)wEk}g1SVUIwz(W62kd62tVg{_lOm+N2DhHbm%il%|)CV z`{m%w{Rycw=6~Fn^E;kYW7A)2_}-tFil98snFf)Y#jVjHk-i(^N`tN50~6NBCcIDpK&I88 zlx;9ll@$qn_?@f@2L4Ef{sW?h6>2ARhp=>_v2=#ei##FO3YIdF)(SxCHdA7)KEMSY4tUNDg;fPhH&$)&DXwf~ z!X!J&Bs&J+`!zeplFt`Zp z?gARg;J@6Ij^Ln3&Iowon}M_-jTdHl9n?WTkUIy55K~R+tLB!exuuAohfmM{`dH>Q z;M@kaDWk~SYrRcY#+si>i6witzS)-CZ#r!iT+gDIDSv^3R~BlDR=D%~Hi39MvP~4- zP7|C-^Fl~az@t#$iLq>>ed6@sOI&rDVi8sgGsA@=KKhdnI)IrdudWrt`cWzuUzNf_ zwki;aThMCp6nHdMe=S2f9-<1pi>7t=7h(A#W=o=Vvthm&buUv2734@v$GR`Vby&`A zu%C~Td}g8`m{KilC?PO8;M;L>l(RMBX_hdYTF43dISc!FI9`4nv+8>+u&Javq>iv( zlKLf!O^eS`>Lkn|okL4y*UvU3zBM~4uc*Pd^?G7pIqP4BktFl0uijDVW3>K}=JTBK z>LX9wqfScXffMTpTmIWD?>CD!j&Z*hn5qF%mV z3tI|_q>+qG+d)4}j-~hmb9f@hbvF$fpo3r=+dL|Eid(zoT1KLl`pxVnojd)JdTp5o zy3|)+xpIx-VwyxsOUt^l%jgsePnNYqlcn*ioox-oO^G7@48g%?Tluxjz=7tq4lk;( zKhTf7cAs)U^;%e|F5$cyH+d? z>rJ3jiq>ONdaoyX9){^z1Dy_Cuz{)nf?9M8W{3f&T2K8MDhmhj*QNBrCCiDF@e7ue zq>_Bz?f& za?eAt9(jHiv~?lc()(x1^LabJte*JQ8CBkwW>I?DL2G{8hS!8<2n z>}t&x(D1L!TZ{;~mv@}kgAk@_Y)4KOL0}C$trHe8`;n!TpMvwPuKKbxRor6}&%kFCuQbz? zq(}HR(%gn%PyIeXB%f1_Tfsu`#pf5#D!DmPQHYiMY?2Nq)?_MEmXSb&^>H5 z&*haq-+IwP)F*VDj~DsCi}M&xp7GqhEg>etyfgY(IXW?OZ_n2`h*nb6Idt1Us((GB z!;X7vj=#S(B34_Zia1r|O#6*ANs=8ebus@T{RM{M?mG~^A9p;AX>T%|U}UFjX(gF$ z6|r{orA;0C+Q+3Yhta6o_nK4qU@0!_PKF)lDsksX=}G2stgDqtgR^Al*kKra6p);J zH(t-S9j>%7#x&>sR7H~m<<8fH4CoIxm*3W?#LcTI~pLR z&Jx|nTCK?*&IH70ab?`2pLkO8%uc`Zr6Q0>TVV0Q+Zup`A9c-nqLSX|!r1B%n?)E#S#m zg$w@mr^+_mo4xsDzmQ~YS1A~C#HZS-ug1XV{KUZPmtbjzQN-!6gTe;K%55kYi6#T z3}ce;9<6p4;A4|ba1%#Ed-UOfBfyAHgXOtEXjnVbxsUJacj~$I&94(?b6e?XQBHKx z=m;1txX;SqhQO1_$7M0Jf_`qDdgWR5e#VCT@{p~?g5cx4A}8W?lr^bEDg2=5{!<;o z+Lp1I=3`2wh`|UF#w6p9!5@RmlB#TWhWI+)cJK(;?P0gqKKcIlG94e1?7MB6X~0(4 zEGYD)6ULiLV8E_F)2}KN82I%H@ftKU#3o2#t0g>V0&X5R6Y898=-WTk73MUYUZS4P z=dNV1W<@!Yvuy|s&7Wz;2hG6n&xyY2Z?{vJbDsm)qUKK%de_Oyr zx1HX%A3mY^Q6Nc$=!rA-0PfGQKRcS=&%JIvK?LmuVgCzQO;_Y8O?PKmfaKBLb0 z-5%dBMCa3sN3=@-9{vY?*if2g*Lo0K@Y?tf%`T8(*2S7x50e!2HQScnYxCWyfsHz` zjz_TxhS6R^ySWV=qT$3N(Qu|Ig05~MKsp{OjF|L4Wy1x-fB7CDxRZdr7T_jpNG!Zw zl^_lGC!pTwj$Mh|9B3yKT2i)Yjd8)P*F@!Y5Swh10wR5Hqc50{!D%_R#ifPz`x*6m zQSDFIqsKWh|Nf|vM)$A!uYsKEW~&RecaE(y?HwQ5!@=t`yEg&U7xAK$sNVIRU5A0a zl^+SV`m*q5wlwoim6C^yze>B=_(i%yXy$VZ_`c@xZv}oqXlI-8u&9lgN z^~eM3+hW=zMK@}I3UtTs0<-TcLl6fF{dIvNR(^UWj$?}p{=M%>fg4LH3Rk6Y1T5=o3CmR><5gueikylCr%&{@CJe4OfwPqG_C zkF(!X=p#S!8Cq`j29Sm+*ECdK`t`gTXYjZxL!{NV+!y%=7L`2t) z&jGz3(8ur>>#h|Y(K>}SIy76-!*nEgE>}^Fq`>J-3Q=BbhJJ%ND|y=PK_15CF`QJV zuF_<98Ly^~EI%)@v&R#H%YB&|u)~W~>Z3fLY-4sMAOnh3eP_VHziRXi0vd=3Ei2P$ zK1UPhf>V;Ja&w`~45q^} z&@c>y2@`Um5}~L>8fBJDn$TG~o#7MTNmeTi!S{_s=gkaw_!3}Hx))v3(o-HYC&+`l9gjAD=Y*f6mxPAn zy9Zpb!EWUYGB-JUJdE|D%uk41r4Oqj*#pBu4_S`$l;WG%xggYY3 z|IB^kzK!@Oeo6Um|FQDX649E%DS`iFh}sjp!XnC=k)M&a+ut`XT0)}Y_}g&@%nwL} z{9%X9ho_i0S-x(1FNJ>V)&oY*bj(JWZkT#%h8p)ts^np(lEahLn^kC0y>mo0@2cB) zJ_?JFVz;fu+}RI(JI9~1Y+Rb;vwqb$((z+)X5gVe)7C_8LQDIFNcPovq4LeuwwCk{ z(zM&GJ_a=v57WkKyk|XO~0w4#KW`j@B^+fgnsD`qpwa=EKq7 zRJ@(xvbT6t_m`5&vbR`yGr#X|A!rbmHcR?!O_Kzpl@N}fH)##WV*uskgg4g?T%8#> zSQl-v5xhCNvYiXk-hO>$T}FAwMN%8q5wis0%M zb0fA$$1R7R(eK{u%mmEuQ(?ohvhbz$V<0@~i`vxRLS}Une%6t$&V-}>KAwcG;SEi* z9i)2iWBW_n7@HIrbZ|!Zl}UJP{2St%1H3#S34@?WLStCiSIxE2!gr(`C9DWzwldvTQVsvnFq&ZEa*?0P+#RmUV{_aOx@z^#a z&}^UX8Y!j66nOMFT9bI0hQ4ogjbbA_85*T4YJC`l##-F>PL!Sn#kIaoklAm_^U((W zNdjPeA5I;>s0g%ieG)AUnC_EbJe|7D|lV&~K`>X!lV3y>t6!I|~5{!Pq&{F|NNg4c3Zz3SogWxih zQ+XNmZ59SZ_oCa;4;JBF{cH&IwF9M^&$1Bm<$$=XspQJEPvn*&8U!D`xBLJ{{ z*r27>24vCNJonjmT7|PvG&%f_DFC%_1GJ_U+wv6Qu8W30quV z-~A;pFKBvYw(=ISJfuL!e*s7UIE8StON4q_9-h=#~yZ< z+-z1~WUX`nZpM)4h}~DEQRCqyKgyTKmhVxo@VEI}@JXbr>Ef>G{d$mEE#h3dAbonF z%v!a)kUWxx;D4g6*E?IP<|BNP>K5 z{gEeH$+#(DO&f8;&np#$!uN;|Lw_v*!3vOg!T`5$`wg|mYuTd#`l@RznHzP?QP%hA z{`dx378}jY;_Wx7A>rGC^NO5Z-f>@z$>Q;WRn}cYqq90kA`?ZCU=(cx^~Z4uu0)U5 zmMW_h*0NB!x$7=G?n^L^{SkOk-O7{6tHSI&?0?ULMjVqHJ}%`YBwg?n%jIg6Puyqa ztZ_F*QPK0F5M8g&X*uL4+2xk4Y_x4|V7vts7Zj95%_*wz_#5v|z4OKuy)1&QK`Nf4 zqlT%hv!n={RD@_b*n^1a-(E&$~MzcjaZnUebtK*Y|U`poq z!fW^C**J0CWgqfHv@A0Hj=QbruR8ypBnKXDetd}wYFoVs&XPe=!gQHwXgVJqb+_VoBPJ3&wj^Z9g6JTFiP> z{a_U%sjl0pHG%s^i7brhx0u$TiW~r} zpqY)VEFnM;<+t4Y}n6R}+Q#`s%o?mkESE*=yapS#4W0t1*k*4}#O)~n&qjTdb9uwj54?cCB;ZYX=c5pwL(-xHG@ z--*hVrms4eiq`z$MKS#eFsDx=HYs< zyL&4-V8gC%gsCs6b5oErWOWQM3!4v&GhX&H-p6&^xY56TTT5@ao4?*qS6xW;^LqDe zQhz$?w`(ieC%qU5G=>!Uiw3J4#DIb7eC8!255N7c|F+LM-83fV8%5(Kg>7Mg97sxE z&L4jur-?8<=pV0C)23MCU5^+`lCs;Rat)ne+Hc~}hUF1e)rdrWv{IWvB;_s6qCg^$ zs&amBV5-pY_>TT*m@19<^|~0VkC&{={jC1U422_L&OkorraB?UZxZ`+e*Uwsh89o$ zaKHYgO`h(Y;YQ8(1oNI)dbe$)uf@UQwHbYqwSFZO^tpp_`f`;@~FS0fUD8mtTkk$|S%HPW(` zr6EW1f?Lt|p-MO@%pY)i=!{O{;qBRH0!m;!BCcp&~FiHCBu>LGf5_ltuY`axVY@a_K$NGVqzFa;krE6a#mcCEDMu2KzK#nnvSX0I7RLunX&!6zZ{GvG zg?%{6qrQIrloCKPzMgnr-M0j3Ca%PK(^|hW*tyv@BV+XajWdh8~ zl#>XrQMDfokMINDGLpPg#RXe6a|E3eAQ>p|17ye_zz-eDcmRum-DUZNJ|H2UZN-4B zMF9XU=)`TAg)iio#Ryw~C+t!U;28-0zeAT;?^4!)vXtj@>y!3Vc;F(IO_To(=2h^= zO862=5B1ErX-{(R{PTI&y7e%XUo3px3AuKv+^GizS>TBn0>(Wmm=b;3`FS0$RsILJ z&eg7tU7J&e2GlKyO)j$ne(1 zynh6um2WF2(&94`Ws?0=bG&Wq@5j7lh%tM=AcMy9njr$n4u%>Tw&=isQ$iTf^GqCX z*-&P9VG>XZol#tH0N+TA2fMO%S)&d&YPrLqqRQS$>R3RDJ^LQ?tpEF-P0igWG~i1` L5vouLF@yaF`QC3= literal 0 HcmV?d00001 diff --git a/vendor/github.com/exoscale/egoscale/instance_groups.go b/vendor/github.com/exoscale/egoscale/instance_groups.go new file mode 100644 index 000000000..52bffba9a --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/instance_groups.go @@ -0,0 +1,71 @@ +package egoscale + +// InstanceGroup represents a group of VM +type InstanceGroup struct { + Account string `json:"account,omitempty" doc:"the account owning the instance group"` + Created string `json:"created,omitempty" doc:"time and date the instance group was created"` + ID *UUID `json:"id,omitempty" doc:"the id of the instance group"` + Name string `json:"name,omitempty" doc:"the name of the instance group"` +} + +// ListRequest builds the ListInstanceGroups request +func (ig InstanceGroup) ListRequest() (ListCommand, error) { + req := &ListInstanceGroups{ + ID: ig.ID, + Name: ig.Name, + } + + return req, nil +} + +// CreateInstanceGroup creates a VM group +type CreateInstanceGroup struct { + Name string `json:"name" doc:"the name of the instance group"` + _ bool `name:"createInstanceGroup" description:"Creates a vm group"` +} + +// Response returns the struct to unmarshal +func (CreateInstanceGroup) Response() interface{} { + return new(InstanceGroup) +} + +// UpdateInstanceGroup updates a VM group +type UpdateInstanceGroup struct { + ID *UUID `json:"id" doc:"Instance group ID"` + Name string `json:"name,omitempty" doc:"new instance group name"` + _ bool `name:"updateInstanceGroup" description:"Updates a vm group"` +} + +// Response returns the struct to unmarshal +func (UpdateInstanceGroup) Response() interface{} { + return new(InstanceGroup) +} + +// DeleteInstanceGroup deletes a VM group +type DeleteInstanceGroup struct { + ID *UUID `json:"id" doc:"the ID of the instance group"` + _ bool `name:"deleteInstanceGroup" description:"Deletes a vm group"` +} + +// Response returns the struct to unmarshal +func (DeleteInstanceGroup) Response() interface{} { + return new(BooleanResponse) +} + +//go:generate go run generate/main.go -interface=Listable ListInstanceGroups + +// ListInstanceGroups lists VM groups +type ListInstanceGroups struct { + ID *UUID `json:"id,omitempty" doc:"List instance groups by ID"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"List instance groups by name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + _ bool `name:"listInstanceGroups" description:"Lists vm groups"` +} + +// ListInstanceGroupsResponse represents a list of instance groups +type ListInstanceGroupsResponse struct { + Count int `json:"count"` + InstanceGroup []InstanceGroup `json:"instancegroup"` +} diff --git a/vendor/github.com/exoscale/egoscale/instancegroups_response.go b/vendor/github.com/exoscale/egoscale/instancegroups_response.go new file mode 100644 index 000000000..90fc1dbac --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/instancegroups_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListInstanceGroups) Response() interface{} { + return new(ListInstanceGroupsResponse) +} + +// ListRequest returns itself +func (ls *ListInstanceGroups) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListInstanceGroups) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListInstanceGroups) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListInstanceGroups) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListInstanceGroupsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListInstanceGroupsResponse was expected, got %T", resp)) + return + } + + for i := range items.InstanceGroup { + if !callback(&items.InstanceGroup[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/isos.go b/vendor/github.com/exoscale/egoscale/isos.go new file mode 100644 index 000000000..d9a0ace82 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/isos.go @@ -0,0 +1,94 @@ +package egoscale + +// ISO represents an attachable ISO disc +type ISO Template + +// ResourceType returns the type of the resource +func (ISO) ResourceType() string { + return "ISO" +} + +// ListRequest produces the ListIsos command. +func (iso ISO) ListRequest() (ListCommand, error) { + req := &ListISOs{ + ID: iso.ID, + Name: iso.Name, + ZoneID: iso.ZoneID, + } + if iso.Bootable { + *req.Bootable = true + } + if iso.IsFeatured { + req.IsoFilter = "featured" + } + if iso.IsPublic { + *req.IsPublic = true + } + if iso.IsReady { + *req.IsReady = true + } + + for i := range iso.Tags { + req.Tags = append(req.Tags, iso.Tags[i]) + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListISOs + +// ListISOs represents the list all available ISO files request +type ListISOs struct { + _ bool `name:"listIsos" description:"Lists all available ISO files."` + Bootable *bool `json:"bootable,omitempty" doc:"True if the ISO is bootable, false otherwise"` + ID *UUID `json:"id,omitempty" doc:"List ISO by id"` + IsoFilter string `json:"isofilter,omitempty" doc:"Possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". * featured : templates that have been marked as featured and public. * self : templates that have been registered or created by the calling user. * selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. * sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. * executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. * community : templates that have been marked as public but not featured. * all : all templates (only usable by admins)."` + IsPublic *bool `json:"ispublic,omitempty" doc:"True if the ISO is publicly available to all users, false otherwise."` + IsReady *bool `json:"isready,omitempty" doc:"True if this ISO is ready to be deployed"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"List all isos by name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ShowRemoved *bool `json:"showremoved,omitempty" doc:"Show removed ISOs as well"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"The ID of the zone"` +} + +// ListISOsResponse represents a list of ISO files +type ListISOsResponse struct { + Count int `json:"count"` + ISO []ISO `json:"iso"` +} + +// AttachISO represents the request to attach an ISO to a virtual machine. +type AttachISO struct { + _ bool `name:"attachIso" description:"Attaches an ISO to a virtual machine."` + ID *UUID `json:"id" doc:"the ID of the ISO file"` + VirtualMachineID *UUID `json:"virtualmachineid" doc:"the ID of the virtual machine"` +} + +// Response returns the struct to unmarshal +func (AttachISO) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (AttachISO) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// DetachISO represents the request to detach an ISO to a virtual machine. +type DetachISO struct { + _ bool `name:"detachIso" description:"Detaches any ISO file (if any) currently attached to a virtual machine."` + VirtualMachineID *UUID `json:"virtualmachineid" doc:"The ID of the virtual machine"` +} + +// Response returns the struct to unmarshal +func (DetachISO) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DetachISO) AsyncResponse() interface{} { + return new(VirtualMachine) +} diff --git a/vendor/github.com/exoscale/egoscale/isos_response.go b/vendor/github.com/exoscale/egoscale/isos_response.go new file mode 100644 index 000000000..2faa45a88 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/isos_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListISOs) Response() interface{} { + return new(ListISOsResponse) +} + +// ListRequest returns itself +func (ls *ListISOs) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListISOs) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListISOs) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListISOs) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListISOsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListISOsResponse was expected, got %T", resp)) + return + } + + for i := range items.ISO { + if !callback(&items.ISO[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/jobstatustype_string.go b/vendor/github.com/exoscale/egoscale/jobstatustype_string.go new file mode 100644 index 000000000..298561608 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/jobstatustype_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type JobStatusType"; DO NOT EDIT. + +package egoscale + +import "strconv" + +const _JobStatusType_name = "PendingSuccessFailure" + +var _JobStatusType_index = [...]uint8{0, 7, 14, 21} + +func (i JobStatusType) String() string { + if i < 0 || i >= JobStatusType(len(_JobStatusType_index)-1) { + return "JobStatusType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _JobStatusType_name[_JobStatusType_index[i]:_JobStatusType_index[i+1]] +} diff --git a/vendor/github.com/exoscale/egoscale/macaddress.go b/vendor/github.com/exoscale/egoscale/macaddress.go new file mode 100644 index 000000000..3c1dcaea4 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/macaddress.go @@ -0,0 +1,63 @@ +package egoscale + +import ( + "encoding/json" + "fmt" + "net" +) + +// MACAddress is a nicely JSON serializable net.HardwareAddr +type MACAddress net.HardwareAddr + +// String returns the MAC address in standard format +func (mac MACAddress) String() string { + return (net.HardwareAddr)(mac).String() +} + +// MAC48 builds a MAC-48 MACAddress +func MAC48(a, b, c, d, e, f byte) MACAddress { + m := make(MACAddress, 6) + m[0] = a + m[1] = b + m[2] = c + m[3] = d + m[4] = e + m[5] = f + return m +} + +// UnmarshalJSON unmarshals the raw JSON into the MAC address +func (mac *MACAddress) UnmarshalJSON(b []byte) error { + var addr string + if err := json.Unmarshal(b, &addr); err != nil { + return err + } + hw, err := ParseMAC(addr) + if err != nil { + return err + } + + *mac = make(MACAddress, 6) + copy(*mac, hw) + return nil +} + +// MarshalJSON converts the MAC Address to a string representation +func (mac MACAddress) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf("%q", mac.String())), nil +} + +// ParseMAC converts a string into a MACAddress +func ParseMAC(s string) (MACAddress, error) { + hw, err := net.ParseMAC(s) + return (MACAddress)(hw), err +} + +// MustParseMAC acts like ParseMAC but panics if in case of an error +func MustParseMAC(s string) MACAddress { + mac, err := ParseMAC(s) + if err != nil { + panic(err) + } + return mac +} diff --git a/vendor/github.com/exoscale/egoscale/network_offerings.go b/vendor/github.com/exoscale/egoscale/network_offerings.go new file mode 100644 index 000000000..989d5871f --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/network_offerings.go @@ -0,0 +1,91 @@ +package egoscale + +// NetworkOffering corresponds to the Compute Offerings +type NetworkOffering struct { + Availability string `json:"availability,omitempty" doc:"availability of the network offering"` + ConserveMode bool `json:"conservemode,omitempty" doc:"true if network offering is ip conserve mode enabled"` + Created string `json:"created,omitempty" doc:"the date this network offering was created"` + Details map[string]string `json:"details,omitempty" doc:"additional key/value details tied with network offering"` + DisplayText string `json:"displaytext,omitempty" doc:"an alternate display text of the network offering."` + EgressDefaultPolicy bool `json:"egressdefaultpolicy,omitempty" doc:"true if guest network default egress policy is allow; false if default egress policy is deny"` + GuestIPType string `json:"guestiptype,omitempty" doc:"guest type of the network offering, can be Shared or Isolated"` + ID *UUID `json:"id,omitempty" doc:"the id of the network offering"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if network offering is default, false otherwise"` + IsPersistent bool `json:"ispersistent,omitempty" doc:"true if network offering supports persistent networks, false otherwise"` + MaxConnections int `json:"maxconnections,omitempty" doc:"maximum number of concurrents connections to be handled by lb"` + Name string `json:"name,omitempty" doc:"the name of the network offering"` + NetworkRate int `json:"networkrate,omitempty" doc:"data transfer rate in megabits per second allowed."` + Service []Service `json:"service,omitempty" doc:"the list of supported services"` + ServiceOfferingID *UUID `json:"serviceofferingid,omitempty" doc:"the ID of the service offering used by virtual router provider"` + SpecifyIPRanges bool `json:"specifyipranges,omitempty" doc:"true if network offering supports specifying ip ranges, false otherwise"` + SpecifyVlan bool `json:"specifyvlan,omitempty" doc:"true if network offering supports vlans, false otherwise"` + State string `json:"state,omitempty" doc:"state of the network offering. Can be Disabled/Enabled/Inactive"` + SupportsStrechedL2Subnet bool `json:"supportsstrechedl2subnet,omitempty" doc:"true if network offering supports network that span multiple zones"` + Tags string `json:"tags,omitempty" doc:"the tags for the network offering"` + TrafficType string `json:"traffictype,omitempty" doc:"the traffic type for the network offering, supported types are Public, Management, Control, Guest, Vlan or Storage."` +} + +// ListRequest builds the ListNetworkOfferings request +// +// This doesn't take into account the IsDefault flag as the default value is true. +func (no NetworkOffering) ListRequest() (ListCommand, error) { + req := &ListNetworkOfferings{ + Availability: no.Availability, + ID: no.ID, + Name: no.Name, + State: no.State, + TrafficType: no.TrafficType, + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListNetworkOfferings + +// ListNetworkOfferings represents a query for network offerings +type ListNetworkOfferings struct { + Availability string `json:"availability,omitempty" doc:"the availability of network offering. Default value is Required"` + DisplayText string `json:"displaytext,omitempty" doc:"list network offerings by display text"` + GuestIPType string `json:"guestiptype,omitempty" doc:"list network offerings by guest type: Shared or Isolated"` + ID *UUID `json:"id,omitempty" doc:"list network offerings by id"` + IsDefault *bool `json:"isdefault,omitempty" doc:"true if need to list only default network offerings. Default value is false"` + IsTagged *bool `json:"istagged,omitempty" doc:"true if offering has tags specified"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"list network offerings by name"` + NetworkID *UUID `json:"networkid,omitempty" doc:"the ID of the network. Pass this in if you want to see the available network offering that a network can be changed to."` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + SourceNATSupported *bool `json:"sourcenatsupported,omitempty" doc:"true if need to list only netwok offerings where source nat is supported, false otherwise"` + SpecifyIPRanges *bool `json:"specifyipranges,omitempty" doc:"true if need to list only network offerings which support specifying ip ranges"` + SpecifyVlan *bool `json:"specifyvlan,omitempty" doc:"the tags for the network offering."` + State string `json:"state,omitempty" doc:"list network offerings by state"` + SupportedServices []Service `json:"supportedservices,omitempty" doc:"list network offerings supporting certain services"` + Tags string `json:"tags,omitempty" doc:"list network offerings by tags"` + TrafficType string `json:"traffictype,omitempty" doc:"list by traffic type"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"list network offerings available for network creation in specific zone"` + _ bool `name:"listNetworkOfferings" description:"Lists all available network offerings."` +} + +// ListNetworkOfferingsResponse represents a list of service offerings +type ListNetworkOfferingsResponse struct { + Count int `json:"count"` + NetworkOffering []NetworkOffering `json:"networkoffering"` +} + +// UpdateNetworkOffering represents a modification of a network offering +type UpdateNetworkOffering struct { + Availability string `json:"availability,omitempty" doc:"the availability of network offering. Default value is Required for Guest Virtual network offering; Optional for Guest Direct network offering"` + DisplayText string `json:"displaytext,omitempty" doc:"the display text of the network offering"` + ID *UUID `json:"id,omitempty" doc:"the id of the network offering"` + KeepAliveEnabled *bool `json:"keepaliveenabled,omitempty" doc:"if true keepalive will be turned on in the loadbalancer. At the time of writing this has only an effect on haproxy; the mode http and httpclose options are unset in the haproxy conf file."` + MaxConnections int `json:"maxconnections,omitempty" doc:"maximum number of concurrent connections supported by the network offering"` + Name string `json:"name,omitempty" doc:"the name of the network offering"` + SortKey int `json:"sortkey,omitempty" doc:"sort key of the network offering, integer"` + State string `json:"state,omitempty" doc:"update state for the network offering"` + _ bool `name:"updateNetworkOffering" description:"Updates a network offering."` +} + +// Response returns the struct to unmarshal +func (UpdateNetworkOffering) Response() interface{} { + return new(NetworkOffering) +} diff --git a/vendor/github.com/exoscale/egoscale/networkofferings_response.go b/vendor/github.com/exoscale/egoscale/networkofferings_response.go new file mode 100644 index 000000000..656de7253 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/networkofferings_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListNetworkOfferings) Response() interface{} { + return new(ListNetworkOfferingsResponse) +} + +// ListRequest returns itself +func (ls *ListNetworkOfferings) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListNetworkOfferings) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListNetworkOfferings) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListNetworkOfferings) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListNetworkOfferingsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListNetworkOfferingsResponse was expected, got %T", resp)) + return + } + + for i := range items.NetworkOffering { + if !callback(&items.NetworkOffering[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/networks.go b/vendor/github.com/exoscale/egoscale/networks.go new file mode 100644 index 000000000..4d6ce12e3 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/networks.go @@ -0,0 +1,229 @@ +package egoscale + +import ( + "net" + "net/url" +) + +// Network represents a network +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/networking_and_traffic.html +type Network struct { + Account string `json:"account,omitempty" doc:"the owner of the network"` + AccountID *UUID `json:"accountid,omitempty" doc:"the owner ID of the network"` + BroadcastDomainType string `json:"broadcastdomaintype,omitempty" doc:"Broadcast domain type of the network"` + BroadcastURI string `json:"broadcasturi,omitempty" doc:"broadcast uri of the network."` + CanUseForDeploy bool `json:"canusefordeploy,omitempty" doc:"list networks available for vm deployment"` + CIDR *CIDR `json:"cidr,omitempty" doc:"Cloudstack managed address space, all CloudStack managed VMs get IP address from CIDR"` + DisplayText string `json:"displaytext,omitempty" doc:"the displaytext of the network"` + DNS1 net.IP `json:"dns1,omitempty" doc:"the first DNS for the network"` + DNS2 net.IP `json:"dns2,omitempty" doc:"the second DNS for the network"` + EndIP net.IP `json:"endip,omitempty" doc:"the ending IP address in the network IP range. Required for managed networks."` + Gateway net.IP `json:"gateway,omitempty" doc:"the network's gateway"` + ID *UUID `json:"id,omitempty" doc:"the id of the network"` + IP6CIDR *CIDR `json:"ip6cidr,omitempty" doc:"the cidr of IPv6 network"` + IP6Gateway net.IP `json:"ip6gateway,omitempty" doc:"the gateway of IPv6 network"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if network is default, false otherwise"` + IsPersistent bool `json:"ispersistent,omitempty" doc:"list networks that are persistent"` + IsSystem bool `json:"issystem,omitempty" doc:"true if network is system, false otherwise"` + Name string `json:"name,omitempty" doc:"the name of the network"` + Netmask net.IP `json:"netmask,omitempty" doc:"the network's netmask"` + NetworkCIDR *CIDR `json:"networkcidr,omitempty" doc:"the network CIDR of the guest network configured with IP reservation. It is the summation of CIDR and RESERVED_IP_RANGE"` + NetworkDomain string `json:"networkdomain,omitempty" doc:"the network domain"` + NetworkOfferingAvailability string `json:"networkofferingavailability,omitempty" doc:"availability of the network offering the network is created from"` + NetworkOfferingConserveMode bool `json:"networkofferingconservemode,omitempty" doc:"true if network offering is ip conserve mode enabled"` + NetworkOfferingDisplayText string `json:"networkofferingdisplaytext,omitempty" doc:"display text of the network offering the network is created from"` + NetworkOfferingID *UUID `json:"networkofferingid,omitempty" doc:"network offering id the network is created from"` + NetworkOfferingName string `json:"networkofferingname,omitempty" doc:"name of the network offering the network is created from"` + PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"the physical network id"` + Related string `json:"related,omitempty" doc:"related to what other network configuration"` + ReservedIPRange string `json:"reservediprange,omitempty" doc:"the network's IP range not to be used by CloudStack guest VMs and can be used for non CloudStack purposes"` + RestartRequired bool `json:"restartrequired,omitempty" doc:"true network requires restart"` + Service []Service `json:"service,omitempty" doc:"the list of services"` + SpecifyIPRanges bool `json:"specifyipranges,omitempty" doc:"true if network supports specifying ip ranges, false otherwise"` + StartIP net.IP `json:"startip,omitempty" doc:"the beginning IP address in the network IP range. Required for managed networks."` + State string `json:"state,omitempty" doc:"state of the network"` + StrechedL2Subnet bool `json:"strechedl2subnet,omitempty" doc:"true if network can span multiple zones"` + SubdomainAccess bool `json:"subdomainaccess,omitempty" doc:"true if users from subdomains can access the domain level network"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with network"` + TrafficType string `json:"traffictype,omitempty" doc:"the traffic type of the network"` + Type string `json:"type,omitempty" doc:"the type of the network"` + Vlan string `json:"vlan,omitemtpy" doc:"The vlan of the network. This parameter is visible to ROOT admins only"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"zone id of the network"` + ZoneName string `json:"zonename,omitempty" doc:"the name of the zone the network belongs to"` + ZonesNetworkSpans []Zone `json:"zonesnetworkspans,omitempty" doc:"If a network is enabled for 'streched l2 subnet' then represents zones on which network currently spans"` +} + +// ListRequest builds the ListNetworks request +func (network Network) ListRequest() (ListCommand, error) { + //TODO add tags support + req := &ListNetworks{ + ID: network.ID, + Keyword: network.Name, // this is a hack as listNetworks doesn't support to search by name. + PhysicalNetworkID: network.PhysicalNetworkID, + TrafficType: network.TrafficType, + Type: network.Type, + ZoneID: network.ZoneID, + } + + if network.CanUseForDeploy { + req.CanUseForDeploy = &network.CanUseForDeploy + } + if network.RestartRequired { + req.RestartRequired = &network.RestartRequired + } + + return req, nil +} + +// ResourceType returns the type of the resource +func (Network) ResourceType() string { + return "Network" +} + +// Service is a feature of a network +type Service struct { + Capability []ServiceCapability `json:"capability,omitempty"` + Name string `json:"name"` + Provider []ServiceProvider `json:"provider,omitempty"` +} + +// ServiceCapability represents optional capability of a service +type ServiceCapability struct { + CanChooseServiceCapability bool `json:"canchooseservicecapability"` + Name string `json:"name"` + Value string `json:"value"` +} + +// ServiceProvider represents the provider of the service +type ServiceProvider struct { + CanEnableIndividualService bool `json:"canenableindividualservice"` + DestinationPhysicalNetworkID *UUID `json:"destinationphysicalnetworkid"` + ID *UUID `json:"id"` + Name string `json:"name"` + PhysicalNetworkID *UUID `json:"physicalnetworkid"` + ServiceList []string `json:"servicelist,omitempty"` +} + +// CreateNetwork creates a network +type CreateNetwork struct { + DisplayText string `json:"displaytext,omitempty" doc:"the display text of the network"` // This field is required but might be empty + EndIP net.IP `json:"endip,omitempty" doc:"the ending IP address in the network IP range. Required for managed networks."` + EndIpv6 net.IP `json:"endipv6,omitempty" doc:"the ending IPv6 address in the IPv6 network range"` + Gateway net.IP `json:"gateway,omitempty" doc:"the gateway of the network. Required for Shared networks and Isolated networks when it belongs to VPC"` + IP6CIDR *CIDR `json:"ip6cidr,omitempty" doc:"the CIDR of IPv6 network, must be at least /64"` + IP6Gateway net.IP `json:"ip6gateway,omitempty" doc:"the gateway of the IPv6 network. Required for Shared networks and Isolated networks when it belongs to VPC"` + IsolatedPVlan string `json:"isolatedpvlan,omitempty" doc:"the isolated private vlan for this network"` + Name string `json:"name,omitempty" doc:"the name of the network"` // This field is required but might be empty + Netmask net.IP `json:"netmask,omitempty" doc:"the netmask of the network. Required for managed networks."` + NetworkDomain string `json:"networkdomain,omitempty" doc:"network domain"` + NetworkOfferingID *UUID `json:"networkofferingid" doc:"the network offering id"` + PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"the Physical Network ID the network belongs to"` + StartIP net.IP `json:"startip,omitempty" doc:"the beginning IP address in the network IP range. Required for managed networks."` + StartIpv6 net.IP `json:"startipv6,omitempty" doc:"the beginning IPv6 address in the IPv6 network range"` + Vlan string `json:"vlan,omitempty" doc:"the ID or VID of the network"` + ZoneID *UUID `json:"zoneid" doc:"the Zone ID for the network"` + _ bool `name:"createNetwork" description:"Creates a network"` +} + +// Response returns the struct to unmarshal +func (CreateNetwork) Response() interface{} { + return new(Network) +} + +func (req CreateNetwork) onBeforeSend(params url.Values) error { + // Those fields are required but might be empty + if req.Name == "" { + params.Set("name", "") + } + if req.DisplayText == "" { + params.Set("displaytext", "") + } + return nil +} + +// UpdateNetwork (Async) updates a network +type UpdateNetwork struct { + _ bool `name:"updateNetwork" description:"Updates a network"` + ChangeCIDR *bool `json:"changecidr,omitempty" doc:"Force update even if cidr type is different"` + DisplayText string `json:"displaytext,omitempty" doc:"the new display text for the network"` + EndIP net.IP `json:"endip,omitempty" doc:"the ending IP address in the network IP range. Required for managed networks."` + GuestVMCIDR *CIDR `json:"guestvmcidr,omitempty" doc:"CIDR for Guest VMs,Cloudstack allocates IPs to Guest VMs only from this CIDR"` + ID *UUID `json:"id" doc:"the ID of the network"` + Name string `json:"name,omitempty" doc:"the new name for the network"` + Netmask net.IP `json:"netmask,omitempty" doc:"the netmask of the network. Required for managed networks."` + NetworkDomain string `json:"networkdomain,omitempty" doc:"network domain"` + NetworkOfferingID *UUID `json:"networkofferingid,omitempty" doc:"network offering ID"` + StartIP net.IP `json:"startip,omitempty" doc:"the beginning IP address in the network IP range. Required for managed networks."` +} + +// Response returns the struct to unmarshal +func (UpdateNetwork) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (UpdateNetwork) AsyncResponse() interface{} { + return new(Network) +} + +// RestartNetwork (Async) updates a network +type RestartNetwork struct { + ID *UUID `json:"id" doc:"The id of the network to restart."` + Cleanup *bool `json:"cleanup,omitempty" doc:"If cleanup old network elements"` + _ bool `name:"restartNetwork" description:"Restarts the network; includes 1) restarting network elements - virtual routers, dhcp servers 2) reapplying all public ips 3) reapplying loadBalancing/portForwarding rules"` +} + +// Response returns the struct to unmarshal +func (RestartNetwork) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RestartNetwork) AsyncResponse() interface{} { + return new(Network) +} + +// DeleteNetwork deletes a network +type DeleteNetwork struct { + ID *UUID `json:"id" doc:"the ID of the network"` + Forced *bool `json:"forced,omitempty" doc:"Force delete a network. Network will be marked as 'Destroy' even when commands to shutdown and cleanup to the backend fails."` + _ bool `name:"deleteNetwork" description:"Deletes a network"` +} + +// Response returns the struct to unmarshal +func (DeleteNetwork) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DeleteNetwork) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +//go:generate go run generate/main.go -interface=Listable ListNetworks + +// ListNetworks represents a query to a network +type ListNetworks struct { + CanUseForDeploy *bool `json:"canusefordeploy,omitempty" doc:"List networks available for vm deployment"` + ID *UUID `json:"id,omitempty" doc:"List networks by id"` + IsSystem *bool `json:"issystem,omitempty" doc:"true If network is system, false otherwise"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + PhysicalNetworkID *UUID `json:"physicalnetworkid,omitempty" doc:"List networks by physical network id"` + RestartRequired *bool `json:"restartrequired,omitempty" doc:"List networks by restartRequired"` + SpecifyIPRanges *bool `json:"specifyipranges,omitempty" doc:"True if need to list only networks which support specifying ip ranges"` + SupportedServices []Service `json:"supportedservices,omitempty" doc:"List networks supporting certain services"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + TrafficType string `json:"traffictype,omitempty" doc:"Type of the traffic"` + Type string `json:"type,omitempty" doc:"The type of the network. Supported values are: Isolated and Shared"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"The Zone ID of the network"` + _ bool `name:"listNetworks" description:"Lists all available networks."` +} + +// ListNetworksResponse represents the list of networks +type ListNetworksResponse struct { + Count int `json:"count"` + Network []Network `json:"network"` +} diff --git a/vendor/github.com/exoscale/egoscale/networks_response.go b/vendor/github.com/exoscale/egoscale/networks_response.go new file mode 100644 index 000000000..058890624 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/networks_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListNetworks) Response() interface{} { + return new(ListNetworksResponse) +} + +// ListRequest returns itself +func (ls *ListNetworks) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListNetworks) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListNetworks) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListNetworks) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListNetworksResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListNetworksResponse was expected, got %T", resp)) + return + } + + for i := range items.Network { + if !callback(&items.Network[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/nics.go b/vendor/github.com/exoscale/egoscale/nics.go new file mode 100644 index 000000000..10863113f --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/nics.go @@ -0,0 +1,120 @@ +package egoscale + +import ( + "net" +) + +// Nic represents a Network Interface Controller (NIC) +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/networking_and_traffic.html#configuring-multiple-ip-addresses-on-a-single-nic +type Nic struct { + BroadcastURI string `json:"broadcasturi,omitempty" doc:"the broadcast uri of the nic"` + DeviceID *UUID `json:"deviceid,omitempty" doc:"device id for the network when plugged into the virtual machine"` + Gateway net.IP `json:"gateway,omitempty" doc:"the gateway of the nic"` + ID *UUID `json:"id,omitempty" doc:"the ID of the nic"` + IP6Address net.IP `json:"ip6address,omitempty" doc:"the IPv6 address of network"` + IP6CIDR *CIDR `json:"ip6cidr,omitempty" doc:"the cidr of IPv6 network"` + IP6Gateway net.IP `json:"ip6gateway,omitempty" doc:"the gateway of IPv6 network"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"the ip address of the nic"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if nic is default, false otherwise"` + IsolationURI string `json:"isolationuri,omitempty" doc:"the isolation uri of the nic"` + MACAddress MACAddress `json:"macaddress,omitempty" doc:"true if nic is default, false otherwise"` + Netmask net.IP `json:"netmask,omitempty" doc:"the netmask of the nic"` + NetworkID *UUID `json:"networkid,omitempty" doc:"the ID of the corresponding network"` + NetworkName string `json:"networkname,omitempty" doc:"the name of the corresponding network"` + ReverseDNS []ReverseDNS `json:"reversedns,omitempty" doc:"the list of PTR record(s) associated with the virtual machine"` + SecondaryIP []NicSecondaryIP `json:"secondaryip,omitempty" doc:"the Secondary ipv4 addr of nic"` + TrafficType string `json:"traffictype,omitempty" doc:"the traffic type of the nic"` + Type string `json:"type,omitempty" doc:"the type of the nic"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"Id of the vm to which the nic belongs"` +} + +// ListRequest build a ListNics request from the given Nic +func (nic Nic) ListRequest() (ListCommand, error) { + req := &ListNics{ + VirtualMachineID: nic.VirtualMachineID, + NicID: nic.ID, + NetworkID: nic.NetworkID, + } + + return req, nil +} + +// NicSecondaryIP represents a link between NicID and IPAddress +type NicSecondaryIP struct { + ID *UUID `json:"id,omitempty" doc:"the ID of the secondary private IP addr"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"Secondary IP address"` + NetworkID *UUID `json:"networkid,omitempty" doc:"the ID of the network"` + NicID *UUID `json:"nicid,omitempty" doc:"the ID of the nic"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"the ID of the vm"` +} + +//go:generate go run generate/main.go -interface=Listable ListNics + +// ListNics represents the NIC search +type ListNics struct { + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + NetworkID *UUID `json:"networkid,omitempty" doc:"list nic of the specific vm's network"` + NicID *UUID `json:"nicid,omitempty" doc:"the ID of the nic to to list IPs"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"the ID of the vm"` + _ bool `name:"listNics" description:"list the vm nics IP to NIC"` +} + +// ListNicsResponse represents a list of templates +type ListNicsResponse struct { + Count int `json:"count"` + Nic []Nic `json:"nic"` +} + +// AddIPToNic (Async) represents the assignation of a secondary IP +type AddIPToNic struct { + NicID *UUID `json:"nicid" doc:"the ID of the nic to which you want to assign private IP"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"Secondary IP Address"` + _ bool `name:"addIpToNic" description:"Assigns secondary IP to NIC"` +} + +// Response returns the struct to unmarshal +func (AddIPToNic) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (AddIPToNic) AsyncResponse() interface{} { + return new(NicSecondaryIP) +} + +// RemoveIPFromNic (Async) represents a deletion request +type RemoveIPFromNic struct { + ID *UUID `json:"id" doc:"the ID of the secondary ip address to nic"` + _ bool `name:"removeIpFromNic" description:"Removes secondary IP from the NIC."` +} + +// Response returns the struct to unmarshal +func (RemoveIPFromNic) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RemoveIPFromNic) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +// ActivateIP6 (Async) activates the IP6 on the given NIC +// +// Exoscale specific API: https://community.exoscale.ch/api/compute/#activateip6_GET +type ActivateIP6 struct { + NicID *UUID `json:"nicid" doc:"the ID of the nic to which you want to assign the IPv6"` + _ bool `name:"activateIp6" description:"Activate the IPv6 on the VM's nic"` +} + +// Response returns the struct to unmarshal +func (ActivateIP6) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (ActivateIP6) AsyncResponse() interface{} { + return new(Nic) +} diff --git a/vendor/github.com/exoscale/egoscale/nics_response.go b/vendor/github.com/exoscale/egoscale/nics_response.go new file mode 100644 index 000000000..dcf960915 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/nics_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListNics) Response() interface{} { + return new(ListNicsResponse) +} + +// ListRequest returns itself +func (ls *ListNics) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListNics) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListNics) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListNics) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListNicsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListNicsResponse was expected, got %T", resp)) + return + } + + for i := range items.Nic { + if !callback(&items.Nic[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/oscategories_response.go b/vendor/github.com/exoscale/egoscale/oscategories_response.go new file mode 100644 index 000000000..985f875df --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/oscategories_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListOSCategories) Response() interface{} { + return new(ListOSCategoriesResponse) +} + +// ListRequest returns itself +func (ls *ListOSCategories) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListOSCategories) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListOSCategories) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListOSCategories) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListOSCategoriesResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListOSCategoriesResponse was expected, got %T", resp)) + return + } + + for i := range items.OSCategory { + if !callback(&items.OSCategory[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/publicipaddresses_response.go b/vendor/github.com/exoscale/egoscale/publicipaddresses_response.go new file mode 100644 index 000000000..2ee92bd7a --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/publicipaddresses_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListPublicIPAddresses) Response() interface{} { + return new(ListPublicIPAddressesResponse) +} + +// ListRequest returns itself +func (ls *ListPublicIPAddresses) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListPublicIPAddresses) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListPublicIPAddresses) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListPublicIPAddresses) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListPublicIPAddressesResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListPublicIPAddressesResponse was expected, got %T", resp)) + return + } + + for i := range items.PublicIPAddress { + if !callback(&items.PublicIPAddress[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/record_string.go b/vendor/github.com/exoscale/egoscale/record_string.go new file mode 100644 index 000000000..b84303bb7 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/record_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type=Record"; DO NOT EDIT. + +package egoscale + +import "strconv" + +const _Record_name = "AAAAAALIASCNAMEHINFOMXNAPTRNSPOOLSPFSRVSSHFPTXTURL" + +var _Record_index = [...]uint8{0, 1, 5, 10, 15, 20, 22, 27, 29, 33, 36, 39, 44, 47, 50} + +func (i Record) String() string { + if i < 0 || i >= Record(len(_Record_index)-1) { + return "Record(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Record_name[_Record_index[i]:_Record_index[i+1]] +} diff --git a/vendor/github.com/exoscale/egoscale/request.go b/vendor/github.com/exoscale/egoscale/request.go new file mode 100644 index 000000000..079c626c0 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/request.go @@ -0,0 +1,405 @@ +package egoscale + +import ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" +) + +// Error formats a CloudStack error into a standard error +func (e ErrorResponse) Error() string { + return fmt.Sprintf("API error %s %d (%s %d): %s", e.ErrorCode, e.ErrorCode, e.CSErrorCode, e.CSErrorCode, e.ErrorText) +} + +// Error formats a CloudStack job response into a standard error +func (e BooleanResponse) Error() error { + if !e.Success { + return fmt.Errorf("API error: %s", e.DisplayText) + } + + return nil +} + +func responseKey(key string) (string, bool) { + // XXX: addIpToNic, activateIp6, restorevmresponse are kind of special + var responseKeys = map[string]string{ + "addiptonicresponse": "addiptovmnicresponse", + "activateip6response": "activateip6nicresponse", + "restorevirtualmachineresponse": "restorevmresponse", + "updatevmaffinitygroupresponse": "updatevirtualmachineresponse", + } + + k, ok := responseKeys[key] + return k, ok +} + +func (client *Client) parseResponse(resp *http.Response, apiName string) (json.RawMessage, error) { + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + m := map[string]json.RawMessage{} + if err := json.Unmarshal(b, &m); err != nil { + return nil, err + } + + key := fmt.Sprintf("%sresponse", strings.ToLower(apiName)) + response, ok := m[key] + if !ok { + if resp.StatusCode >= 400 { + response, ok = m["errorresponse"] + } + + if !ok { + // try again with the special keys + value, ok := responseKey(key) + if ok { + key = value + } + + response, ok = m[key] + + if !ok { + return nil, fmt.Errorf("malformed JSON response %d, %q was expected.\n%s", resp.StatusCode, key, b) + } + } + } + + if resp.StatusCode >= 400 { + errorResponse := new(ErrorResponse) + if e := json.Unmarshal(response, errorResponse); e != nil && errorResponse.ErrorCode <= 0 { + return nil, fmt.Errorf("%d %s", resp.StatusCode, b) + } + return nil, errorResponse + } + + n := map[string]json.RawMessage{} + if err := json.Unmarshal(response, &n); err != nil { + return nil, err + } + + // list response may contain only one key + if len(n) > 1 || strings.HasPrefix(key, "list") { + return response, nil + } + + if len(n) == 1 { + for k := range n { + // boolean response and asyncjob result may also contain + // only one key + if k == "success" || k == "jobid" { + return response, nil + } + return n[k], nil + } + } + + return response, nil +} + +// asyncRequest perform an asynchronous job with a context +func (client *Client) asyncRequest(ctx context.Context, asyncCommand AsyncCommand) (interface{}, error) { + var err error + + resp := asyncCommand.AsyncResponse() + client.AsyncRequestWithContext( + ctx, + asyncCommand, + func(j *AsyncJobResult, e error) bool { + if e != nil { + err = e + return false + } + if j.JobStatus != Pending { + if r := j.Result(resp); r != nil { + err = r + } + return false + } + return true + }, + ) + return resp, err +} + +// SyncRequestWithContext performs a sync request with a context +func (client *Client) SyncRequestWithContext(ctx context.Context, command Command) (interface{}, error) { + body, err := client.request(ctx, command) + if err != nil { + return nil, err + } + + response := command.Response() + b, ok := response.(*BooleanResponse) + if ok { + m := make(map[string]interface{}) + if errUnmarshal := json.Unmarshal(body, &m); errUnmarshal != nil { + return nil, errUnmarshal + } + + b.DisplayText, _ = m["displaytext"].(string) + + if success, okSuccess := m["success"].(string); okSuccess { + b.Success = success == "true" + } + + if success, okSuccess := m["success"].(bool); okSuccess { + b.Success = success + } + + return b, nil + } + + if err := json.Unmarshal(body, response); err != nil { + errResponse := new(ErrorResponse) + if e := json.Unmarshal(body, errResponse); e == nil && errResponse.ErrorCode > 0 { + return errResponse, nil + } + return nil, err + } + + return response, nil +} + +// BooleanRequest performs the given boolean command +func (client *Client) BooleanRequest(command Command) error { + resp, err := client.Request(command) + if err != nil { + return err + } + + if b, ok := resp.(*BooleanResponse); ok { + return b.Error() + } + + panic(fmt.Errorf("command %q is not a proper boolean response. %#v", client.APIName(command), resp)) +} + +// BooleanRequestWithContext performs the given boolean command +func (client *Client) BooleanRequestWithContext(ctx context.Context, command Command) error { + resp, err := client.RequestWithContext(ctx, command) + if err != nil { + return err + } + + if b, ok := resp.(*BooleanResponse); ok { + return b.Error() + } + + panic(fmt.Errorf("command %q is not a proper boolean response. %#v", client.APIName(command), resp)) +} + +// Request performs the given command +func (client *Client) Request(command Command) (interface{}, error) { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + return client.RequestWithContext(ctx, command) +} + +// RequestWithContext preforms a command with a context +func (client *Client) RequestWithContext(ctx context.Context, command Command) (interface{}, error) { + switch c := command.(type) { + case AsyncCommand: + return client.asyncRequest(ctx, c) + default: + return client.SyncRequestWithContext(ctx, command) + } +} + +// SyncRequest performs the command as is +func (client *Client) SyncRequest(command Command) (interface{}, error) { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + return client.SyncRequestWithContext(ctx, command) +} + +// AsyncRequest performs the given command +func (client *Client) AsyncRequest(asyncCommand AsyncCommand, callback WaitAsyncJobResultFunc) { + ctx, cancel := context.WithTimeout(context.Background(), client.Timeout) + defer cancel() + + client.AsyncRequestWithContext(ctx, asyncCommand, callback) +} + +// AsyncRequestWithContext preforms a request with a context +func (client *Client) AsyncRequestWithContext(ctx context.Context, asyncCommand AsyncCommand, callback WaitAsyncJobResultFunc) { + result, err := client.SyncRequestWithContext(ctx, asyncCommand) + if err != nil { + if !callback(nil, err) { + return + } + } + + jobResult, ok := result.(*AsyncJobResult) + if !ok { + callback(nil, fmt.Errorf("wrong type, AsyncJobResult was expected instead of %T", result)) + } + + // Successful response + if jobResult.JobID == nil || jobResult.JobStatus != Pending { + callback(jobResult, nil) + // without a JobID, the next requests will only fail + return + } + + for iteration := 0; ; iteration++ { + time.Sleep(client.RetryStrategy(int64(iteration))) + + req := &QueryAsyncJobResult{JobID: jobResult.JobID} + resp, err := client.SyncRequestWithContext(ctx, req) + if err != nil && !callback(nil, err) { + return + } + + result, ok := resp.(*AsyncJobResult) + if !ok { + if !callback(nil, fmt.Errorf("wrong type. AsyncJobResult expected, got %T", resp)) { + return + } + } + + if !callback(result, nil) { + return + } + } +} + +// Payload builds the HTTP request params from the given command +func (client *Client) Payload(command Command) (url.Values, error) { + params, err := prepareValues("", command) + if err != nil { + return nil, err + } + if hookReq, ok := command.(onBeforeHook); ok { + if err := hookReq.onBeforeSend(params); err != nil { + return params, err + } + } + params.Set("apikey", client.APIKey) + params.Set("command", client.APIName(command)) + params.Set("response", "json") + + if params.Get("expires") == "" && client.Expiration >= 0 { + params.Set("signatureversion", "3") + params.Set("expires", time.Now().Add(client.Expiration).Local().Format("2006-01-02T15:04:05-0700")) + } + + return params, nil +} + +// Sign signs the HTTP request and returns the signature as as base64 encoding +func (client *Client) Sign(params url.Values) (string, error) { + query := encodeValues(params) + query = strings.ToLower(query) + mac := hmac.New(sha1.New, []byte(client.apiSecret)) + _, err := mac.Write([]byte(query)) + if err != nil { + return "", err + } + + signature := base64.StdEncoding.EncodeToString(mac.Sum(nil)) + return signature, nil +} + +// request makes a Request while being close to the metal +func (client *Client) request(ctx context.Context, command Command) (json.RawMessage, error) { + params, err := client.Payload(command) + if err != nil { + return nil, err + } + signature, err := client.Sign(params) + if err != nil { + return nil, err + } + params.Add("signature", signature) + + method := "GET" + query := params.Encode() + url := fmt.Sprintf("%s?%s", client.Endpoint, query) + + var body io.Reader + // respect Internet Explorer limit of 2048 + if len(url) > 2048 { + url = client.Endpoint + method = "POST" + body = strings.NewReader(query) + } + + request, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + request = request.WithContext(ctx) + request.Header.Add("User-Agent", UserAgent) + + if method == "POST" { + request.Header.Add("Content-Type", "application/x-www-form-urlencoded") + request.Header.Add("Content-Length", strconv.Itoa(len(query))) + } + + resp, err := client.HTTPClient.Do(request) + if err != nil { + return nil, err + } + defer resp.Body.Close() // nolint: errcheck + + contentType := resp.Header.Get("content-type") + + if !strings.Contains(contentType, "application/json") { + return nil, fmt.Errorf(`body content-type response expected "application/json", got %q`, contentType) + } + + text, err := client.parseResponse(resp, client.APIName(command)) + if err != nil { + return nil, err + } + + return text, nil +} + +func encodeValues(params url.Values) string { + // This code is borrowed from net/url/url.go + // The way it's encoded by net/url doesn't match + // how CloudStack works to determine the signature. + // + // CloudStack only encodes the values of the query parameters + // and furthermore doesn't use '+' for whitespaces. Therefore + // after encoding the values all '+' are replaced with '%20'. + if params == nil { + return "" + } + + var buf bytes.Buffer + keys := make([]string, 0, len(params)) + for k := range params { + keys = append(keys, k) + } + + sort.Strings(keys) + for _, k := range keys { + prefix := k + "=" + for _, v := range params[k] { + if buf.Len() > 0 { + buf.WriteByte('&') + } + buf.WriteString(prefix) + buf.WriteString(csEncode(v)) + } + } + return buf.String() +} diff --git a/vendor/github.com/exoscale/egoscale/request_type.go b/vendor/github.com/exoscale/egoscale/request_type.go new file mode 100644 index 000000000..7394e1ad3 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/request_type.go @@ -0,0 +1,184 @@ +package egoscale + +import ( + "net/url" +) + +// Command represents a generic request +type Command interface { + Response() interface{} +} + +// AsyncCommand represents a async request +type AsyncCommand interface { + Command + AsyncResponse() interface{} +} + +// ListCommand represents a listing request +type ListCommand interface { + Listable + Command + // SetPage defines the current pages + SetPage(int) + // SetPageSize defines the size of the page + SetPageSize(int) + // Each reads the data from the response and feeds channels, and returns true if we are on the last page + Each(interface{}, IterateItemFunc) +} + +// onBeforeHook represents an action to be done on the params before sending them +// +// This little took helps with issue of relying on JSON serialization logic only. +// `omitempty` may make sense in some cases but not all the time. +type onBeforeHook interface { + onBeforeSend(params url.Values) error +} + +// CommandInfo represents the meta data related to a Command +type CommandInfo struct { + Name string + Description string + RootOnly bool +} + +// JobStatusType represents the status of a Job +type JobStatusType int + +//go:generate stringer -type JobStatusType +const ( + // Pending represents a job in progress + Pending JobStatusType = iota + // Success represents a successfully completed job + Success + // Failure represents a job that has failed to complete + Failure +) + +// ErrorCode represents the CloudStack ApiErrorCode enum +// +// See: https://github.com/apache/cloudstack/blob/master/api/src/main/java/org/apache/cloudstack/api/ApiErrorCode.java +type ErrorCode int + +//go:generate stringer -type ErrorCode +const ( + // Unauthorized represents ... (TODO) + Unauthorized ErrorCode = 401 + // MethodNotAllowed represents ... (TODO) + MethodNotAllowed ErrorCode = 405 + // UnsupportedActionError represents ... (TODO) + UnsupportedActionError ErrorCode = 422 + // APILimitExceeded represents ... (TODO) + APILimitExceeded ErrorCode = 429 + // MalformedParameterError represents ... (TODO) + MalformedParameterError ErrorCode = 430 + // ParamError represents ... (TODO) + ParamError ErrorCode = 431 + + // InternalError represents a server error + InternalError ErrorCode = 530 + // AccountError represents ... (TODO) + AccountError ErrorCode = 531 + // AccountResourceLimitError represents ... (TODO) + AccountResourceLimitError ErrorCode = 532 + // InsufficientCapacityError represents ... (TODO) + InsufficientCapacityError ErrorCode = 533 + // ResourceUnavailableError represents ... (TODO) + ResourceUnavailableError ErrorCode = 534 + // ResourceAllocationError represents ... (TODO) + ResourceAllocationError ErrorCode = 535 + // ResourceInUseError represents ... (TODO) + ResourceInUseError ErrorCode = 536 + // NetworkRuleConflictError represents ... (TODO) + NetworkRuleConflictError ErrorCode = 537 +) + +// CSErrorCode represents the CloudStack CSExceptionErrorCode enum +// +// See: https://github.com/apache/cloudstack/blob/master/utils/src/main/java/com/cloud/utils/exception/CSExceptionErrorCode.java +type CSErrorCode int + +//go:generate stringer -type CSErrorCode +const ( + // CloudRuntimeException ... (TODO) + CloudRuntimeException CSErrorCode = 4250 + // ExecutionException ... (TODO) + ExecutionException CSErrorCode = 4260 + // HypervisorVersionChangedException ... (TODO) + HypervisorVersionChangedException CSErrorCode = 4265 + // CloudException ... (TODO) + CloudException CSErrorCode = 4275 + // AccountLimitException ... (TODO) + AccountLimitException CSErrorCode = 4280 + // AgentUnavailableException ... (TODO) + AgentUnavailableException CSErrorCode = 4285 + // CloudAuthenticationException ... (TODO) + CloudAuthenticationException CSErrorCode = 4290 + // ConcurrentOperationException ... (TODO) + ConcurrentOperationException CSErrorCode = 4300 + // ConflictingNetworksException ... (TODO) + ConflictingNetworkSettingsException CSErrorCode = 4305 + // DiscoveredWithErrorException ... (TODO) + DiscoveredWithErrorException CSErrorCode = 4310 + // HAStateException ... (TODO) + HAStateException CSErrorCode = 4315 + // InsufficientAddressCapacityException ... (TODO) + InsufficientAddressCapacityException CSErrorCode = 4320 + // InsufficientCapacityException ... (TODO) + InsufficientCapacityException CSErrorCode = 4325 + // InsufficientNetworkCapacityException ... (TODO) + InsufficientNetworkCapacityException CSErrorCode = 4330 + // InsufficientServerCapaticyException ... (TODO) + InsufficientServerCapacityException CSErrorCode = 4335 + // InsufficientStorageCapacityException ... (TODO) + InsufficientStorageCapacityException CSErrorCode = 4340 + // InternalErrorException ... (TODO) + InternalErrorException CSErrorCode = 4345 + // InvalidParameterValueException ... (TODO) + InvalidParameterValueException CSErrorCode = 4350 + // ManagementServerException ... (TODO) + ManagementServerException CSErrorCode = 4355 + // NetworkRuleConflictException ... (TODO) + NetworkRuleConflictException CSErrorCode = 4360 + // PermissionDeniedException ... (TODO) + PermissionDeniedException CSErrorCode = 4365 + // ResourceAllocationException ... (TODO) + ResourceAllocationException CSErrorCode = 4370 + // ResourceInUseException ... (TODO) + ResourceInUseException CSErrorCode = 4375 + // ResourceUnavailableException ... (TODO) + ResourceUnavailableException CSErrorCode = 4380 + // StorageUnavailableException ... (TODO) + StorageUnavailableException CSErrorCode = 4385 + // UnsupportedServiceException ... (TODO) + UnsupportedServiceException CSErrorCode = 4390 + // VirtualMachineMigrationException ... (TODO) + VirtualMachineMigrationException CSErrorCode = 4395 + // AsyncCommandQueued ... (TODO) + AsyncCommandQueued CSErrorCode = 4540 + // RequestLimitException ... (TODO) + RequestLimitException CSErrorCode = 4545 + // ServerAPIException ... (TODO) + ServerAPIException CSErrorCode = 9999 +) + +// ErrorResponse represents the standard error response +type ErrorResponse struct { + CSErrorCode CSErrorCode `json:"cserrorcode"` + ErrorCode ErrorCode `json:"errorcode"` + ErrorText string `json:"errortext"` + UUIDList []UUIDItem `json:"uuidList,omitempty"` // uuid*L*ist is not a typo +} + +// UUIDItem represents an item of the UUIDList part of an ErrorResponse +type UUIDItem struct { + Description string `json:"description,omitempty"` + SerialVersionUID int64 `json:"serialVersionUID,omitempty"` + UUID string `json:"uuid"` +} + +// BooleanResponse represents a boolean response (usually after a deletion) +type BooleanResponse struct { + DisplayText string `json:"displaytext,omitempty"` + Success bool `json:"success"` +} diff --git a/vendor/github.com/exoscale/egoscale/resource_limits.go b/vendor/github.com/exoscale/egoscale/resource_limits.go new file mode 100644 index 000000000..56011dc66 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/resource_limits.go @@ -0,0 +1,100 @@ +package egoscale + +// https://github.com/apache/cloudstack/blob/master/api/src/main/java/com/cloud/configuration/Resource.java + +// ResourceTypeName represents the name of a resource type (for limits) +type ResourceTypeName string + +const ( + // VirtualMachineTypeName is the resource type name of a VM + VirtualMachineTypeName ResourceTypeName = "user_vm" + // IPAddressTypeName is the resource type name of an IP address + IPAddressTypeName ResourceTypeName = "public_ip" + // VolumeTypeName is the resource type name of a volume + VolumeTypeName ResourceTypeName = "volume" + // SnapshotTypeName is the resource type name of a snapshot + SnapshotTypeName ResourceTypeName = "snapshot" + // TemplateTypeName is the resource type name of a template + TemplateTypeName ResourceTypeName = "template" + // ProjectTypeName is the resource type name of a project + ProjectTypeName ResourceTypeName = "project" + // NetworkTypeName is the resource type name of a network + NetworkTypeName ResourceTypeName = "network" + // VPCTypeName is the resource type name of a VPC + VPCTypeName ResourceTypeName = "vpc" + // CPUTypeName is the resource type name of a CPU + CPUTypeName ResourceTypeName = "cpu" + // MemoryTypeName is the resource type name of Memory + MemoryTypeName ResourceTypeName = "memory" + // PrimaryStorageTypeName is the resource type name of primary storage + PrimaryStorageTypeName ResourceTypeName = "primary_storage" + // SecondaryStorageTypeName is the resource type name of secondary storage + SecondaryStorageTypeName ResourceTypeName = "secondary_storage" +) + +// ResourceType represents the ID of a resource type (for limits) +type ResourceType string + +const ( + // VirtualMachineType is the resource type ID of a VM + VirtualMachineType ResourceType = "0" + // IPAddressType is the resource type ID of an IP address + IPAddressType ResourceType = "1" + // VolumeType is the resource type ID of a volume + VolumeType ResourceType = "2" + // SnapshotType is the resource type ID of a snapshot + SnapshotType ResourceType = "3" + // TemplateType is the resource type ID of a template + TemplateType ResourceType = "4" + // ProjectType is the resource type ID of a project + ProjectType ResourceType = "5" + // NetworkType is the resource type ID of a network + NetworkType ResourceType = "6" + // VPCType is the resource type ID of a VPC + VPCType ResourceType = "7" + // CPUType is the resource type ID of a CPU + CPUType ResourceType = "8" + // MemoryType is the resource type ID of Memory + MemoryType ResourceType = "9" + // PrimaryStorageType is the resource type ID of primary storage + PrimaryStorageType ResourceType = "10" + // SecondaryStorageType is the resource type ID of secondary storage + SecondaryStorageType ResourceType = "11" +) + +// ResourceLimit represents the limit on a particular resource +type ResourceLimit struct { + Max int64 `json:"max,omitempty" doc:"the maximum number of the resource. A -1 means the resource currently has no limit."` + ResourceType ResourceType `json:"resourcetype,omitempty" doc:"resource type. Values include 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11. See the resourceType parameter for more information on these values."` + ResourceTypeName string `json:"resourcetypename,omitempty" doc:"resource type name. Values include user_vm, public_ip, volume, snapshot, template, network, cpu, memory, primary_storage, secondary_storage."` +} + +// ListRequest builds the ListResourceLimits request +func (limit ResourceLimit) ListRequest() (ListCommand, error) { + req := &ListResourceLimits{ + ResourceType: limit.ResourceType, + ResourceTypeName: limit.ResourceTypeName, + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListResourceLimits + +// ListResourceLimits lists the resource limits +type ListResourceLimits struct { + ID int64 `json:"id,omitempty" doc:"Lists resource limits by ID."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ResourceType ResourceType `json:"resourcetype,omitempty" doc:"Type of resource. Values are 0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12, and 13. 0 - Instance. Number of instances a user can create. 1 - IP. Number of public IP addresses an account can own. 2 - Volume. Number of disk volumes an account can own. 3 - Snapshot. Number of snapshots an account can own. 4 - Template. Number of templates an account can register/create. 6 - Network. Number of networks an account can own. 8 - CPU. Number of CPU an account can allocate for his resources. 9 - Memory. Amount of RAM an account can allocate for his resources. 10 - PrimaryStorage. Total primary storage space (in GiB) a user can use. 11 - SecondaryStorage. Total secondary storage space (in GiB) a user can use. 12 - Elastic IP. Number of public elastic IP addresses an account can own. 13 - SMTP. If the account is allowed SMTP outbound traffic."` + ResourceTypeName string `json:"resourcetypename,omitempty" doc:"Type of resource (wins over resourceType if both are provided). Values are: user_vm - Instance. Number of instances a user can create. public_ip - IP. Number of public IP addresses an account can own. volume - Volume. Number of disk volumes an account can own. snapshot - Snapshot. Number of snapshots an account can own. template - Template. Number of templates an account can register/create. network - Network. Number of networks an account can own. cpu - CPU. Number of CPU an account can allocate for his resources. memory - Memory. Amount of RAM an account can allocate for his resources. primary_storage - PrimaryStorage. Total primary storage space (in GiB) a user can use. secondary_storage - SecondaryStorage. Total secondary storage space (in GiB) a user can use. public_elastic_ip - IP. Number of public elastic IP addresses an account can own. smtp - SG. If the account is allowed SMTP outbound traffic."` + + _ bool `name:"listResourceLimits" description:"Lists resource limits."` +} + +// ListResourceLimitsResponse represents a list of resource limits +type ListResourceLimitsResponse struct { + Count int `json:"count"` + ResourceLimit []ResourceLimit `json:"resourcelimit"` +} diff --git a/vendor/github.com/exoscale/egoscale/resource_metadata.go b/vendor/github.com/exoscale/egoscale/resource_metadata.go new file mode 100644 index 000000000..52c5ee8b0 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/resource_metadata.go @@ -0,0 +1,41 @@ +package egoscale + +import "fmt" + +// ResourceDetail represents extra details +type ResourceDetail ResourceTag + +// ListRequest builds the ListResourceDetails request +func (detail ResourceDetail) ListRequest() (ListCommand, error) { + if detail.ResourceType == "" { + return nil, fmt.Errorf("the resourcetype parameter is required") + } + + req := &ListResourceDetails{ + ResourceType: detail.ResourceType, + ResourceID: detail.ResourceID, + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListResourceDetails + +// ListResourceDetails lists the resource tag(s) (but different from listTags...) +type ListResourceDetails struct { + ResourceType string `json:"resourcetype" doc:"list by resource type"` + ForDisplay bool `json:"fordisplay,omitempty" doc:"if set to true, only details marked with display=true, are returned. False by default"` + Key string `json:"key,omitempty" doc:"list by key"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ResourceID *UUID `json:"resourceid,omitempty" doc:"list by resource id"` + Value string `json:"value,omitempty" doc:"list by key, value. Needs to be passed only along with key"` + _ bool `name:"listResourceDetails" description:"List resource detail(s)"` +} + +// ListResourceDetailsResponse represents a list of resource details +type ListResourceDetailsResponse struct { + Count int `json:"count"` + ResourceDetail []ResourceTag `json:"resourcedetail"` +} diff --git a/vendor/github.com/exoscale/egoscale/resourcedetails_response.go b/vendor/github.com/exoscale/egoscale/resourcedetails_response.go new file mode 100644 index 000000000..2a08cd825 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/resourcedetails_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListResourceDetails) Response() interface{} { + return new(ListResourceDetailsResponse) +} + +// ListRequest returns itself +func (ls *ListResourceDetails) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListResourceDetails) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListResourceDetails) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListResourceDetails) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListResourceDetailsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListResourceDetailsResponse was expected, got %T", resp)) + return + } + + for i := range items.ResourceDetail { + if !callback(&items.ResourceDetail[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/resourcelimits_response.go b/vendor/github.com/exoscale/egoscale/resourcelimits_response.go new file mode 100644 index 000000000..656febfc9 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/resourcelimits_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListResourceLimits) Response() interface{} { + return new(ListResourceLimitsResponse) +} + +// ListRequest returns itself +func (ls *ListResourceLimits) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListResourceLimits) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListResourceLimits) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListResourceLimits) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListResourceLimitsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListResourceLimitsResponse was expected, got %T", resp)) + return + } + + for i := range items.ResourceLimit { + if !callback(&items.ResourceLimit[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/reversedns.go b/vendor/github.com/exoscale/egoscale/reversedns.go new file mode 100644 index 000000000..e8bd124ce --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/reversedns.go @@ -0,0 +1,83 @@ +package egoscale + +import ( + "net" +) + +// ReverseDNS represents the PTR record linked with an IPAddress or IP6Address belonging to a Virtual Machine or a Public IP Address (Elastic IP) instance +type ReverseDNS struct { + DomainName string `json:"domainname,omitempty" doc:"the domain name of the PTR record"` + IP6Address net.IP `json:"ip6address,omitempty" doc:"the IPv6 address linked with the PTR record (mutually exclusive with ipaddress)"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"the IPv4 address linked with the PTR record (mutually exclusive with ip6address)"` + NicID *UUID `json:"nicid,omitempty" doc:"the virtual machine default NIC ID"` + PublicIPID *UUID `json:"publicipid,omitempty" doc:"the public IP address ID"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"the virtual machine ID"` +} + +// DeleteReverseDNSFromPublicIPAddress is a command to create/delete the PTR record of a public IP address +type DeleteReverseDNSFromPublicIPAddress struct { + ID *UUID `json:"id,omitempty" doc:"the ID of the public IP address"` + _ bool `name:"deleteReverseDnsFromPublicIpAddress" description:"delete the PTR DNS record from the public IP address"` +} + +// Response returns the struct to unmarshal +func (*DeleteReverseDNSFromPublicIPAddress) Response() interface{} { + return new(BooleanResponse) +} + +// DeleteReverseDNSFromVirtualMachine is a command to create/delete the PTR record(s) of a virtual machine +type DeleteReverseDNSFromVirtualMachine struct { + ID *UUID `json:"id,omitempty" doc:"the ID of the virtual machine"` + _ bool `name:"deleteReverseDnsFromVirtualMachine" description:"Delete the PTR DNS record(s) from the virtual machine"` +} + +// Response returns the struct to unmarshal +func (*DeleteReverseDNSFromVirtualMachine) Response() interface{} { + return new(BooleanResponse) +} + +// QueryReverseDNSForPublicIPAddress is a command to create/query the PTR record of a public IP address +type QueryReverseDNSForPublicIPAddress struct { + ID *UUID `json:"id,omitempty" doc:"the ID of the public IP address"` + _ bool `name:"queryReverseDnsForPublicIpAddress" description:"Query the PTR DNS record for the public IP address"` +} + +// Response returns the struct to unmarshal +func (*QueryReverseDNSForPublicIPAddress) Response() interface{} { + return new(IPAddress) +} + +// QueryReverseDNSForVirtualMachine is a command to create/query the PTR record(s) of a virtual machine +type QueryReverseDNSForVirtualMachine struct { + ID *UUID `json:"id,omitempty" doc:"the ID of the virtual machine"` + _ bool `name:"queryReverseDnsForVirtualMachine" description:"Query the PTR DNS record(s) for the virtual machine"` +} + +// Response returns the struct to unmarshal +func (*QueryReverseDNSForVirtualMachine) Response() interface{} { + return new(VirtualMachine) +} + +// UpdateReverseDNSForPublicIPAddress is a command to create/update the PTR record of a public IP address +type UpdateReverseDNSForPublicIPAddress struct { + DomainName string `json:"domainname,omitempty" doc:"the domain name for the PTR record. It must have a valid TLD"` + ID *UUID `json:"id,omitempty" doc:"the ID of the public IP address"` + _ bool `name:"updateReverseDnsForPublicIpAddress" description:"Update/create the PTR DNS record for the public IP address"` +} + +// Response returns the struct to unmarshal +func (*UpdateReverseDNSForPublicIPAddress) Response() interface{} { + return new(IPAddress) +} + +// UpdateReverseDNSForVirtualMachine is a command to create/update the PTR record(s) of a virtual machine +type UpdateReverseDNSForVirtualMachine struct { + DomainName string `json:"domainname,omitempty" doc:"the domain name for the PTR record(s). It must have a valid TLD"` + ID *UUID `json:"id,omitempty" doc:"the ID of the virtual machine"` + _ bool `name:"updateReverseDnsForVirtualMachine" description:"Update/create the PTR DNS record(s) for the virtual machine"` +} + +// Response returns the struct to unmarshal +func (*UpdateReverseDNSForVirtualMachine) Response() interface{} { + return new(VirtualMachine) +} diff --git a/vendor/github.com/exoscale/egoscale/runstatus.go b/vendor/github.com/exoscale/egoscale/runstatus.go new file mode 100644 index 000000000..48905962e --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/runstatus.go @@ -0,0 +1,131 @@ +package egoscale + +import ( + "context" + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + "time" +) + +// RunstatusValidationErrorResponse represents an error in the API +type RunstatusValidationErrorResponse map[string][]string + +// RunstatusErrorResponse represents the default errors +type RunstatusErrorResponse struct { + Detail string `json:"detail"` +} + +// runstatusPagesURL is the only URL that cannot be guessed +const runstatusPagesURL = "/pages" + +// Error formats the DNSerror into a string +func (req RunstatusErrorResponse) Error() string { + return fmt.Sprintf("Runstatus error: %s", req.Detail) +} + +// Error formats the DNSerror into a string +func (req RunstatusValidationErrorResponse) Error() string { + if len(req) > 0 { + errs := []string{} + for name, ss := range req { + if len(ss) > 0 { + errs = append(errs, fmt.Sprintf("%s: %s", name, strings.Join(ss, ", "))) + } + } + return fmt.Sprintf("Runstatus error: %s", strings.Join(errs, "; ")) + } + return fmt.Sprintf("Runstatus error") +} + +func (client *Client) runstatusRequest(ctx context.Context, uri string, structParam interface{}, method string) (json.RawMessage, error) { + reqURL, err := url.Parse(uri) + if err != nil { + return nil, err + } + if reqURL.Scheme == "" { + return nil, fmt.Errorf("only absolute URI are considered valid, got %q", uri) + } + + var params string + if structParam != nil { + m, err := json.Marshal(structParam) + if err != nil { + return nil, err + } + params = string(m) + } + + req, err := http.NewRequest(method, reqURL.String(), strings.NewReader(params)) + if err != nil { + return nil, err + } + + time := time.Now().Local().Format("2006-01-02T15:04:05-0700") + + payload := fmt.Sprintf("%s%s%s", req.URL.String(), time, params) + + mac := hmac.New(sha256.New, []byte(client.apiSecret)) + _, err = mac.Write([]byte(payload)) + if err != nil { + return nil, err + } + signature := hex.EncodeToString(mac.Sum(nil)) + + var hdr = make(http.Header) + + hdr.Add("Authorization", fmt.Sprintf("Exoscale-HMAC-SHA256 %s:%s", client.APIKey, signature)) + hdr.Add("Exoscale-Date", time) + hdr.Add("User-Agent", UserAgent) + hdr.Add("Accept", "application/json") + if params != "" { + hdr.Add("Content-Type", "application/json") + } + req.Header = hdr + + req = req.WithContext(ctx) + + resp, err := client.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() // nolint: errcheck + + if resp.StatusCode == 204 { + if method != "DELETE" { + return nil, fmt.Errorf("only DELETE is expected to produce 204, was %q", method) + } + return nil, nil + } + + contentType := resp.Header.Get("content-type") + if !strings.Contains(contentType, "application/json") { + return nil, fmt.Errorf(`response %d content-type expected to be "application/json", got %q`, resp.StatusCode, contentType) + } + + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode >= 400 { + rerr := new(RunstatusValidationErrorResponse) + if err := json.Unmarshal(b, rerr); err == nil { + return nil, rerr + } + rverr := new(RunstatusErrorResponse) + if err := json.Unmarshal(b, rverr); err != nil { + return nil, err + } + + return nil, rverr + } + + return b, nil +} diff --git a/vendor/github.com/exoscale/egoscale/runstatus_event.go b/vendor/github.com/exoscale/egoscale/runstatus_event.go new file mode 100644 index 000000000..2c698788b --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/runstatus_event.go @@ -0,0 +1,37 @@ +package egoscale + +import ( + "context" + "fmt" + "time" +) + +//RunstatusEvent is a runstatus event +type RunstatusEvent struct { + Created *time.Time `json:"created,omitempty"` + State string `json:"state,omitempty"` + Status string `json:"status"` + Text string `json:"text"` +} + +// UpdateRunstatusIncident create runstatus incident event +// Events can be updates or final message with status completed. +func (client *Client) UpdateRunstatusIncident(ctx context.Context, incident RunstatusIncident, event RunstatusEvent) error { + if incident.EventsURL == "" { + return fmt.Errorf("empty Events URL for %#v", incident) + } + + _, err := client.runstatusRequest(ctx, incident.EventsURL, event, "POST") + return err +} + +// UpdateRunstatusMaintenance adds a event to a maintenance. +// Events can be updates or final message with status completed. +func (client *Client) UpdateRunstatusMaintenance(ctx context.Context, maintenance RunstatusMaintenance, event RunstatusEvent) error { + if maintenance.EventsURL == "" { + return fmt.Errorf("empty Events URL for %#v", maintenance) + } + + _, err := client.runstatusRequest(ctx, maintenance.EventsURL, event, "POST") + return err +} diff --git a/vendor/github.com/exoscale/egoscale/runstatus_incident.go b/vendor/github.com/exoscale/egoscale/runstatus_incident.go new file mode 100644 index 000000000..57d20c81b --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/runstatus_incident.go @@ -0,0 +1,175 @@ +package egoscale + +import ( + "context" + "encoding/json" + "fmt" + "time" +) + +//RunstatusIncident is a runstatus incident +type RunstatusIncident struct { + EndDate *time.Time `json:"end_date,omitempty"` + Events []RunstatusEvent `json:"events,omitempty"` + EventsURL string `json:"events_url,omitempty"` + ID int `json:"id,omitempty"` + PageURL string `json:"page_url,omitempty"` // fake field + PostMortem string `json:"post_mortem,omitempty"` + RealTime bool `json:"real_time,omitempty"` + Services []string `json:"services"` + StartDate *time.Time `json:"start_date,omitempty"` + State string `json:"state"` + Status string `json:"status"` + StatusText string `json:"status_text"` + Title string `json:"title"` + URL string `json:"url,omitempty"` +} + +// Match returns true if the other incident has got similarities with itself +func (incident RunstatusIncident) Match(other RunstatusIncident) bool { + if other.Title != "" && incident.Title == other.Title { + return true + } + + if other.ID > 0 && incident.ID == other.ID { + return true + } + + return false +} + +//RunstatusIncidentList is a list of incident +type RunstatusIncidentList struct { + Next string `json:"next"` + Previous string `json:"previous"` + Incidents []RunstatusIncident `json:"results"` +} + +// GetRunstatusIncident retrieves the details of a specific incident. +func (client *Client) GetRunstatusIncident(ctx context.Context, incident RunstatusIncident) (*RunstatusIncident, error) { + if incident.URL != "" { + return client.getRunstatusIncident(ctx, incident.URL) + } + + if incident.PageURL == "" { + return nil, fmt.Errorf("empty Page URL for %#v", incident) + } + + page, err := client.getRunstatusPage(ctx, incident.PageURL) + if err != nil { + return nil, err + } + + for i := range page.Incidents { + j := &page.Incidents[i] + if j.Match(incident) { + return j, nil + } + } + + return nil, fmt.Errorf("%#v not found", incident) +} + +func (client *Client) getRunstatusIncident(ctx context.Context, incidentURL string) (*RunstatusIncident, error) { + resp, err := client.runstatusRequest(ctx, incidentURL, nil, "GET") + if err != nil { + return nil, err + } + + i := new(RunstatusIncident) + if err := json.Unmarshal(resp, i); err != nil { + return nil, err + } + return i, nil +} + +// ListRunstatusIncidents lists the incidents for a specific page. +func (client *Client) ListRunstatusIncidents(ctx context.Context, page RunstatusPage) ([]RunstatusIncident, error) { + if page.IncidentsURL == "" { + return nil, fmt.Errorf("empty Incidents URL for %#v", page) + } + + results := make([]RunstatusIncident, 0) + + var err error + client.PaginateRunstatusIncidents(ctx, page, func(incident *RunstatusIncident, e error) bool { + if e != nil { + err = e + return false + } + + results = append(results, *incident) + return true + }) + + return results, err +} + +// PaginateRunstatusIncidents paginate Incidents +func (client *Client) PaginateRunstatusIncidents(ctx context.Context, page RunstatusPage, callback func(*RunstatusIncident, error) bool) { + if page.IncidentsURL == "" { + callback(nil, fmt.Errorf("empty Incidents URL for %#v", page)) + return + } + + incidentsURL := page.IncidentsURL + for incidentsURL != "" { + resp, err := client.runstatusRequest(ctx, incidentsURL, nil, "GET") + if err != nil { + callback(nil, err) + return + } + + var is *RunstatusIncidentList + if err := json.Unmarshal(resp, &is); err != nil { + callback(nil, err) + return + } + + for i := range is.Incidents { + if cont := callback(&is.Incidents[i], nil); !cont { + return + } + } + + incidentsURL = is.Next + } +} + +// CreateRunstatusIncident create runstatus incident +func (client *Client) CreateRunstatusIncident(ctx context.Context, incident RunstatusIncident) (*RunstatusIncident, error) { + if incident.PageURL == "" { + return nil, fmt.Errorf("empty Page URL for %#v", incident) + } + + page, err := client.getRunstatusPage(ctx, incident.PageURL) + if err != nil { + return nil, err + } + + if page.IncidentsURL == "" { + return nil, fmt.Errorf("empty Incidents URL for %#v", page) + } + + resp, err := client.runstatusRequest(ctx, page.IncidentsURL, incident, "POST") + if err != nil { + return nil, err + } + + i := &RunstatusIncident{} + if err := json.Unmarshal(resp, &i); err != nil { + return nil, err + } + + return i, nil +} + +// DeleteRunstatusIncident delete runstatus incident +func (client *Client) DeleteRunstatusIncident(ctx context.Context, incident RunstatusIncident) error { + if incident.URL == "" { + return fmt.Errorf("empty URL for %#v", incident) + } + + _, err := client.runstatusRequest(ctx, incident.URL, nil, "DELETE") + return err +} diff --git a/vendor/github.com/exoscale/egoscale/runstatus_maintenance.go b/vendor/github.com/exoscale/egoscale/runstatus_maintenance.go new file mode 100644 index 000000000..44501f9b7 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/runstatus_maintenance.go @@ -0,0 +1,208 @@ +package egoscale + +import ( + "context" + "encoding/json" + "fmt" + "log" + "net/url" + "path" + "strconv" + "time" +) + +// RunstatusMaintenance is a runstatus maintenance +type RunstatusMaintenance struct { + Created *time.Time `json:"created,omitempty"` + Description string `json:"description,omitempty"` + EndDate *time.Time `json:"end_date"` + Events []RunstatusEvent `json:"events,omitempty"` + EventsURL string `json:"events_url,omitempty"` + ID int `json:"id,omitempty"` // missing field + PageURL string `json:"page_url,omitempty"` // fake field + RealTime bool `json:"real_time,omitempty"` + Services []string `json:"services"` + StartDate *time.Time `json:"start_date"` + Status string `json:"status"` + Title string `json:"title"` + URL string `json:"url,omitempty"` +} + +// Match returns true if the other maintenance has got similarities with itself +func (maintenance RunstatusMaintenance) Match(other RunstatusMaintenance) bool { + if other.Title != "" && maintenance.Title == other.Title { + return true + } + + if other.ID > 0 && maintenance.ID == other.ID { + return true + } + + return false +} + +// FakeID fills up the ID field as it's currently missing +func (maintenance *RunstatusMaintenance) FakeID() error { + if maintenance.ID > 0 { + return nil + } + + if maintenance.URL == "" { + return fmt.Errorf("empty URL for %#v", maintenance) + } + + u, err := url.Parse(maintenance.URL) + if err != nil { + return err + } + + s := path.Base(u.Path) + id, err := strconv.Atoi(s) + if err != nil { + return err + } + maintenance.ID = id + return nil +} + +// RunstatusMaintenanceList is a list of incident +type RunstatusMaintenanceList struct { + Next string `json:"next"` + Previous string `json:"previous"` + Maintenances []RunstatusMaintenance `json:"results"` +} + +// GetRunstatusMaintenance retrieves the details of a specific maintenance. +func (client *Client) GetRunstatusMaintenance(ctx context.Context, maintenance RunstatusMaintenance) (*RunstatusMaintenance, error) { + if maintenance.URL != "" { + return client.getRunstatusMaintenance(ctx, maintenance.URL) + } + + if maintenance.PageURL == "" { + return nil, fmt.Errorf("empty Page URL for %#v", maintenance) + } + + page, err := client.getRunstatusPage(ctx, maintenance.PageURL) + if err != nil { + return nil, err + } + + for i := range page.Maintenances { + m := &page.Maintenances[i] + if m.Match(maintenance) { + if err := m.FakeID(); err != nil { + log.Printf("bad fake ID for %#v, %s", m, err) + } + return m, nil + } + } + + return nil, fmt.Errorf("%#v not found", maintenance) +} + +func (client *Client) getRunstatusMaintenance(ctx context.Context, maintenanceURL string) (*RunstatusMaintenance, error) { + resp, err := client.runstatusRequest(ctx, maintenanceURL, nil, "GET") + if err != nil { + return nil, err + } + + m := new(RunstatusMaintenance) + if err := json.Unmarshal(resp, m); err != nil { + return nil, err + } + return m, nil +} + +// ListRunstatusMaintenances returns the list of maintenances for the page. +func (client *Client) ListRunstatusMaintenances(ctx context.Context, page RunstatusPage) ([]RunstatusMaintenance, error) { + if page.MaintenancesURL == "" { + return nil, fmt.Errorf("empty Maintenances URL for %#v", page) + } + + results := make([]RunstatusMaintenance, 0) + + var err error + client.PaginateRunstatusMaintenances(ctx, page, func(maintenance *RunstatusMaintenance, e error) bool { + if e != nil { + err = e + return false + } + + results = append(results, *maintenance) + return true + }) + + return results, err +} + +// PaginateRunstatusMaintenances paginate Maintenances +func (client *Client) PaginateRunstatusMaintenances(ctx context.Context, page RunstatusPage, callback func(*RunstatusMaintenance, error) bool) { // nolint: dupl + if page.MaintenancesURL == "" { + callback(nil, fmt.Errorf("empty Maintenances URL for %#v", page)) + return + } + + maintenancesURL := page.MaintenancesURL + for maintenancesURL != "" { + resp, err := client.runstatusRequest(ctx, maintenancesURL, nil, "GET") + if err != nil { + callback(nil, err) + return + } + + var ms *RunstatusMaintenanceList + if err := json.Unmarshal(resp, &ms); err != nil { + callback(nil, err) + return + } + + for i := range ms.Maintenances { + if err := ms.Maintenances[i].FakeID(); err != nil { + log.Printf("bad fake ID for %#v, %s", ms.Maintenances[i], err) + } + if cont := callback(&ms.Maintenances[i], nil); !cont { + return + } + } + + maintenancesURL = ms.Next + } +} + +// CreateRunstatusMaintenance create runstatus Maintenance +func (client *Client) CreateRunstatusMaintenance(ctx context.Context, maintenance RunstatusMaintenance) (*RunstatusMaintenance, error) { + if maintenance.PageURL == "" { + return nil, fmt.Errorf("empty Page URL for %#v", maintenance) + } + + page, err := client.getRunstatusPage(ctx, maintenance.PageURL) + if err != nil { + return nil, err + } + + resp, err := client.runstatusRequest(ctx, page.MaintenancesURL, maintenance, "POST") + if err != nil { + return nil, err + } + + m := &RunstatusMaintenance{} + if err := json.Unmarshal(resp, &m); err != nil { + return nil, err + } + + if err := m.FakeID(); err != nil { + log.Printf("bad fake ID for %#v, %s", m, err) + } + + return m, nil +} + +// DeleteRunstatusMaintenance delete runstatus Maintenance +func (client *Client) DeleteRunstatusMaintenance(ctx context.Context, maintenance RunstatusMaintenance) error { + if maintenance.URL == "" { + return fmt.Errorf("empty URL for %#v", maintenance) + } + + _, err := client.runstatusRequest(ctx, maintenance.URL, nil, "DELETE") + return err +} diff --git a/vendor/github.com/exoscale/egoscale/runstatus_page.go b/vendor/github.com/exoscale/egoscale/runstatus_page.go new file mode 100644 index 000000000..01b6b8c77 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/runstatus_page.go @@ -0,0 +1,168 @@ +package egoscale + +import ( + "context" + "encoding/json" + "fmt" + "log" + "time" +) + +// RunstatusPage runstatus page +type RunstatusPage struct { + Created *time.Time `json:"created,omitempty"` + DarkTheme bool `json:"dark_theme,omitempty"` + Domain string `json:"domain,omitempty"` + GradientEnd string `json:"gradient_end,omitempty"` + GradientStart string `json:"gradient_start,omitempty"` + HeaderBackground string `json:"header_background,omitempty"` + ID int `json:"id,omitempty"` + Incidents []RunstatusIncident `json:"incidents,omitempty"` + IncidentsURL string `json:"incidents_url,omitempty"` + Logo string `json:"logo,omitempty"` + Maintenances []RunstatusMaintenance `json:"maintenances,omitempty"` + MaintenancesURL string `json:"maintenances_url,omitempty"` + Name string `json:"name"` //fake field (used to post a new runstatus page) + OkText string `json:"ok_text,omitempty"` + Plan string `json:"plan,omitempty"` + PublicURL string `json:"public_url,omitempty"` + Services []RunstatusService `json:"services,omitempty"` + ServicesURL string `json:"services_url,omitempty"` + State string `json:"state,omitempty"` + Subdomain string `json:"subdomain"` + SupportEmail string `json:"support_email,omitempty"` + TimeZone string `json:"time_zone,omitempty"` + Title string `json:"title,omitempty"` + TitleColor string `json:"title_color,omitempty"` + TwitterUsername string `json:"twitter_username,omitempty"` + URL string `json:"url,omitempty"` +} + +// Match returns true if the other page has got similarities with itself +func (page RunstatusPage) Match(other RunstatusPage) bool { + if other.Subdomain != "" && page.Subdomain == other.Subdomain { + return true + } + + if other.ID > 0 && page.ID == other.ID { + return true + } + + return false +} + +// RunstatusPageList runstatus page list +type RunstatusPageList struct { + Next string `json:"next"` + Previous string `json:"previous"` + Pages []RunstatusPage `json:"results"` +} + +// CreateRunstatusPage create runstatus page +func (client *Client) CreateRunstatusPage(ctx context.Context, page RunstatusPage) (*RunstatusPage, error) { + resp, err := client.runstatusRequest(ctx, client.Endpoint+runstatusPagesURL, page, "POST") + if err != nil { + return nil, err + } + + var p *RunstatusPage + if err := json.Unmarshal(resp, &p); err != nil { + return nil, err + } + + return p, nil +} + +// DeleteRunstatusPage delete runstatus page +func (client *Client) DeleteRunstatusPage(ctx context.Context, page RunstatusPage) error { + if page.URL == "" { + return fmt.Errorf("empty URL for %#v", page) + } + _, err := client.runstatusRequest(ctx, page.URL, nil, "DELETE") + return err +} + +// GetRunstatusPage fetches the runstatus page +func (client *Client) GetRunstatusPage(ctx context.Context, page RunstatusPage) (*RunstatusPage, error) { + if page.URL != "" { + return client.getRunstatusPage(ctx, page.URL) + } + + ps, err := client.ListRunstatusPages(ctx) + if err != nil { + return nil, err + } + + for i := range ps { + if ps[i].Match(page) { + return client.getRunstatusPage(ctx, ps[i].URL) + } + } + + return nil, fmt.Errorf("%#v not found", page) +} + +func (client *Client) getRunstatusPage(ctx context.Context, pageURL string) (*RunstatusPage, error) { + resp, err := client.runstatusRequest(ctx, pageURL, nil, "GET") + if err != nil { + return nil, err + } + + p := new(RunstatusPage) + if err := json.Unmarshal(resp, p); err != nil { + return nil, err + } + + // NOTE: fix the missing IDs + for i := range p.Maintenances { + if err := p.Maintenances[i].FakeID(); err != nil { + log.Printf("bad fake ID for %#v, %s", p.Maintenances[i], err) + } + } + for i := range p.Services { + if err := p.Services[i].FakeID(); err != nil { + log.Printf("bad fake ID for %#v, %s", p.Services[i], err) + } + } + + return p, nil +} + +// ListRunstatusPages list all the runstatus pages +func (client *Client) ListRunstatusPages(ctx context.Context) ([]RunstatusPage, error) { + resp, err := client.runstatusRequest(ctx, client.Endpoint+runstatusPagesURL, nil, "GET") + if err != nil { + return nil, err + } + + var p *RunstatusPageList + if err := json.Unmarshal(resp, &p); err != nil { + return nil, err + } + + return p.Pages, nil +} + +//PaginateRunstatusPages paginate on runstatus pages +func (client *Client) PaginateRunstatusPages(ctx context.Context, callback func(pages []RunstatusPage, e error) bool) { + pageURL := client.Endpoint + runstatusPagesURL + for pageURL != "" { + resp, err := client.runstatusRequest(ctx, pageURL, nil, "GET") + if err != nil { + callback(nil, err) + return + } + + var p *RunstatusPageList + if err := json.Unmarshal(resp, &p); err != nil { + callback(nil, err) + return + } + + if ok := callback(p.Pages, nil); ok { + return + } + + pageURL = p.Next + } +} diff --git a/vendor/github.com/exoscale/egoscale/runstatus_service.go b/vendor/github.com/exoscale/egoscale/runstatus_service.go new file mode 100644 index 000000000..456d92fcf --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/runstatus_service.go @@ -0,0 +1,201 @@ +package egoscale + +import ( + "context" + "encoding/json" + "fmt" + "log" + "net/url" + "path" + "strconv" +) + +// RunstatusService is a runstatus service +type RunstatusService struct { + ID int `json:"id"` // missing field + Name string `json:"name"` + PageURL string `json:"page_url,omitempty"` // fake field + State string `json:"state,omitempty"` + URL string `json:"url,omitempty"` +} + +// FakeID fills up the ID field as it's currently missing +func (service *RunstatusService) FakeID() error { + if service.ID > 0 { + return nil + } + + if service.URL == "" { + return fmt.Errorf("empty URL for %#v", service) + } + + u, err := url.Parse(service.URL) + if err != nil { + return err + } + + s := path.Base(u.Path) + id, err := strconv.Atoi(s) + if err != nil { + return err + } + service.ID = id + return nil +} + +// Match returns true if the other service has got similarities with itself +func (service RunstatusService) Match(other RunstatusService) bool { + if other.Name != "" && service.Name == other.Name { + return true + } + + if other.ID > 0 && service.ID == other.ID { + return true + } + + return false +} + +// RunstatusServiceList service list +type RunstatusServiceList struct { + Next string `json:"next"` + Previous string `json:"previous"` + Services []RunstatusService `json:"results"` +} + +// DeleteRunstatusService delete runstatus service +func (client *Client) DeleteRunstatusService(ctx context.Context, service RunstatusService) error { + if service.URL == "" { + return fmt.Errorf("empty URL for %#v", service) + } + + _, err := client.runstatusRequest(ctx, service.URL, nil, "DELETE") + return err +} + +// CreateRunstatusService create runstatus service +func (client *Client) CreateRunstatusService(ctx context.Context, service RunstatusService) (*RunstatusService, error) { + if service.PageURL == "" { + return nil, fmt.Errorf("empty Page URL for %#v", service) + } + + page, err := client.GetRunstatusPage(ctx, RunstatusPage{URL: service.PageURL}) + if err != nil { + return nil, err + } + + resp, err := client.runstatusRequest(ctx, page.ServicesURL, service, "POST") + if err != nil { + return nil, err + } + + s := &RunstatusService{} + if err := json.Unmarshal(resp, s); err != nil { + return nil, err + } + + return s, nil +} + +// GetRunstatusService displays service detail. +func (client *Client) GetRunstatusService(ctx context.Context, service RunstatusService) (*RunstatusService, error) { + if service.URL != "" { + return client.getRunstatusService(ctx, service.URL) + } + + if service.PageURL == "" { + return nil, fmt.Errorf("empty Page URL in %#v", service) + } + + page, err := client.getRunstatusPage(ctx, service.PageURL) + if err != nil { + return nil, err + } + + for i := range page.Services { + s := &page.Services[i] + if s.Match(service) { + if err := s.FakeID(); err != nil { + log.Printf("bad fake ID for %#v, %s", s, err) + } + return s, nil + } + } + + return nil, fmt.Errorf("%#v not found", service) +} + +func (client *Client) getRunstatusService(ctx context.Context, serviceURL string) (*RunstatusService, error) { + resp, err := client.runstatusRequest(ctx, serviceURL, nil, "GET") + if err != nil { + return nil, err + } + + s := &RunstatusService{} + if err := json.Unmarshal(resp, &s); err != nil { + return nil, err + } + + if err := s.FakeID(); err != nil { + log.Printf("bad fake ID for %#v, %s", s, err) + } + + return s, nil +} + +// ListRunstatusServices displays the list of services. +func (client *Client) ListRunstatusServices(ctx context.Context, page RunstatusPage) ([]RunstatusService, error) { + if page.ServicesURL == "" { + return nil, fmt.Errorf("empty Services URL for %#v", page) + } + + results := make([]RunstatusService, 0) + + var err error + client.PaginateRunstatusServices(ctx, page, func(service *RunstatusService, e error) bool { + if e != nil { + err = e + return false + } + + results = append(results, *service) + return true + }) + + return results, err +} + +// PaginateRunstatusServices paginates Services +func (client *Client) PaginateRunstatusServices(ctx context.Context, page RunstatusPage, callback func(*RunstatusService, error) bool) { // nolint: dupl + if page.ServicesURL == "" { + callback(nil, fmt.Errorf("empty Services URL for %#v", page)) + return + } + + servicesURL := page.ServicesURL + for servicesURL != "" { + resp, err := client.runstatusRequest(ctx, servicesURL, nil, "GET") + if err != nil { + callback(nil, err) + return + } + + var ss *RunstatusServiceList + if err := json.Unmarshal(resp, &ss); err != nil { + callback(nil, err) + return + } + + for i := range ss.Services { + if err := ss.Services[i].FakeID(); err != nil { + log.Printf("bad fake ID for %#v, %s", ss.Services[i], err) + } + + if cont := callback(&ss.Services[i], nil); !cont { + return + } + } + + servicesURL = ss.Next + } +} diff --git a/vendor/github.com/exoscale/egoscale/security_groups.go b/vendor/github.com/exoscale/egoscale/security_groups.go new file mode 100644 index 000000000..a11e53a4f --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/security_groups.go @@ -0,0 +1,226 @@ +package egoscale + +import ( + "context" + "fmt" + "net/url" + "strconv" + "strings" +) + +// SecurityGroup represent a firewalling set of rules +type SecurityGroup struct { + Account string `json:"account,omitempty" doc:"the account owning the security group"` + Description string `json:"description,omitempty" doc:"the description of the security group"` + EgressRule []EgressRule `json:"egressrule,omitempty" doc:"the list of egress rules associated with the security group"` + ID *UUID `json:"id" doc:"the ID of the security group"` + IngressRule []IngressRule `json:"ingressrule,omitempty" doc:"the list of ingress rules associated with the security group"` + Name string `json:"name,omitempty" doc:"the name of the security group"` +} + +// UserSecurityGroup converts a SecurityGroup to a UserSecurityGroup +func (sg SecurityGroup) UserSecurityGroup() UserSecurityGroup { + return UserSecurityGroup{ + Group: sg.Name, + } +} + +// ListRequest builds the ListSecurityGroups request +func (sg SecurityGroup) ListRequest() (ListCommand, error) { + req := &ListSecurityGroups{ + ID: sg.ID, + SecurityGroupName: sg.Name, + } + + return req, nil +} + +// Delete deletes the given Security Group +func (sg SecurityGroup) Delete(ctx context.Context, client *Client) error { + if sg.ID == nil && sg.Name == "" { + return fmt.Errorf("a SecurityGroup may only be deleted using ID or Name") + } + + req := &DeleteSecurityGroup{} + + if sg.ID != nil { + req.ID = sg.ID + } else { + req.Name = sg.Name + } + + return client.BooleanRequestWithContext(ctx, req) +} + +// RuleByID returns IngressRule or EgressRule by a rule ID +func (sg SecurityGroup) RuleByID(ruleID UUID) (*IngressRule, *EgressRule) { + for i, in := range sg.IngressRule { + if in.RuleID.Equal(ruleID) { + return &sg.IngressRule[i], nil + } + } + + for i, out := range sg.EgressRule { + if out.RuleID.Equal(ruleID) { + return nil, &sg.EgressRule[i] + } + } + + return nil, nil +} + +// IngressRule represents the ingress rule +type IngressRule struct { + CIDR *CIDR `json:"cidr,omitempty" doc:"the CIDR notation for the base IP address of the security group rule"` + Description string `json:"description,omitempty" doc:"description of the security group rule"` + EndPort uint16 `json:"endport,omitempty" doc:"the ending port of the security group rule "` + IcmpCode uint8 `json:"icmpcode,omitempty" doc:"the code for the ICMP message response"` + IcmpType uint8 `json:"icmptype,omitempty" doc:"the type of the ICMP message response"` + Protocol string `json:"protocol,omitempty" doc:"the protocol of the security group rule"` + RuleID *UUID `json:"ruleid" doc:"the id of the security group rule"` + SecurityGroupName string `json:"securitygroupname,omitempty" doc:"security group name"` + StartPort uint16 `json:"startport,omitempty" doc:"the starting port of the security group rule"` +} + +// EgressRule represents the ingress rule +type EgressRule IngressRule + +// UserSecurityGroup represents the traffic of another security group +type UserSecurityGroup struct { + Group string `json:"group,omitempty"` +} + +// String gives the UserSecurityGroup name +func (usg UserSecurityGroup) String() string { + return usg.Group +} + +// CreateSecurityGroup represents a security group creation +type CreateSecurityGroup struct { + Name string `json:"name" doc:"name of the security group"` + Description string `json:"description,omitempty" doc:"the description of the security group"` + _ bool `name:"createSecurityGroup" description:"Creates a security group"` +} + +// Response returns the struct to unmarshal +func (CreateSecurityGroup) Response() interface{} { + return new(SecurityGroup) +} + +// DeleteSecurityGroup represents a security group deletion +type DeleteSecurityGroup struct { + ID *UUID `json:"id,omitempty" doc:"The ID of the security group. Mutually exclusive with name parameter"` + Name string `json:"name,omitempty" doc:"The ID of the security group. Mutually exclusive with id parameter"` + _ bool `name:"deleteSecurityGroup" description:"Deletes security group"` +} + +// Response returns the struct to unmarshal +func (DeleteSecurityGroup) Response() interface{} { + return new(BooleanResponse) +} + +// AuthorizeSecurityGroupIngress (Async) represents the ingress rule creation +type AuthorizeSecurityGroupIngress struct { + CIDRList []CIDR `json:"cidrlist,omitempty" doc:"the cidr list associated"` + Description string `json:"description,omitempty" doc:"the description of the ingress/egress rule"` + EndPort uint16 `json:"endport,omitempty" doc:"end port for this ingress/egress rule"` + IcmpCode uint8 `json:"icmpcode,omitempty" doc:"error code for this icmp message"` + IcmpType uint8 `json:"icmptype,omitempty" doc:"type of the icmp message being sent"` + Protocol string `json:"protocol,omitempty" doc:"TCP is default. UDP, ICMP, ICMPv6, AH, ESP, GRE, IPIP are the other supported protocols"` + SecurityGroupID *UUID `json:"securitygroupid,omitempty" doc:"The ID of the security group. Mutually exclusive with securitygroupname parameter"` + SecurityGroupName string `json:"securitygroupname,omitempty" doc:"The name of the security group. Mutually exclusive with securitygroupid parameter"` + StartPort uint16 `json:"startport,omitempty" doc:"start port for this ingress/egress rule"` + UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty" doc:"user to security group mapping"` + _ bool `name:"authorizeSecurityGroupIngress" description:"Authorize a particular ingress/egress rule for this security group"` +} + +// Response returns the struct to unmarshal +func (AuthorizeSecurityGroupIngress) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (AuthorizeSecurityGroupIngress) AsyncResponse() interface{} { + return new(SecurityGroup) +} + +func (req AuthorizeSecurityGroupIngress) onBeforeSend(params url.Values) error { + // ICMP code and type may be zero but can also be omitted... + if strings.HasPrefix(strings.ToLower(req.Protocol), "icmp") { + params.Set("icmpcode", strconv.FormatInt(int64(req.IcmpCode), 10)) + params.Set("icmptype", strconv.FormatInt(int64(req.IcmpType), 10)) + } + // StartPort may be zero but can also be omitted... + if req.EndPort != 0 && req.StartPort == 0 { + params.Set("startport", "0") + } + return nil +} + +// AuthorizeSecurityGroupEgress (Async) represents the egress rule creation +type AuthorizeSecurityGroupEgress AuthorizeSecurityGroupIngress + +// Response returns the struct to unmarshal +func (AuthorizeSecurityGroupEgress) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (AuthorizeSecurityGroupEgress) AsyncResponse() interface{} { + return new(SecurityGroup) +} + +func (req AuthorizeSecurityGroupEgress) onBeforeSend(params url.Values) error { + return (AuthorizeSecurityGroupIngress)(req).onBeforeSend(params) +} + +// RevokeSecurityGroupIngress (Async) represents the ingress/egress rule deletion +type RevokeSecurityGroupIngress struct { + ID *UUID `json:"id" doc:"The ID of the ingress rule"` + _ bool `name:"revokeSecurityGroupIngress" description:"Deletes a particular ingress rule from this security group"` +} + +// Response returns the struct to unmarshal +func (RevokeSecurityGroupIngress) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RevokeSecurityGroupIngress) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +// RevokeSecurityGroupEgress (Async) represents the ingress/egress rule deletion +type RevokeSecurityGroupEgress struct { + ID *UUID `json:"id" doc:"The ID of the egress rule"` + _ bool `name:"revokeSecurityGroupEgress" description:"Deletes a particular egress rule from this security group"` +} + +// Response returns the struct to unmarshal +func (RevokeSecurityGroupEgress) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RevokeSecurityGroupEgress) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +//go:generate go run generate/main.go -interface=Listable ListSecurityGroups + +// ListSecurityGroups represents a search for security groups +type ListSecurityGroups struct { + ID *UUID `json:"id,omitempty" doc:"list the security group by the id provided"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + SecurityGroupName string `json:"securitygroupname,omitempty" doc:"lists security groups by name"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"lists security groups by virtual machine id"` + _ bool `name:"listSecurityGroups" description:"Lists security groups"` +} + +// ListSecurityGroupsResponse represents a list of security groups +type ListSecurityGroupsResponse struct { + Count int `json:"count"` + SecurityGroup []SecurityGroup `json:"securitygroup"` +} diff --git a/vendor/github.com/exoscale/egoscale/securitygroups_response.go b/vendor/github.com/exoscale/egoscale/securitygroups_response.go new file mode 100644 index 000000000..ff08f333c --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/securitygroups_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListSecurityGroups) Response() interface{} { + return new(ListSecurityGroupsResponse) +} + +// ListRequest returns itself +func (ls *ListSecurityGroups) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListSecurityGroups) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListSecurityGroups) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListSecurityGroups) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListSecurityGroupsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListSecurityGroupsResponse was expected, got %T", resp)) + return + } + + for i := range items.SecurityGroup { + if !callback(&items.SecurityGroup[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/serialization.go b/vendor/github.com/exoscale/egoscale/serialization.go new file mode 100644 index 000000000..24a0c123f --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/serialization.go @@ -0,0 +1,402 @@ +package egoscale + +import ( + "encoding/base64" + "fmt" + "log" + "net" + "net/url" + "reflect" + "strconv" + "strings" +) + +func csQuotePlus(s string) string { + s = strings.Replace(s, "+", "%20", -1) + return s +} + +func csEncode(s string) string { + return csQuotePlus(url.QueryEscape(s)) +} + +// info returns the meta info of a command +// +// command is not a Command so it's easier to Test +func info(command interface{}) (*CommandInfo, error) { + typeof := reflect.TypeOf(command) + + // Going up the pointer chain to find the underlying struct + for typeof.Kind() == reflect.Ptr { + typeof = typeof.Elem() + } + + field, ok := typeof.FieldByName("_") + if !ok { + return nil, fmt.Errorf(`missing meta ("_") field in %#v`, command) + } + + name, nameOk := field.Tag.Lookup("name") + description, _ := field.Tag.Lookup("description") + + if !nameOk { + return nil, fmt.Errorf(`missing "name" key in the tag string of %#v`, command) + } + + info := &CommandInfo{ + Name: name, + Description: description, + } + + return info, nil +} + +// prepareValues uses a command to build a POST request +// +// command is not a Command so it's easier to Test +func prepareValues(prefix string, command interface{}) (url.Values, error) { + params := url.Values{} + + value := reflect.ValueOf(command) + typeof := reflect.TypeOf(command) + + // Going up the pointer chain to find the underlying struct + for typeof.Kind() == reflect.Ptr { + typeof = typeof.Elem() + value = value.Elem() + } + + // Checking for nil commands + if !value.IsValid() { + return nil, fmt.Errorf("cannot serialize the invalid value %#v", command) + } + + for i := 0; i < typeof.NumField(); i++ { + field := typeof.Field(i) + if field.Name == "_" { + continue + } + + val := value.Field(i) + tag := field.Tag + + var err error + var name string + var value interface{} + + if json, ok := tag.Lookup("json"); ok { + n, required := ExtractJSONTag(field.Name, json) + name = prefix + n + + switch val.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + value, err = prepareInt(val.Int(), required) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + value, err = prepareUint(val.Uint(), required) + + case reflect.Float32, reflect.Float64: + value, err = prepareFloat(val.Float(), required) + + case reflect.String: + value, err = prepareString(val.String(), required) + + case reflect.Bool: + value, err = prepareBool(val.Bool(), required) + + case reflect.Map: + if val.Len() == 0 { + if required { + err = fmt.Errorf("field is required, got empty map") + } + } else { + value, err = prepareMap(name, val.Interface()) + } + + case reflect.Ptr: + value, err = preparePtr(field.Type.Elem().Kind(), val, required) + + case reflect.Slice: + value, err = prepareSlice(name, field.Type, val, required) + + case reflect.Struct: + value, err = prepareStruct(val.Interface(), required) + + default: + if required { + err = fmt.Errorf("unsupported type") + } + } + } else { + switch val.Kind() { + case reflect.Struct: + value, err = prepareEmbedStruct(val.Interface()) + default: + log.Printf("[SKIP] %s.%s no json label found", typeof.Name(), field.Name) + } + } + + if err != nil { + return nil, fmt.Errorf("%s.%s (%v) %s", typeof.Name(), field.Name, val.Kind(), err) + } + + switch v := value.(type) { + case *string: + if name != "" && v != nil { + params.Set(name, *v) + } + case url.Values: + for k, xs := range v { + for _, x := range xs { + params.Add(k, x) + } + } + } + } + + return params, nil +} + +func prepareInt(v int64, required bool) (*string, error) { + if v == 0 { + if required { + return nil, fmt.Errorf("field is required, got %d", v) + } + return nil, nil + } + value := strconv.FormatInt(v, 10) + return &value, nil +} + +func prepareUint(v uint64, required bool) (*string, error) { + if v == 0 { + if required { + return nil, fmt.Errorf("field is required, got %d", v) + } + return nil, nil + } + + value := strconv.FormatUint(v, 10) + return &value, nil +} + +func prepareFloat(v float64, required bool) (*string, error) { + if v == 0 { + if required { + return nil, fmt.Errorf("field is required, got %f", v) + } + return nil, nil + } + value := strconv.FormatFloat(v, 'f', -1, 64) + return &value, nil +} + +func prepareString(v string, required bool) (*string, error) { + if v == "" { + if required { + return nil, fmt.Errorf("field is required, got %q", v) + } + return nil, nil + } + return &v, nil +} + +func prepareBool(v bool, required bool) (*string, error) { + value := strconv.FormatBool(v) + if !v { + if required { + return &value, nil + } + return nil, nil + } + + return &value, nil +} + +func prepareList(prefix string, slice interface{}) (url.Values, error) { + params := url.Values{} + value := reflect.ValueOf(slice) + + for i := 0; i < value.Len(); i++ { + ps, err := prepareValues(fmt.Sprintf("%s[%d].", prefix, i), value.Index(i).Interface()) + if err != nil { + return nil, err + } + + for k, xs := range ps { + for _, x := range xs { + params.Add(k, x) + } + } + } + + return params, nil +} + +func prepareMap(prefix string, m interface{}) (url.Values, error) { + value := url.Values{} + v := reflect.ValueOf(m) + + for i, key := range v.MapKeys() { + var keyName string + var keyValue string + + switch key.Kind() { + case reflect.String: + keyName = key.String() + default: + return value, fmt.Errorf("only map[string]string are supported (XXX)") + } + + val := v.MapIndex(key) + switch val.Kind() { + case reflect.String: + keyValue = val.String() + default: + return value, fmt.Errorf("only map[string]string are supported (XXX)") + } + + value.Set(fmt.Sprintf("%s[%d].%s", prefix, i, keyName), keyValue) + } + + return value, nil +} + +func preparePtr(kind reflect.Kind, val reflect.Value, required bool) (*string, error) { + if val.IsNil() { + if required { + return nil, fmt.Errorf("field is required, got empty ptr") + } + return nil, nil + } + + switch kind { + case reflect.Bool: + return prepareBool(val.Elem().Bool(), true) + case reflect.Struct: + return prepareStruct(val.Interface(), required) + default: + return nil, fmt.Errorf("kind %v is not supported as a ptr", kind) + } +} + +func prepareSlice(name string, fieldType reflect.Type, val reflect.Value, required bool) (interface{}, error) { + switch fieldType.Elem().Kind() { + case reflect.Uint8: + switch fieldType { + case reflect.TypeOf(net.IPv4zero): + ip := (net.IP)(val.Bytes()) + if ip == nil || ip.Equal(net.IP{}) { + if required { + return nil, fmt.Errorf("field is required, got zero IPv4 address") + } + } else { + value := ip.String() + return &value, nil + } + + case reflect.TypeOf(MAC48(0, 0, 0, 0, 0, 0)): + mac := val.Interface().(MACAddress) + s := mac.String() + if s == "" { + if required { + return nil, fmt.Errorf("field is required, got empty MAC address") + } + } else { + return &s, nil + } + default: + if val.Len() == 0 { + if required { + return nil, fmt.Errorf("field is required, got empty slice") + } + } else { + value := base64.StdEncoding.EncodeToString(val.Bytes()) + return &value, nil + } + } + case reflect.String: + if val.Len() == 0 { + if required { + return nil, fmt.Errorf("field is required, got empty slice") + } + } else { + elems := make([]string, 0, val.Len()) + for i := 0; i < val.Len(); i++ { + // XXX what if the value contains a comma? Double encode? + s := val.Index(i).String() + elems = append(elems, s) + } + value := strings.Join(elems, ",") + return &value, nil + } + default: + switch fieldType.Elem() { + case reflect.TypeOf(CIDR{}), reflect.TypeOf(UUID{}): + if val.Len() == 0 { + if required { + return nil, fmt.Errorf("field is required, got empty slice") + } + } else { + v := reflect.ValueOf(val.Interface()) + ss := make([]string, val.Len()) + for i := 0; i < v.Len(); i++ { + e := v.Index(i).Interface() + s, ok := e.(fmt.Stringer) + if !ok { + return nil, fmt.Errorf("not a String, %T", e) + } + ss[i] = s.String() + } + value := strings.Join(ss, ",") + return &value, nil + } + default: + if val.Len() == 0 { + if required { + return nil, fmt.Errorf("field is required, got empty slice") + } + } else { + return prepareList(name, val.Interface()) + } + } + } + + return nil, nil +} + +func prepareStruct(i interface{}, required bool) (*string, error) { + s, ok := i.(fmt.Stringer) + if !ok { + return nil, fmt.Errorf("struct field not a Stringer") + } + + if s == nil { + if required { + return nil, fmt.Errorf("field is required, got %#v", s) + } + } + + return prepareString(s.String(), required) +} + +func prepareEmbedStruct(i interface{}) (url.Values, error) { + return prepareValues("", i) +} + +// ExtractJSONTag returns the variable name or defaultName as well as if the field is required (!omitempty) +func ExtractJSONTag(defaultName, jsonTag string) (string, bool) { + tags := strings.Split(jsonTag, ",") + name := tags[0] + required := true + for _, tag := range tags { + if tag == "omitempty" { + required = false + } + } + + if name == "" || name == "omitempty" { + name = defaultName + } + return name, required +} diff --git a/vendor/github.com/exoscale/egoscale/service_offerings.go b/vendor/github.com/exoscale/egoscale/service_offerings.go new file mode 100644 index 000000000..8d3551467 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/service_offerings.go @@ -0,0 +1,77 @@ +package egoscale + +// ServiceOffering corresponds to the Compute Offerings +// +// A service offering correspond to some hardware features (CPU, RAM). +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/latest/service_offerings.html +type ServiceOffering struct { + Authorized bool `json:"authorized,omitempty" doc:"is the account/domain authorized to use this service offering"` + CPUNumber int `json:"cpunumber,omitempty" doc:"the number of CPU"` + CPUSpeed int `json:"cpuspeed,omitempty" doc:"the clock rate CPU speed in Mhz"` + Created string `json:"created,omitempty" doc:"the date this service offering was created"` + DefaultUse bool `json:"defaultuse,omitempty" doc:"is this a default system vm offering"` + DeploymentPlanner string `json:"deploymentplanner,omitempty" doc:"deployment strategy used to deploy VM."` + DiskBytesReadRate int64 `json:"diskBytesReadRate,omitempty" doc:"bytes read rate of the service offering"` + DiskBytesWriteRate int64 `json:"diskBytesWriteRate,omitempty" doc:"bytes write rate of the service offering"` + DiskIopsReadRate int64 `json:"diskIopsReadRate,omitempty" doc:"io requests read rate of the service offering"` + DiskIopsWriteRate int64 `json:"diskIopsWriteRate,omitempty" doc:"io requests write rate of the service offering"` + Displaytext string `json:"displaytext,omitempty" doc:"an alternate display text of the service offering."` + HostTags string `json:"hosttags,omitempty" doc:"the host tag for the service offering"` + HypervisorSnapshotReserve int `json:"hypervisorsnapshotreserve,omitempty" doc:"Hypervisor snapshot reserve space as a percent of a volume (for managed storage using Xen or VMware)"` + ID *UUID `json:"id" doc:"the id of the service offering"` + IsCustomized bool `json:"iscustomized,omitempty" doc:"is true if the offering is customized"` + IsCustomizedIops bool `json:"iscustomizediops,omitempty" doc:"true if disk offering uses custom iops, false otherwise"` + IsSystem bool `json:"issystem,omitempty" doc:"is this a system vm offering"` + IsVolatile bool `json:"isvolatile,omitempty" doc:"true if the vm needs to be volatile, i.e., on every reboot of vm from API root disk is discarded and creates a new root disk"` + LimitCPUUse bool `json:"limitcpuuse,omitempty" doc:"restrict the CPU usage to committed service offering"` + MaxIops int64 `json:"maxiops,omitempty" doc:"the max iops of the disk offering"` + Memory int `json:"memory,omitempty" doc:"the memory in MB"` + MinIops int64 `json:"miniops,omitempty" doc:"the min iops of the disk offering"` + Name string `json:"name,omitempty" doc:"the name of the service offering"` + NetworkRate int `json:"networkrate,omitempty" doc:"data transfer rate in megabits per second allowed."` + OfferHA bool `json:"offerha,omitempty" doc:"the ha support in the service offering"` + Restricted bool `json:"restricted,omitempty" doc:"is this offering restricted"` + ServiceOfferingDetails map[string]string `json:"serviceofferingdetails,omitempty" doc:"additional key/value details tied with this service offering"` + StorageType string `json:"storagetype,omitempty" doc:"the storage type for this service offering"` + SystemVMType string `json:"systemvmtype,omitempty" doc:"is this a the systemvm type for system vm offering"` + Tags string `json:"tags,omitempty" doc:"the tags for the service offering"` +} + +// ListRequest builds the ListSecurityGroups request +func (so ServiceOffering) ListRequest() (ListCommand, error) { + // Restricted cannot be applied here because it really has three states + req := &ListServiceOfferings{ + ID: so.ID, + Name: so.Name, + SystemVMType: so.SystemVMType, + } + + if so.IsSystem { + req.IsSystem = &so.IsSystem + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListServiceOfferings + +// ListServiceOfferings represents a query for service offerings +type ListServiceOfferings struct { + ID *UUID `json:"id,omitempty" doc:"ID of the service offering"` + IsSystem *bool `json:"issystem,omitempty" doc:"is this a system vm offering"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"name of the service offering"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + Restricted *bool `json:"restricted,omitempty" doc:"filter by the restriction flag: true to list only the restricted service offerings, false to list non-restricted service offerings, or nothing for all."` + SystemVMType string `json:"systemvmtype,omitempty" doc:"the system VM type. Possible types are \"consoleproxy\", \"secondarystoragevm\" or \"domainrouter\"."` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"the ID of the virtual machine. Pass this in if you want to see the available service offering that a virtual machine can be changed to."` + _ bool `name:"listServiceOfferings" description:"Lists all available service offerings."` +} + +// ListServiceOfferingsResponse represents a list of service offerings +type ListServiceOfferingsResponse struct { + Count int `json:"count"` + ServiceOffering []ServiceOffering `json:"serviceoffering"` +} diff --git a/vendor/github.com/exoscale/egoscale/serviceofferings_response.go b/vendor/github.com/exoscale/egoscale/serviceofferings_response.go new file mode 100644 index 000000000..a01d4aaf4 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/serviceofferings_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListServiceOfferings) Response() interface{} { + return new(ListServiceOfferingsResponse) +} + +// ListRequest returns itself +func (ls *ListServiceOfferings) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListServiceOfferings) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListServiceOfferings) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListServiceOfferings) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListServiceOfferingsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListServiceOfferingsResponse was expected, got %T", resp)) + return + } + + for i := range items.ServiceOffering { + if !callback(&items.ServiceOffering[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/snapshots.go b/vendor/github.com/exoscale/egoscale/snapshots.go new file mode 100644 index 000000000..191f4a0f7 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/snapshots.go @@ -0,0 +1,139 @@ +package egoscale + +// SnapshotState represents the Snapshot.State enum +// +// See: https://github.com/apache/cloudstack/blob/master/api/src/main/java/com/cloud/storage/Snapshot.java +type SnapshotState string + +const ( + // Allocated ... (TODO) + Allocated SnapshotState = "Allocated" + // Creating ... (TODO) + Creating SnapshotState = "Creating" + // CreatedOnPrimary ... (TODO) + CreatedOnPrimary SnapshotState = "CreatedOnPrimary" + // BackingUp ... (TODO) + BackingUp SnapshotState = "BackingUp" + // BackedUp ... (TODO) + BackedUp SnapshotState = "BackedUp" + // Copying ... (TODO) + Copying SnapshotState = "Copying" + // Destroying ... (TODO) + Destroying SnapshotState = "Destroying" + // Destroyed ... (TODO) + Destroyed SnapshotState = "Destroyed" + // Error is a state where the user can't see the snapshot while the snapshot may still exist on the storage + Error SnapshotState = "Error" +) + +// Snapshot represents a volume snapshot +type Snapshot struct { + Account string `json:"account,omitempty" doc:"the account associated with the snapshot"` + AccountID *UUID `json:"accountid,omitempty" doc:"the account ID associated with the snapshot"` + Created string `json:"created,omitempty" doc:"the date the snapshot was created"` + ID *UUID `json:"id,omitempty" doc:"ID of the snapshot"` + IntervalType string `json:"intervaltype,omitempty" doc:"valid types are hourly, daily, weekly, monthy, template, and none."` + Name string `json:"name,omitempty" doc:"name of the snapshot"` + PhysicalSize int64 `json:"physicalsize,omitempty" doc:"physical size of the snapshot on image store"` + Revertable *bool `json:"revertable,omitempty" doc:"indicates whether the underlying storage supports reverting the volume to this snapshot"` + Size int64 `json:"size,omitempty" doc:"the size of original volume"` + SnapshotType string `json:"snapshottype,omitempty" doc:"the type of the snapshot"` + State string `json:"state,omitempty" doc:"the state of the snapshot. BackedUp means that snapshot is ready to be used; Creating - the snapshot is being allocated on the primary storage; BackingUp - the snapshot is being backed up on secondary storage"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with snapshot"` + VolumeID *UUID `json:"volumeid,omitempty" doc:"ID of the disk volume"` + VolumeName string `json:"volumename,omitempty" doc:"name of the disk volume"` + VolumeType string `json:"volumetype,omitempty" doc:"type of the disk volume"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"id of the availability zone"` +} + +// ResourceType returns the type of the resource +func (Snapshot) ResourceType() string { + return "Snapshot" +} + +// CreateSnapshot (Async) creates an instant snapshot of a volume +type CreateSnapshot struct { + VolumeID *UUID `json:"volumeid" doc:"The ID of the disk volume"` + QuiesceVM *bool `json:"quiescevm,omitempty" doc:"quiesce vm if true"` + _ bool `name:"createSnapshot" description:"Creates an instant snapshot of a volume."` +} + +// Response returns the struct to unmarshal +func (CreateSnapshot) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (CreateSnapshot) AsyncResponse() interface{} { + return new(Snapshot) +} + +// ListRequest builds the ListSnapshot request +func (ss Snapshot) ListRequest() (ListCommand, error) { + // Restricted cannot be applied here because it really has three states + req := &ListSnapshots{ + ID: ss.ID, + Name: ss.Name, + VolumeID: ss.VolumeID, + SnapshotType: ss.SnapshotType, + ZoneID: ss.ZoneID, + // TODO: tags + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListSnapshots + +// ListSnapshots lists the volume snapshots +type ListSnapshots struct { + ID *UUID `json:"id,omitempty" doc:"lists snapshot by snapshot ID"` + IntervalType string `json:"intervaltype,omitempty" doc:"valid values are HOURLY, DAILY, WEEKLY, and MONTHLY."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"lists snapshot by snapshot name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + SnapshotType string `json:"snapshottype,omitempty" doc:"valid values are MANUAL or RECURRING."` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + VolumeID *UUID `json:"volumeid,omitempty" doc:"the ID of the disk volume"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"list snapshots by zone id"` + _ bool `name:"listSnapshots" description:"Lists all available snapshots for the account."` +} + +// ListSnapshotsResponse represents a list of volume snapshots +type ListSnapshotsResponse struct { + Count int `json:"count"` + Snapshot []Snapshot `json:"snapshot"` +} + +// DeleteSnapshot (Async) deletes a snapshot of a disk volume +type DeleteSnapshot struct { + ID *UUID `json:"id" doc:"The ID of the snapshot"` + _ bool `name:"deleteSnapshot" description:"Deletes a snapshot of a disk volume."` +} + +// Response returns the struct to unmarshal +func (DeleteSnapshot) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DeleteSnapshot) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +// RevertSnapshot (Async) reverts a volume snapshot +type RevertSnapshot struct { + ID *UUID `json:"id" doc:"The ID of the snapshot"` + _ bool `name:"revertSnapshot" description:"revert a volume snapshot."` +} + +// Response returns the struct to unmarshal +func (RevertSnapshot) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RevertSnapshot) AsyncResponse() interface{} { + return new(BooleanResponse) +} diff --git a/vendor/github.com/exoscale/egoscale/snapshots_response.go b/vendor/github.com/exoscale/egoscale/snapshots_response.go new file mode 100644 index 000000000..2ca9cff5a --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/snapshots_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListSnapshots) Response() interface{} { + return new(ListSnapshotsResponse) +} + +// ListRequest returns itself +func (ls *ListSnapshots) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListSnapshots) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListSnapshots) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListSnapshots) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListSnapshotsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListSnapshotsResponse was expected, got %T", resp)) + return + } + + for i := range items.Snapshot { + if !callback(&items.Snapshot[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/ssh_keypairs.go b/vendor/github.com/exoscale/egoscale/ssh_keypairs.go new file mode 100644 index 000000000..9f2bedca0 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/ssh_keypairs.go @@ -0,0 +1,105 @@ +package egoscale + +import ( + "context" + "fmt" +) + +// SSHKeyPair represents an SSH key pair +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html#creating-the-ssh-keypair +type SSHKeyPair struct { + Fingerprint string `json:"fingerprint,omitempty" doc:"Fingerprint of the public key"` + Name string `json:"name,omitempty" doc:"Name of the keypair"` + PrivateKey string `json:"privatekey,omitempty" doc:"Private key"` +} + +// Delete removes the given SSH key, by Name +func (ssh SSHKeyPair) Delete(ctx context.Context, client *Client) error { + if ssh.Name == "" { + return fmt.Errorf("an SSH Key Pair may only be deleted using Name") + } + + return client.BooleanRequestWithContext(ctx, &DeleteSSHKeyPair{ + Name: ssh.Name, + }) +} + +// ListRequest builds the ListSSHKeyPairs request +func (ssh SSHKeyPair) ListRequest() (ListCommand, error) { + req := &ListSSHKeyPairs{ + Fingerprint: ssh.Fingerprint, + Name: ssh.Name, + } + + return req, nil +} + +// CreateSSHKeyPair represents a new keypair to be created +type CreateSSHKeyPair struct { + Name string `json:"name" doc:"Name of the keypair"` + _ bool `name:"createSSHKeyPair" description:"Create a new keypair and returns the private key"` +} + +// Response returns the struct to unmarshal +func (CreateSSHKeyPair) Response() interface{} { + return new(SSHKeyPair) +} + +// DeleteSSHKeyPair represents a new keypair to be created +type DeleteSSHKeyPair struct { + Name string `json:"name" doc:"Name of the keypair"` + _ bool `name:"deleteSSHKeyPair" description:"Deletes a keypair by name"` +} + +// Response returns the struct to unmarshal +func (DeleteSSHKeyPair) Response() interface{} { + return new(BooleanResponse) +} + +// RegisterSSHKeyPair represents a new registration of a public key in a keypair +type RegisterSSHKeyPair struct { + Name string `json:"name" doc:"Name of the keypair"` + PublicKey string `json:"publickey" doc:"Public key material of the keypair"` + _ bool `name:"registerSSHKeyPair" description:"Register a public key in a keypair under a certain name"` +} + +// Response returns the struct to unmarshal +func (RegisterSSHKeyPair) Response() interface{} { + return new(SSHKeyPair) +} + +//go:generate go run generate/main.go -interface=Listable ListSSHKeyPairs + +// ListSSHKeyPairs represents a query for a list of SSH KeyPairs +type ListSSHKeyPairs struct { + Fingerprint string `json:"fingerprint,omitempty" doc:"A public key fingerprint to look for"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"A key pair name to look for"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + _ bool `name:"listSSHKeyPairs" description:"List registered keypairs"` +} + +// ListSSHKeyPairsResponse represents a list of SSH key pairs +type ListSSHKeyPairsResponse struct { + Count int `json:"count"` + SSHKeyPair []SSHKeyPair `json:"sshkeypair"` +} + +// ResetSSHKeyForVirtualMachine (Async) represents a change for the key pairs +type ResetSSHKeyForVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + KeyPair string `json:"keypair" doc:"Name of the ssh key pair used to login to the virtual machine"` + _ bool `name:"resetSSHKeyForVirtualMachine" description:"Resets the SSH Key for virtual machine. The virtual machine must be in a \"Stopped\" state."` +} + +// Response returns the struct to unmarshal +func (ResetSSHKeyForVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (ResetSSHKeyForVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} diff --git a/vendor/github.com/exoscale/egoscale/sshkeypairs_response.go b/vendor/github.com/exoscale/egoscale/sshkeypairs_response.go new file mode 100644 index 000000000..31c471df2 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/sshkeypairs_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListSSHKeyPairs) Response() interface{} { + return new(ListSSHKeyPairsResponse) +} + +// ListRequest returns itself +func (ls *ListSSHKeyPairs) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListSSHKeyPairs) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListSSHKeyPairs) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListSSHKeyPairs) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListSSHKeyPairsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListSSHKeyPairsResponse was expected, got %T", resp)) + return + } + + for i := range items.SSHKeyPair { + if !callback(&items.SSHKeyPair[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/tags.go b/vendor/github.com/exoscale/egoscale/tags.go new file mode 100644 index 000000000..56e014850 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/tags.go @@ -0,0 +1,84 @@ +package egoscale + +// ResourceTag is a tag associated with a resource +// +// https://community.exoscale.com/documentation/compute/instance-tags/ +type ResourceTag struct { + Account string `json:"account,omitempty" doc:"the account associated with the tag"` + Customer string `json:"customer,omitempty" doc:"customer associated with the tag"` + Key string `json:"key,omitempty" doc:"tag key name"` + ResourceID *UUID `json:"resourceid,omitempty" doc:"id of the resource"` + ResourceType string `json:"resourcetype,omitempty" doc:"resource type"` + Value string `json:"value,omitempty" doc:"tag value"` +} + +// ListRequest builds the ListZones request +func (tag ResourceTag) ListRequest() (ListCommand, error) { + req := &ListTags{ + Customer: tag.Customer, + Key: tag.Key, + ResourceID: tag.ResourceID, + ResourceType: tag.ResourceType, + Value: tag.Value, + } + + return req, nil +} + +// CreateTags (Async) creates resource tag(s) +type CreateTags struct { + ResourceIDs []UUID `json:"resourceids" doc:"list of resources to create the tags for"` + ResourceType string `json:"resourcetype" doc:"type of the resource"` + Tags []ResourceTag `json:"tags" doc:"Map of tags (key/value pairs)"` + Customer string `json:"customer,omitempty" doc:"identifies client specific tag. When the value is not null, the tag can't be used by cloudStack code internally"` + _ bool `name:"createTags" description:"Creates resource tag(s)"` +} + +// Response returns the struct to unmarshal +func (CreateTags) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (CreateTags) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +// DeleteTags (Async) deletes the resource tag(s) +type DeleteTags struct { + ResourceIDs []UUID `json:"resourceids" doc:"Delete tags for resource id(s)"` + ResourceType string `json:"resourcetype" doc:"Delete tag by resource type"` + Tags []ResourceTag `json:"tags,omitempty" doc:"Delete tags matching key/value pairs"` + _ bool `name:"deleteTags" description:"Deleting resource tag(s)"` +} + +// Response returns the struct to unmarshal +func (DeleteTags) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DeleteTags) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +//go:generate go run generate/main.go -interface=Listable ListTags + +// ListTags list resource tag(s) +type ListTags struct { + Customer string `json:"customer,omitempty" doc:"list by customer name"` + Key string `json:"key,omitempty" doc:"list by key"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ResourceID *UUID `json:"resourceid,omitempty" doc:"list by resource id"` + ResourceType string `json:"resourcetype,omitempty" doc:"list by resource type"` + Value string `json:"value,omitempty" doc:"list by value"` + _ bool `name:"listTags" description:"List resource tag(s)"` +} + +// ListTagsResponse represents a list of resource tags +type ListTagsResponse struct { + Count int `json:"count"` + Tag []ResourceTag `json:"tag"` +} diff --git a/vendor/github.com/exoscale/egoscale/tags_response.go b/vendor/github.com/exoscale/egoscale/tags_response.go new file mode 100644 index 000000000..870ef49a8 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/tags_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListTags) Response() interface{} { + return new(ListTagsResponse) +} + +// ListRequest returns itself +func (ls *ListTags) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListTags) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListTags) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListTags) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListTagsResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListTagsResponse was expected, got %T", resp)) + return + } + + for i := range items.Tag { + if !callback(&items.Tag[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/templates.go b/vendor/github.com/exoscale/egoscale/templates.go new file mode 100644 index 000000000..9f49369d2 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/templates.go @@ -0,0 +1,163 @@ +package egoscale + +// Template represents a machine to be deployed. +type Template struct { + Account string `json:"account,omitempty" doc:"the account name to which the template belongs"` + AccountID *UUID `json:"accountid,omitempty" doc:"the account id to which the template belongs"` + Bootable bool `json:"bootable,omitempty" doc:"true if the ISO is bootable, false otherwise"` + Checksum string `json:"checksum,omitempty" doc:"checksum of the template"` + Created string `json:"created,omitempty" doc:"the date this template was created"` + CrossZones bool `json:"crossZones,omitempty" doc:"true if the template is managed across all Zones, false otherwise"` + Details map[string]string `json:"details,omitempty" doc:"additional key/value details tied with template"` + DisplayText string `json:"displaytext,omitempty" doc:"the template display text"` + Format string `json:"format,omitempty" doc:"the format of the template."` + HostID *UUID `json:"hostid,omitempty" doc:"the ID of the secondary storage host for the template"` + HostName string `json:"hostname,omitempty" doc:"the name of the secondary storage host for the template"` + Hypervisor string `json:"hypervisor,omitempty" doc:"the target hypervisor for the template"` + ID *UUID `json:"id,omitempty" doc:"the template ID"` + IsDynamicallyScalable bool `json:"isdynamicallyscalable,omitempty" doc:"true if template contains XS/VMWare tools inorder to support dynamic scaling of VM cpu/memory"` + IsExtractable bool `json:"isextractable,omitempty" doc:"true if the template is extractable, false otherwise"` + IsFeatured bool `json:"isfeatured,omitempty" doc:"true if this template is a featured template, false otherwise"` + IsPublic bool `json:"ispublic,omitempty" doc:"true if this template is a public template, false otherwise"` + IsReady bool `json:"isready,omitempty" doc:"true if the template is ready to be deployed from, false otherwise."` + Name string `json:"name,omitempty" doc:"the template name"` + OsCategoryID *UUID `json:"oscategoryid,omitempty" doc:"the ID of the OS category for this template"` + OsCategoryName string `json:"oscategoryname,omitempty" doc:"the name of the OS category for this template"` + OsTypeID *UUID `json:"ostypeid,omitempty" doc:"the ID of the OS type for this template"` + OsTypeName string `json:"ostypename,omitempty" doc:"the name of the OS type for this template"` + PasswordEnabled bool `json:"passwordenabled,omitempty" doc:"true if the reset password feature is enabled, false otherwise"` + Removed string `json:"removed,omitempty" doc:"the date this template was removed"` + Size int64 `json:"size,omitempty" doc:"the size of the template"` + SourceTemplateID *UUID `json:"sourcetemplateid,omitempty" doc:"the template ID of the parent template if present"` + SSHKeyEnabled bool `json:"sshkeyenabled,omitempty" doc:"true if template is sshkey enabled, false otherwise"` + Status string `json:"status,omitempty" doc:"the status of the template"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with tempate"` + TemplateDirectory string `json:"templatedirectory,omitempty" doc:"Template directory"` + TemplateTag string `json:"templatetag,omitempty" doc:"the tag of this template"` + TemplateType string `json:"templatetype,omitempty" doc:"the type of the template"` + URL string `json:"url,omitempty" doc:"Original URL of the template where it was downloaded"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"the ID of the zone for this template"` + ZoneName string `json:"zonename,omitempty" doc:"the name of the zone for this template"` +} + +// ResourceType returns the type of the resource +func (Template) ResourceType() string { + return "Template" +} + +// ListRequest builds the ListTemplates request +func (template Template) ListRequest() (ListCommand, error) { + req := &ListTemplates{ + ID: template.ID, + Name: template.Name, + ZoneID: template.ZoneID, + } + if template.IsFeatured { + req.TemplateFilter = "featured" + } + if template.Removed != "" { + *req.ShowRemoved = true + } + + for i := range template.Tags { + req.Tags = append(req.Tags, template.Tags[i]) + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListTemplates + +// ListTemplates represents a template query filter +type ListTemplates struct { + TemplateFilter string `json:"templatefilter" doc:"Possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". * featured : templates that have been marked as featured and public. * self : templates that have been registered or created by the calling user. * selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. * sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. * executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. * community : templates that have been marked as public but not featured."` + ID *UUID `json:"id,omitempty" doc:"the template ID"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"the template name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ShowRemoved *bool `json:"showremoved,omitempty" doc:"Show removed templates as well"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"list templates by zoneid"` + _ bool `name:"listTemplates" description:"List all public, private, and privileged templates."` +} + +// ListTemplatesResponse represents a list of templates +type ListTemplatesResponse struct { + Count int `json:"count"` + Template []Template `json:"template"` +} + +// OSCategory represents an OS category +type OSCategory struct { + ID *UUID `json:"id,omitempty" doc:"the ID of the OS category"` + Name string `json:"name,omitempty" doc:"the name of the OS category"` +} + +// ListRequest builds the ListOSCategories request +func (osCat OSCategory) ListRequest() (ListCommand, error) { + req := &ListOSCategories{ + Name: osCat.Name, + ID: osCat.ID, + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListOSCategories + +// ListOSCategories lists the OS categories +type ListOSCategories struct { + ID *UUID `json:"id,omitempty" doc:"list Os category by id"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"list os category by name"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + _ bool `name:"listOsCategories" description:"Lists all supported OS categories for this cloud."` +} + +// ListOSCategoriesResponse represents a list of OS categories +type ListOSCategoriesResponse struct { + Count int `json:"count"` + OSCategory []OSCategory `json:"oscategory"` +} + +// DeleteTemplate deletes a template by ID +type DeleteTemplate struct { + _ bool `name:"deleteTemplate" description:"Deletes a template"` + ID *UUID `json:"id" doc:"the ID of the template"` +} + +// Response returns the struct to unmarshal +func (DeleteTemplate) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DeleteTemplate) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +// RegisterCustomTemplate registers a new template +type RegisterCustomTemplate struct { + _ bool `name:"registerCustomTemplate" description:"Register a new template."` + Checksum string `json:"checksum" doc:"the MD5 checksum value of this template"` + Details map[string]string `json:"details,omitempty" doc:"Template details in key/value pairs"` + Displaytext string `json:"displaytext" doc:"the display text of the template"` + Name string `json:"name" doc:"the name of the template"` + PasswordEnabled *bool `json:"passwordenabled,omitempty" doc:"true if the template supports the password reset feature; default is false"` + SSHKeyEnabled *bool `json:"sshkeyenabled,omitempty" doc:"true if the template supports the sshkey upload feature; default is false"` + TemplateTag string `json:"templatetag,omitempty" doc:"the tag for this template"` + URL string `json:"url" doc:"the URL of where the template is hosted"` + ZoneID *UUID `json:"zoneid" doc:"the ID of the zone the template is to be hosted on"` +} + +// Response returns the struct to unmarshal +func (RegisterCustomTemplate) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RegisterCustomTemplate) AsyncResponse() interface{} { + return new([]Template) +} diff --git a/vendor/github.com/exoscale/egoscale/templates_response.go b/vendor/github.com/exoscale/egoscale/templates_response.go new file mode 100644 index 000000000..b9d61b546 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/templates_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListTemplates) Response() interface{} { + return new(ListTemplatesResponse) +} + +// ListRequest returns itself +func (ls *ListTemplates) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListTemplates) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListTemplates) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListTemplates) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListTemplatesResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListTemplatesResponse was expected, got %T", resp)) + return + } + + for i := range items.Template { + if !callback(&items.Template[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/users.go b/vendor/github.com/exoscale/egoscale/users.go new file mode 100644 index 000000000..71078a97b --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/users.go @@ -0,0 +1,63 @@ +package egoscale + +// User represents a User +type User struct { + APIKey string `json:"apikey,omitempty" doc:"the api key of the user"` + Account string `json:"account,omitempty" doc:"the account name of the user"` + AccountID *UUID `json:"accountid,omitempty" doc:"the account ID of the user"` + Created string `json:"created,omitempty" doc:"the date and time the user account was created"` + Email string `json:"email,omitempty" doc:"the user email address"` + FirstName string `json:"firstname,omitempty" doc:"the user firstname"` + ID *UUID `json:"id,omitempty" doc:"the user ID"` + IsDefault bool `json:"isdefault,omitempty" doc:"true if user is default, false otherwise"` + LastName string `json:"lastname,omitempty" doc:"the user lastname"` + RoleID *UUID `json:"roleid,omitempty" doc:"the ID of the role"` + RoleName string `json:"rolename,omitempty" doc:"the name of the role"` + RoleType string `json:"roletype,omitempty" doc:"the type of the role"` + SecretKey string `json:"secretkey,omitempty" doc:"the secret key of the user"` + State string `json:"state,omitempty" doc:"the user state"` + Timezone string `json:"timezone,omitempty" doc:"the timezone user was created in"` + UserName string `json:"username,omitempty" doc:"the user name"` +} + +// ListRequest builds the ListUsers request +func (user User) ListRequest() (ListCommand, error) { + req := &ListUsers{ + ID: user.ID, + UserName: user.UserName, + } + + return req, nil +} + +// RegisterUserKeys registers a new set of key of the given user +// +// NB: only the APIKey and SecretKey will be filled +type RegisterUserKeys struct { + ID *UUID `json:"id" doc:"User id"` + _ bool `name:"registerUserKeys" description:"This command allows a user to register for the developer API, returning a secret key and an API key. This request is made through the integration API port, so it is a privileged command and must be made on behalf of a user. It is up to the implementer just how the username and password are entered, and then how that translates to an integration API request. Both secret key and API key should be returned to the user"` +} + +// Response returns the struct to unmarshal +func (RegisterUserKeys) Response() interface{} { + return new(User) +} + +//go:generate go run generate/main.go -interface=Listable ListUsers + +// ListUsers represents the search for Users +type ListUsers struct { + ID *UUID `json:"id,omitempty" doc:"List user by ID."` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + State string `json:"state,omitempty" doc:"List users by state of the user account."` + UserName string `json:"username,omitempty" doc:"List user by the username"` + _ bool `name:"listUsers" description:"Lists user accounts"` +} + +// ListUsersResponse represents a list of users +type ListUsersResponse struct { + Count int `json:"count"` + User []User `json:"user"` +} diff --git a/vendor/github.com/exoscale/egoscale/users_response.go b/vendor/github.com/exoscale/egoscale/users_response.go new file mode 100644 index 000000000..4bd4bf473 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/users_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListUsers) Response() interface{} { + return new(ListUsersResponse) +} + +// ListRequest returns itself +func (ls *ListUsers) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListUsers) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListUsers) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListUsers) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListUsersResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListUsersResponse was expected, got %T", resp)) + return + } + + for i := range items.User { + if !callback(&items.User[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/uuid.go b/vendor/github.com/exoscale/egoscale/uuid.go new file mode 100644 index 000000000..dd8be1557 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/uuid.go @@ -0,0 +1,79 @@ +package egoscale + +import ( + "encoding/json" + "fmt" + + uuid "github.com/gofrs/uuid" +) + +// UUID holds a UUID v4 +type UUID struct { + uuid.UUID +} + +// DeepCopy create a true copy of the receiver. +func (u *UUID) DeepCopy() *UUID { + if u == nil { + return nil + } + + out := [uuid.Size]byte{} + copy(out[:], u.Bytes()) + + return &UUID{ + (uuid.UUID)(out), + } +} + +// DeepCopyInto copies the receiver into out. +// +// In must be non nil. +func (u *UUID) DeepCopyInto(out *UUID) { + o := [uuid.Size]byte{} + copy(o[:], u.Bytes()) + + out.UUID = (uuid.UUID)(o) +} + +// Equal returns true if itself is equal to other. +func (u UUID) Equal(other UUID) bool { + return u == other +} + +// UnmarshalJSON unmarshals the raw JSON into the UUID. +func (u *UUID) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + + new, err := ParseUUID(s) + if err == nil { + u.UUID = new.UUID + } + return err +} + +// MarshalJSON converts the UUID to a string representation. +func (u UUID) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf("%q", u.String())), nil +} + +// ParseUUID parses a string into a UUID. +func ParseUUID(s string) (*UUID, error) { + u, err := uuid.FromString(s) + if err != nil { + return nil, err + } + return &UUID{u}, nil +} + +// MustParseUUID acts like ParseUUID but panic in case of a failure. +func MustParseUUID(s string) *UUID { + u, e := ParseUUID(s) + if e != nil { + panic(e) + } + return u +} diff --git a/vendor/github.com/exoscale/egoscale/version.go b/vendor/github.com/exoscale/egoscale/version.go new file mode 100644 index 000000000..d96946140 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/version.go @@ -0,0 +1,4 @@ +package egoscale + +// Version of the library +const Version = "0.18.1" diff --git a/vendor/github.com/exoscale/egoscale/virtual_machines.go b/vendor/github.com/exoscale/egoscale/virtual_machines.go new file mode 100644 index 000000000..da6ce65c5 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/virtual_machines.go @@ -0,0 +1,613 @@ +package egoscale + +import ( + "bytes" + "compress/gzip" + "context" + "encoding/base64" + "fmt" + "io/ioutil" + "net" + "net/url" +) + +// VirtualMachineState holds the state of the instance +// +// https://github.com/apache/cloudstack/blob/master/api/src/main/java/com/cloud/vm/VirtualMachine.java +type VirtualMachineState string + +const ( + // VirtualMachineStarting VM is being started. At this state, you should find host id filled which means it's being started on that host + VirtualMachineStarting VirtualMachineState = "Starting" + // VirtualMachineRunning VM is running. host id has the host that it is running on + VirtualMachineRunning VirtualMachineState = "Running" + // VirtualMachineStopping VM is being stopped. host id has the host that it is being stopped on + VirtualMachineStopping VirtualMachineState = "Stopping" + // VirtualMachineStopped VM is stopped. host id should be null + VirtualMachineStopped VirtualMachineState = "Stopped" + // VirtualMachineDestroyed VM is marked for destroy + VirtualMachineDestroyed VirtualMachineState = "Destroyed" + // VirtualMachineExpunging "VM is being expunged + VirtualMachineExpunging VirtualMachineState = "Expunging" + // VirtualMachineMigrating VM is being live migrated. host id holds destination host, last host id holds source host + VirtualMachineMigrating VirtualMachineState = "Migrating" + // VirtualMachineMoving VM is being migrated offline (volume is being moved). + VirtualMachineMoving VirtualMachineState = "Moving" + // VirtualMachineError VM is in error + VirtualMachineError VirtualMachineState = "Error" + // VirtualMachineUnknown VM state is unknown + VirtualMachineUnknown VirtualMachineState = "Unknown" + // VirtualMachineShutdowned VM is shutdowned from inside + VirtualMachineShutdowned VirtualMachineState = "Shutdowned" +) + +// VirtualMachine represents a virtual machine +// +// See: http://docs.cloudstack.apache.org/projects/cloudstack-administration/en/stable/virtual_machines.html +type VirtualMachine struct { + Account string `json:"account,omitempty" doc:"the account associated with the virtual machine"` + AccountID *UUID `json:"accountid,omitempty" doc:"the account ID associated with the virtual machine"` + AffinityGroup []AffinityGroup `json:"affinitygroup,omitempty" doc:"list of affinity groups associated with the virtual machine"` + ClusterID *UUID `json:"clusterid,omitempty" doc:"the ID of the vm's cluster"` + ClusterName string `json:"clustername,omitempty" doc:"the name of the vm's cluster"` + CPUNumber int `json:"cpunumber,omitempty" doc:"the number of cpu this virtual machine is running with"` + CPUSpeed int `json:"cpuspeed,omitempty" doc:"the speed of each cpu"` + CPUUsed string `json:"cpuused,omitempty" doc:"the amount of the vm's CPU currently used"` + Created string `json:"created,omitempty" doc:"the date when this virtual machine was created"` + Details map[string]string `json:"details,omitempty" doc:"Vm details in key/value pairs."` + DiskIoRead int64 `json:"diskioread,omitempty" doc:"the read (io) of disk on the vm"` + DiskIoWrite int64 `json:"diskiowrite,omitempty" doc:"the write (io) of disk on the vm"` + DiskKbsRead int64 `json:"diskkbsread,omitempty" doc:"the read (bytes) of disk on the vm"` + DiskKbsWrite int64 `json:"diskkbswrite,omitempty" doc:"the write (bytes) of disk on the vm"` + DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"the ID of the disk offering of the virtual machine"` + DiskOfferingName string `json:"diskofferingname,omitempty" doc:"the name of the disk offering of the virtual machine"` + DisplayName string `json:"displayname,omitempty" doc:"user generated name. The name of the virtual machine is returned if no displayname exists."` + ForVirtualNetwork bool `json:"forvirtualnetwork,omitempty" doc:"the virtual network for the service offering"` + Group string `json:"group,omitempty" doc:"the group name of the virtual machine"` + GroupID *UUID `json:"groupid,omitempty" doc:"the group ID of the virtual machine"` + HAEnable bool `json:"haenable,omitempty" doc:"true if high-availability is enabled, false otherwise"` + HostName string `json:"hostname,omitempty" doc:"the name of the host for the virtual machine"` + ID *UUID `json:"id,omitempty" doc:"the ID of the virtual machine"` + InstanceName string `json:"instancename,omitempty" doc:"instance name of the user vm; this parameter is returned to the ROOT admin only"` + IsoDisplayText string `json:"isodisplaytext,omitempty" doc:"an alternate display text of the ISO attached to the virtual machine"` + IsoID *UUID `json:"isoid,omitempty" doc:"the ID of the ISO attached to the virtual machine"` + IsoName string `json:"isoname,omitempty" doc:"the name of the ISO attached to the virtual machine"` + KeyPair string `json:"keypair,omitempty" doc:"ssh key-pair"` + Memory int `json:"memory,omitempty" doc:"the memory allocated for the virtual machine"` + Name string `json:"name,omitempty" doc:"the name of the virtual machine"` + NetworkKbsRead int64 `json:"networkkbsread,omitempty" doc:"the incoming network traffic on the vm"` + NetworkKbsWrite int64 `json:"networkkbswrite,omitempty" doc:"the outgoing network traffic on the host"` + Nic []Nic `json:"nic,omitempty" doc:"the list of nics associated with vm"` + OSCategoryID *UUID `json:"oscategoryid,omitempty" doc:"Os category ID of the virtual machine"` + OSCategoryName string `json:"oscategoryname,omitempty" doc:"Os category name of the virtual machine"` + OSTypeID *UUID `json:"ostypeid,omitempty" doc:"OS type id of the vm"` + Password string `json:"password,omitempty" doc:"the password (if exists) of the virtual machine"` + PasswordEnabled bool `json:"passwordenabled,omitempty" doc:"true if the password rest feature is enabled, false otherwise"` + PCIDevices []PCIDevice `json:"pcidevices,omitempty" doc:"list of PCI devices"` + PodID *UUID `json:"podid,omitempty" doc:"the ID of the vm's pod"` + PodName string `json:"podname,omitempty" doc:"the name of the vm's pod"` + PublicIP string `json:"publicip,omitempty" doc:"public IP address id associated with vm via Static nat rule"` + PublicIPID *UUID `json:"publicipid,omitempty" doc:"public IP address id associated with vm via Static nat rule"` + RootDeviceID int64 `json:"rootdeviceid,omitempty" doc:"device ID of the root volume"` + RootDeviceType string `json:"rootdevicetype,omitempty" doc:"device type of the root volume"` + SecurityGroup []SecurityGroup `json:"securitygroup,omitempty" doc:"list of security groups associated with the virtual machine"` + ServiceOfferingID *UUID `json:"serviceofferingid,omitempty" doc:"the ID of the service offering of the virtual machine"` + ServiceOfferingName string `json:"serviceofferingname,omitempty" doc:"the name of the service offering of the virtual machine"` + ServiceState string `json:"servicestate,omitempty" doc:"State of the Service from LB rule"` + State string `json:"state,omitempty" doc:"the state of the virtual machine"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with vm"` + TemplateDisplayText string `json:"templatedisplaytext,omitempty" doc:"an alternate display text of the template for the virtual machine"` + TemplateID *UUID `json:"templateid,omitempty" doc:"the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file."` + TemplateName string `json:"templatename,omitempty" doc:"the name of the template for the virtual machine"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"the ID of the availablility zone for the virtual machine"` + ZoneName string `json:"zonename,omitempty" doc:"the name of the availability zone for the virtual machine"` +} + +// ResourceType returns the type of the resource +func (VirtualMachine) ResourceType() string { + return "UserVM" +} + +// Delete destroys the VM +func (vm VirtualMachine) Delete(ctx context.Context, client *Client) error { + _, err := client.RequestWithContext(ctx, &DestroyVirtualMachine{ + ID: vm.ID, + }) + + return err +} + +// ListRequest builds the ListVirtualMachines request +func (vm VirtualMachine) ListRequest() (ListCommand, error) { + // XXX: AffinityGroupID, SecurityGroupID + + req := &ListVirtualMachines{ + GroupID: vm.GroupID, + ID: vm.ID, + Name: vm.Name, + State: vm.State, + TemplateID: vm.TemplateID, + ZoneID: vm.ZoneID, + } + + nic := vm.DefaultNic() + if nic != nil { + req.IPAddress = nic.IPAddress + } + + for i := range vm.Tags { + req.Tags = append(req.Tags, vm.Tags[i]) + } + + return req, nil +} + +// DefaultNic returns the default nic +func (vm VirtualMachine) DefaultNic() *Nic { + for i, nic := range vm.Nic { + if nic.IsDefault { + return &vm.Nic[i] + } + } + + return nil +} + +// IP returns the default nic IP address +func (vm VirtualMachine) IP() *net.IP { + nic := vm.DefaultNic() + if nic != nil { + ip := nic.IPAddress + return &ip + } + + return nil +} + +// NicsByType returns the corresponding interfaces base on the given type +func (vm VirtualMachine) NicsByType(nicType string) []Nic { + nics := make([]Nic, 0) + for _, nic := range vm.Nic { + if nic.Type == nicType { + // XXX The API forgets to specify it + n := nic + n.VirtualMachineID = vm.ID + nics = append(nics, n) + } + } + return nics +} + +// NicByNetworkID returns the corresponding interface based on the given NetworkID +// +// A VM cannot be connected twice to a same network. +func (vm VirtualMachine) NicByNetworkID(networkID UUID) *Nic { + for _, nic := range vm.Nic { + if nic.NetworkID.Equal(networkID) { + n := nic + n.VirtualMachineID = vm.ID + return &n + } + } + return nil +} + +// NicByID returns the corresponding interface base on its ID +func (vm VirtualMachine) NicByID(nicID UUID) *Nic { + for _, nic := range vm.Nic { + if nic.ID.Equal(nicID) { + n := nic + n.VirtualMachineID = vm.ID + return &n + } + } + + return nil +} + +// IPToNetwork represents a mapping between ip and networks +type IPToNetwork struct { + IP net.IP `json:"ip,omitempty"` + Ipv6 net.IP `json:"ipv6,omitempty"` + NetworkID *UUID `json:"networkid,omitempty"` +} + +// PCIDevice represents a PCI card present in the host +type PCIDevice struct { + PCIVendorName string `json:"pcivendorname,omitempty" doc:"Device vendor name of pci card"` + DeviceID string `json:"deviceid,omitempty" doc:"Device model ID of pci card"` + RemainingCapacity int `json:"remainingcapacity,omitempty" doc:"Remaining capacity in terms of no. of more VMs that can be deployped with this vGPU type"` + MaxCapacity int `json:"maxcapacity,omitempty" doc:"Maximum vgpu can be created with this vgpu type on the given pci group"` + PCIVendorID string `json:"pcivendorid,omitempty" doc:"Device vendor ID of pci card"` + PCIDeviceName string `json:"pcidevicename,omitempty" doc:"Device model name of pci card"` +} + +// Password represents an encrypted password +// +// TODO: method to decrypt it, https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=34014652 +type Password struct { + EncryptedPassword string `json:"encryptedpassword"` +} + +// VirtualMachineUserData represents the base64 encoded user-data +type VirtualMachineUserData struct { + UserData string `json:"userdata" doc:"Base 64 encoded VM user data"` + VirtualMachineID *UUID `json:"virtualmachineid" doc:"the ID of the virtual machine"` +} + +// Decode decodes as a readable string the content of the user-data (base64 · gzip) +func (userdata VirtualMachineUserData) Decode() (string, error) { + data, err := base64.StdEncoding.DecodeString(userdata.UserData) + if err != nil { + return "", err + } + // 0x1f8b is the magic number for gzip + if len(data) < 2 || data[0] != 0x1f || data[1] != 0x8b { + return string(data), nil + } + gr, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return "", err + } + defer gr.Close() // nolint: errcheck + + str, err := ioutil.ReadAll(gr) + if err != nil { + return "", err + } + return string(str), nil +} + +// DeployVirtualMachine (Async) represents the machine creation +// +// Regarding the UserData field, the client is responsible to base64 (and probably gzip) it. Doing it within this library would make the integration with other tools, e.g. Terraform harder. +type DeployVirtualMachine struct { + AffinityGroupIDs []UUID `json:"affinitygroupids,omitempty" doc:"comma separated list of affinity groups id that are going to be applied to the virtual machine. Mutually exclusive with affinitygroupnames parameter"` + AffinityGroupNames []string `json:"affinitygroupnames,omitempty" doc:"comma separated list of affinity groups names that are going to be applied to the virtual machine.Mutually exclusive with affinitygroupids parameter"` + Details map[string]string `json:"details,omitempty" doc:"used to specify the custom parameters."` + DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"the ID of the disk offering for the virtual machine. If the template is of ISO format, the diskofferingid is for the root disk volume. Otherwise this parameter is used to indicate the offering for the data disk volume. If the templateid parameter passed is from a Template object, the diskofferingid refers to a DATA Disk Volume created. If the templateid parameter passed is from an ISO object, the diskofferingid refers to a ROOT Disk Volume created."` + DisplayName string `json:"displayname,omitempty" doc:"an optional user generated name for the virtual machine"` + Group string `json:"group,omitempty" doc:"an optional group for the virtual machine"` + IP4 *bool `json:"ip4,omitempty" doc:"True to set an IPv4 to the default interface"` + IP6 *bool `json:"ip6,omitempty" doc:"True to set an IPv6 to the default interface"` + IP6Address net.IP `json:"ip6address,omitempty" doc:"the ipv6 address for default vm's network"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"the ip address for default vm's network"` + Keyboard string `json:"keyboard,omitempty" doc:"an optional keyboard device type for the virtual machine. valid value can be one of de,de-ch,es,fi,fr,fr-be,fr-ch,is,it,jp,nl-be,no,pt,uk,us"` + KeyPair string `json:"keypair,omitempty" doc:"name of the ssh key pair used to login to the virtual machine"` + Name string `json:"name,omitempty" doc:"host name for the virtual machine"` + NetworkIDs []UUID `json:"networkids,omitempty" doc:"list of network ids used by virtual machine. Can't be specified with ipToNetworkList parameter"` + RootDiskSize int64 `json:"rootdisksize,omitempty" doc:"Optional field to resize root disk on deploy. Value is in GB. Only applies to template-based deployments. Analogous to details[0].rootdisksize, which takes precedence over this parameter if both are provided"` + SecurityGroupIDs []UUID `json:"securitygroupids,omitempty" doc:"comma separated list of security groups id that going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupnames parameter"` + SecurityGroupNames []string `json:"securitygroupnames,omitempty" doc:"comma separated list of security groups names that going to be applied to the virtual machine. Should be passed only when vm is created from a zone with Basic Network support. Mutually exclusive with securitygroupids parameter"` + ServiceOfferingID *UUID `json:"serviceofferingid" doc:"the ID of the service offering for the virtual machine"` + Size int64 `json:"size,omitempty" doc:"the arbitrary size for the DATADISK volume. Mutually exclusive with diskofferingid"` + StartVM *bool `json:"startvm,omitempty" doc:"true if start vm after creating. Default value is true"` + TemplateID *UUID `json:"templateid" doc:"the ID of the template for the virtual machine"` + UserData string `json:"userdata,omitempty" doc:"an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding."` + ZoneID *UUID `json:"zoneid" doc:"availability zone for the virtual machine"` + _ bool `name:"deployVirtualMachine" description:"Creates and automatically starts a virtual machine based on a service offering, disk offering, and template."` +} + +func (req DeployVirtualMachine) onBeforeSend(_ url.Values) error { + // Either AffinityGroupIDs or AffinityGroupNames must be set + if len(req.AffinityGroupIDs) > 0 && len(req.AffinityGroupNames) > 0 { + return fmt.Errorf("either AffinityGroupIDs or AffinityGroupNames must be set") + } + + // Either SecurityGroupIDs or SecurityGroupNames must be set + if len(req.SecurityGroupIDs) > 0 && len(req.SecurityGroupNames) > 0 { + return fmt.Errorf("either SecurityGroupIDs or SecurityGroupNames must be set") + } + + return nil +} + +// Response returns the struct to unmarshal +func (DeployVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DeployVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// StartVirtualMachine (Async) represents the creation of the virtual machine +type StartVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + RescueProfile string `json:"rescueprofile,omitempty" doc:"An optional rescue profile to use when booting"` + _ bool `name:"startVirtualMachine" description:"Starts a virtual machine."` +} + +// Response returns the struct to unmarshal +func (StartVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (StartVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// StopVirtualMachine (Async) represents the stopping of the virtual machine +type StopVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + Forced *bool `json:"forced,omitempty" doc:"Force stop the VM (vm is marked as Stopped even when command fails to be send to the backend). The caller knows the VM is stopped."` + _ bool `name:"stopVirtualMachine" description:"Stops a virtual machine."` +} + +// Response returns the struct to unmarshal +func (StopVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (StopVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// RebootVirtualMachine (Async) represents the rebooting of the virtual machine +type RebootVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + _ bool `name:"rebootVirtualMachine" description:"Reboots a virtual machine."` +} + +// Response returns the struct to unmarshal +func (RebootVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RebootVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// RestoreVirtualMachine (Async) represents the restoration of the virtual machine +type RestoreVirtualMachine struct { + VirtualMachineID *UUID `json:"virtualmachineid" doc:"Virtual Machine ID"` + TemplateID *UUID `json:"templateid,omitempty" doc:"an optional template Id to restore vm from the new template. This can be an ISO id in case of restore vm deployed using ISO"` + RootDiskSize int64 `json:"rootdisksize,omitempty" doc:"Optional field to resize root disk on restore. Value is in GB. Only applies to template-based deployments."` + _ bool `name:"restoreVirtualMachine" description:"Restore a VM to original template/ISO or new template/ISO"` +} + +// Response returns the struct to unmarshal +func (RestoreVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RestoreVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// RecoverVirtualMachine represents the restoration of the virtual machine +type RecoverVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + _ bool `name:"recoverVirtualMachine" description:"Recovers a virtual machine."` +} + +// Response returns the struct to unmarshal +func (RecoverVirtualMachine) Response() interface{} { + return new(VirtualMachine) +} + +// DestroyVirtualMachine (Async) represents the destruction of the virtual machine +type DestroyVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + _ bool `name:"destroyVirtualMachine" description:"Destroys a virtual machine."` +} + +// Response returns the struct to unmarshal +func (DestroyVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (DestroyVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// UpdateVirtualMachine represents the update of the virtual machine +type UpdateVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + Details map[string]string `json:"details,omitempty" doc:"Details in key/value pairs."` + DisplayName string `json:"displayname,omitempty" doc:"user generated name"` + Group string `json:"group,omitempty" doc:"group of the virtual machine"` + Name string `json:"name,omitempty" doc:"new host name of the vm. The VM has to be stopped/started for this update to take affect"` + SecurityGroupIDs []UUID `json:"securitygroupids,omitempty" doc:"list of security group ids to be applied on the virtual machine."` + UserData string `json:"userdata,omitempty" doc:"an optional binary data that can be sent to the virtual machine upon a successful deployment. This binary data must be base64 encoded before adding it to the request. Using HTTP GET (via querystring), you can send up to 2KB of data after base64 encoding. Using HTTP POST(via POST body), you can send up to 32K of data after base64 encoding."` + _ bool `name:"updateVirtualMachine" description:"Updates properties of a virtual machine. The VM has to be stopped and restarted for the new properties to take effect. UpdateVirtualMachine does not first check whether the VM is stopped. Therefore, stop the VM manually before issuing this call."` +} + +// Response returns the struct to unmarshal +func (UpdateVirtualMachine) Response() interface{} { + return new(VirtualMachine) +} + +// ExpungeVirtualMachine represents the annihilation of a VM +type ExpungeVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + _ bool `name:"expungeVirtualMachine" description:"Expunge a virtual machine. Once expunged, it cannot be recoverd."` +} + +// Response returns the struct to unmarshal +func (ExpungeVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (ExpungeVirtualMachine) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +// ScaleVirtualMachine (Async) scales the virtual machine to a new service offering. +// +// ChangeServiceForVirtualMachine does the same thing but returns the +// new Virtual Machine which is more consistent with the rest of the API. +type ScaleVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + ServiceOfferingID *UUID `json:"serviceofferingid" doc:"the ID of the service offering for the virtual machine"` + Details map[string]string `json:"details,omitempty" doc:"name value pairs of custom parameters for cpu,memory and cpunumber. example details[i].name=value"` + _ bool `name:"scaleVirtualMachine" description:"Scales the virtual machine to a new service offering."` +} + +// Response returns the struct to unmarshal +func (ScaleVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (ScaleVirtualMachine) AsyncResponse() interface{} { + return new(BooleanResponse) +} + +// ChangeServiceForVirtualMachine changes the service offering for a virtual machine. The virtual machine must be in a "Stopped" state for this command to take effect. +type ChangeServiceForVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + ServiceOfferingID *UUID `json:"serviceofferingid" doc:"the service offering ID to apply to the virtual machine"` + Details map[string]string `json:"details,omitempty" doc:"name value pairs of custom parameters for cpu, memory and cpunumber. example details[i].name=value"` + _ bool `name:"changeServiceForVirtualMachine" description:"Changes the service offering for a virtual machine. The virtual machine must be in a \"Stopped\" state for this command to take effect."` +} + +// Response returns the struct to unmarshal +func (ChangeServiceForVirtualMachine) Response() interface{} { + return new(VirtualMachine) +} + +// ResetPasswordForVirtualMachine resets the password for virtual machine. The virtual machine must be in a "Stopped" state... +type ResetPasswordForVirtualMachine struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + _ bool `name:"resetPasswordForVirtualMachine" description:"Resets the password for virtual machine. The virtual machine must be in a \"Stopped\" state and the template must already support this feature for this command to take effect."` +} + +// Response returns the struct to unmarshal +func (ResetPasswordForVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (ResetPasswordForVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// GetVMPassword asks for an encrypted password +type GetVMPassword struct { + ID *UUID `json:"id" doc:"The ID of the virtual machine"` + _ bool `name:"getVMPassword" description:"Returns an encrypted password for the VM"` +} + +// Response returns the struct to unmarshal +func (GetVMPassword) Response() interface{} { + return new(Password) +} + +//go:generate go run generate/main.go -interface=Listable ListVirtualMachines + +// ListVirtualMachines represents a search for a VM +type ListVirtualMachines struct { + AffinityGroupID *UUID `json:"affinitygroupid,omitempty" doc:"list vms by affinity group"` + Details []string `json:"details,omitempty" doc:"comma separated list of host details requested, value can be a list of [all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp]. If no parameter is passed in, the details will be defaulted to all"` + ForVirtualNetwork *bool `json:"forvirtualnetwork,omitempty" doc:"list by network type; true if need to list vms using Virtual Network, false otherwise"` + GroupID *UUID `json:"groupid,omitempty" doc:"the group ID"` + ID *UUID `json:"id,omitempty" doc:"the ID of the virtual machine"` + IDs []UUID `json:"ids,omitempty" doc:"the IDs of the virtual machines, mutually exclusive with id"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"an IP address to filter the result"` + IsoID *UUID `json:"isoid,omitempty" doc:"list vms by iso"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"name of the virtual machine"` + NetworkID *UUID `json:"networkid,omitempty" doc:"list by network id"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ServiceOfferindID *UUID `json:"serviceofferingid,omitempty" doc:"list by the service offering"` + State string `json:"state,omitempty" doc:"state of the virtual machine"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + TemplateID *UUID `json:"templateid,omitempty" doc:"list vms by template"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"the availability zone ID"` + _ bool `name:"listVirtualMachines" description:"List the virtual machines owned by the account."` +} + +// ListVirtualMachinesResponse represents a list of virtual machines +type ListVirtualMachinesResponse struct { + Count int `json:"count"` + VirtualMachine []VirtualMachine `json:"virtualmachine"` +} + +// AddNicToVirtualMachine (Async) adds a NIC to a VM +type AddNicToVirtualMachine struct { + NetworkID *UUID `json:"networkid" doc:"Network ID"` + VirtualMachineID *UUID `json:"virtualmachineid" doc:"Virtual Machine ID"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"Static IP address lease for the corresponding NIC and network which should be in the range defined in the network"` + _ bool `name:"addNicToVirtualMachine" description:"Adds VM to specified network by creating a NIC"` +} + +// Response returns the struct to unmarshal +func (AddNicToVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (AddNicToVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// RemoveNicFromVirtualMachine (Async) removes a NIC from a VM +type RemoveNicFromVirtualMachine struct { + NicID *UUID `json:"nicid" doc:"NIC ID"` + VirtualMachineID *UUID `json:"virtualmachineid" doc:"Virtual Machine ID"` + _ bool `name:"removeNicFromVirtualMachine" description:"Removes VM from specified network by deleting a NIC"` +} + +// Response returns the struct to unmarshal +func (RemoveNicFromVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (RemoveNicFromVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// UpdateDefaultNicForVirtualMachine (Async) adds a NIC to a VM +type UpdateDefaultNicForVirtualMachine struct { + NicID *UUID `json:"nicid" doc:"NIC ID"` + VirtualMachineID *UUID `json:"virtualmachineid" doc:"Virtual Machine ID"` + _ bool `name:"updateDefaultNicForVirtualMachine" description:"Changes the default NIC on a VM"` +} + +// Response returns the struct to unmarshal +func (UpdateDefaultNicForVirtualMachine) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (UpdateDefaultNicForVirtualMachine) AsyncResponse() interface{} { + return new(VirtualMachine) +} + +// GetVirtualMachineUserData returns the user-data of the given VM +type GetVirtualMachineUserData struct { + VirtualMachineID *UUID `json:"virtualmachineid" doc:"The ID of the virtual machine"` + _ bool `name:"getVirtualMachineUserData" description:"Returns user data associated with the VM"` +} + +// Response returns the struct to unmarshal +func (GetVirtualMachineUserData) Response() interface{} { + return new(VirtualMachineUserData) +} + +// UpdateVMNicIP updates the default IP address of a VM Nic +type UpdateVMNicIP struct { + _ bool `name:"updateVmNicIp" description:"Update the default Ip of a VM Nic"` + IPAddress net.IP `json:"ipaddress,omitempty" doc:"Static IP address lease for the corresponding NIC and network which should be in the range defined in the network. If absent, the call removes the lease associated with the nic."` + NicID *UUID `json:"nicid" doc:"the ID of the nic."` +} + +// Response returns the struct to unmarshal +func (UpdateVMNicIP) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (UpdateVMNicIP) AsyncResponse() interface{} { + return new(VirtualMachine) +} diff --git a/vendor/github.com/exoscale/egoscale/virtualmachines_response.go b/vendor/github.com/exoscale/egoscale/virtualmachines_response.go new file mode 100644 index 000000000..9aafb01a3 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/virtualmachines_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListVirtualMachines) Response() interface{} { + return new(ListVirtualMachinesResponse) +} + +// ListRequest returns itself +func (ls *ListVirtualMachines) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListVirtualMachines) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListVirtualMachines) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListVirtualMachines) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListVirtualMachinesResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListVirtualMachinesResponse was expected, got %T", resp)) + return + } + + for i := range items.VirtualMachine { + if !callback(&items.VirtualMachine[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/volumes.go b/vendor/github.com/exoscale/egoscale/volumes.go new file mode 100644 index 000000000..f942890a4 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/volumes.go @@ -0,0 +1,113 @@ +package egoscale + +// Volume represents a volume linked to a VM +type Volume struct { + Account string `json:"account,omitempty" doc:"the account associated with the disk volume"` + Attached string `json:"attached,omitempty" doc:"the date the volume was attached to a VM instance"` + ChainInfo string `json:"chaininfo,omitempty" doc:"the chain info of the volume"` + ClusterID *UUID `json:"clusterid,omitempty" doc:"ID of the cluster"` + ClusterName string `json:"clustername,omitempty" doc:"name of the cluster"` + Created string `json:"created,omitempty" doc:"the date the disk volume was created"` + Destroyed bool `json:"destroyed,omitempty" doc:"the boolean state of whether the volume is destroyed or not"` + DeviceID int64 `json:"deviceid,omitempty" doc:"the ID of the device on user vm the volume is attahed to. This tag is not returned when the volume is detached."` + DiskBytesReadRate int64 `json:"diskBytesReadRate,omitempty" doc:"bytes read rate of the disk volume"` + DiskBytesWriteRate int64 `json:"diskBytesWriteRate,omitempty" doc:"bytes write rate of the disk volume"` + DiskIopsReadRate int64 `json:"diskIopsReadRate,omitempty" doc:"io requests read rate of the disk volume"` + DiskIopsWriteRate int64 `json:"diskIopsWriteRate,omitempty" doc:"io requests write rate of the disk volume"` + DiskOfferingDisplayText string `json:"diskofferingdisplaytext,omitempty" doc:"the display text of the disk offering"` + DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"ID of the disk offering"` + DiskOfferingName string `json:"diskofferingname,omitempty" doc:"name of the disk offering"` + DisplayVolume bool `json:"displayvolume,omitempty" doc:"an optional field whether to the display the volume to the end user or not."` + Hypervisor string `json:"hypervisor,omitempty" doc:"Hypervisor the volume belongs to"` + ID *UUID `json:"id,omitempty" doc:"ID of the disk volume"` + IsExtractable *bool `json:"isextractable,omitempty" doc:"true if the volume is extractable, false otherwise"` + IsoDisplayText string `json:"isodisplaytext,omitempty" doc:"an alternate display text of the ISO attached to the virtual machine"` + IsoID *UUID `json:"isoid,omitempty" doc:"the ID of the ISO attached to the virtual machine"` + IsoName string `json:"isoname,omitempty" doc:"the name of the ISO attached to the virtual machine"` + MaxIops int64 `json:"maxiops,omitempty" doc:"max iops of the disk volume"` + MinIops int64 `json:"miniops,omitempty" doc:"min iops of the disk volume"` + Name string `json:"name,omitempty" doc:"name of the disk volume"` + Path string `json:"path,omitempty" doc:"the path of the volume"` + PodID *UUID `json:"podid,omitempty" doc:"ID of the pod"` + PodName string `json:"podname,omitempty" doc:"name of the pod"` + QuiesceVM bool `json:"quiescevm,omitempty" doc:"need quiesce vm or not when taking snapshot"` + ServiceOfferingDisplayText string `json:"serviceofferingdisplaytext,omitempty" doc:"the display text of the service offering for root disk"` + ServiceOfferingID *UUID `json:"serviceofferingid,omitempty" doc:"ID of the service offering for root disk"` + ServiceOfferingName string `json:"serviceofferingname,omitempty" doc:"name of the service offering for root disk"` + Size uint64 `json:"size,omitempty" doc:"size of the disk volume"` + SnapshotID *UUID `json:"snapshotid,omitempty" doc:"ID of the snapshot from which this volume was created"` + State string `json:"state,omitempty" doc:"the state of the disk volume"` + Status string `json:"status,omitempty" doc:"the status of the volume"` + Storage string `json:"storage,omitempty" doc:"name of the primary storage hosting the disk volume"` + StorageID *UUID `json:"storageid,omitempty" doc:"id of the primary storage hosting the disk volume; returned to admin user only"` + StorageType string `json:"storagetype,omitempty" doc:"shared or local storage"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with volume"` + TemplateDisplayText string `json:"templatedisplaytext,omitempty" doc:"an alternate display text of the template for the virtual machine"` + TemplateID *UUID `json:"templateid,omitempty" doc:"the ID of the template for the virtual machine. A -1 is returned if the virtual machine was created from an ISO file."` // no *UUID because of the -1 thingy... + TemplateName string `json:"templatename,omitempty" doc:"the name of the template for the virtual machine"` + Type string `json:"type,omitempty" doc:"type of the disk volume (ROOT or DATADISK)"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"id of the virtual machine"` + VMDisplayName string `json:"vmdisplayname,omitempty" doc:"display name of the virtual machine"` + VMName string `json:"vmname,omitempty" doc:"name of the virtual machine"` + VMState string `json:"vmstate,omitempty" doc:"state of the virtual machine"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"ID of the availability zone"` + ZoneName string `json:"zonename,omitempty" doc:"name of the availability zone"` +} + +// ResourceType returns the type of the resource +func (Volume) ResourceType() string { + return "Volume" +} + +// ListRequest builds the ListVolumes request +func (vol Volume) ListRequest() (ListCommand, error) { + req := &ListVolumes{ + Name: vol.Name, + Type: vol.Type, + VirtualMachineID: vol.VirtualMachineID, + ZoneID: vol.ZoneID, + } + + return req, nil +} + +// ResizeVolume (Async) resizes a volume +type ResizeVolume struct { + ID *UUID `json:"id" doc:"the ID of the disk volume"` + DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"new disk offering id"` + Size int64 `json:"size,omitempty" doc:"New volume size in G (must be larger than current size since shrinking the disk is not supported)"` + _ bool `name:"resizeVolume" description:"Resizes a volume"` +} + +// Response returns the struct to unmarshal +func (ResizeVolume) Response() interface{} { + return new(AsyncJobResult) +} + +// AsyncResponse returns the struct to unmarshal the async job +func (ResizeVolume) AsyncResponse() interface{} { + return new(Volume) +} + +//go:generate go run generate/main.go -interface=Listable ListVolumes + +// ListVolumes represents a query listing volumes +type ListVolumes struct { + DiskOfferingID *UUID `json:"diskofferingid,omitempty" doc:"List volumes by disk offering"` + ID *UUID `json:"id,omitempty" doc:"The ID of the disk volume"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"The name of the disk volume"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List resources by tags (key/value pairs)"` + Type string `json:"type,omitempty" doc:"The type of disk volume"` + VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"The ID of the virtual machine"` + ZoneID *UUID `json:"zoneid,omitempty" doc:"The ID of the availability zone"` + _ bool `name:"listVolumes" description:"Lists all volumes."` +} + +// ListVolumesResponse represents a list of volumes +type ListVolumesResponse struct { + Count int `json:"count"` + Volume []Volume `json:"volume"` +} diff --git a/vendor/github.com/exoscale/egoscale/volumes_response.go b/vendor/github.com/exoscale/egoscale/volumes_response.go new file mode 100644 index 000000000..c7486bc1e --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/volumes_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListVolumes) Response() interface{} { + return new(ListVolumesResponse) +} + +// ListRequest returns itself +func (ls *ListVolumes) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListVolumes) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListVolumes) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListVolumes) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListVolumesResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListVolumesResponse was expected, got %T", resp)) + return + } + + for i := range items.Volume { + if !callback(&items.Volume[i], nil) { + break + } + } +} diff --git a/vendor/github.com/exoscale/egoscale/zones.go b/vendor/github.com/exoscale/egoscale/zones.go new file mode 100644 index 000000000..763246033 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/zones.go @@ -0,0 +1,62 @@ +package egoscale + +import ( + "net" +) + +// Zone represents a data center +// +// TODO: represent correctly the capacity field. +type Zone struct { + AllocationState string `json:"allocationstate,omitempty" doc:"the allocation state of the cluster"` + Description string `json:"description,omitempty" doc:"Zone description"` + DhcpProvider string `json:"dhcpprovider,omitempty" doc:"the dhcp Provider for the Zone"` + DisplayText string `json:"displaytext,omitempty" doc:"the display text of the zone"` + DNS1 net.IP `json:"dns1,omitempty" doc:"the first DNS for the Zone"` + DNS2 net.IP `json:"dns2,omitempty" doc:"the second DNS for the Zone"` + GuestCIDRAddress *CIDR `json:"guestcidraddress,omitempty" doc:"the guest CIDR address for the Zone"` + ID *UUID `json:"id,omitempty" doc:"Zone id"` + InternalDNS1 net.IP `json:"internaldns1,omitempty" doc:"the first internal DNS for the Zone"` + InternalDNS2 net.IP `json:"internaldns2,omitempty" doc:"the second internal DNS for the Zone"` + IP6DNS1 net.IP `json:"ip6dns1,omitempty" doc:"the first IPv6 DNS for the Zone"` + IP6DNS2 net.IP `json:"ip6dns2,omitempty" doc:"the second IPv6 DNS for the Zone"` + LocalStorageEnabled *bool `json:"localstorageenabled,omitempty" doc:"true if local storage offering enabled, false otherwise"` + Name string `json:"name,omitempty" doc:"Zone name"` + NetworkType string `json:"networktype,omitempty" doc:"the network type of the zone; can be Basic or Advanced"` + ResourceDetails map[string]string `json:"resourcedetails,omitempty" doc:"Meta data associated with the zone (key/value pairs)"` + SecurityGroupsEnabled *bool `json:"securitygroupsenabled,omitempty" doc:"true if security groups support is enabled, false otherwise"` + Tags []ResourceTag `json:"tags,omitempty" doc:"the list of resource tags associated with zone."` + Vlan string `json:"vlan,omitempty" doc:"the vlan range of the zone"` + ZoneToken string `json:"zonetoken,omitempty" doc:"Zone Token"` +} + +// ListRequest builds the ListZones request +func (zone Zone) ListRequest() (ListCommand, error) { + req := &ListZones{ + ID: zone.ID, + Name: zone.Name, + } + + return req, nil +} + +//go:generate go run generate/main.go -interface=Listable ListZones + +// ListZones represents a query for zones +type ListZones struct { + Available *bool `json:"available,omitempty" doc:"true if you want to retrieve all available Zones. False if you only want to return the Zones from which you have at least one VM. Default is false."` + ID *UUID `json:"id,omitempty" doc:"the ID of the zone"` + Keyword string `json:"keyword,omitempty" doc:"List by keyword"` + Name string `json:"name,omitempty" doc:"the name of the zone"` + Page int `json:"page,omitempty"` + PageSize int `json:"pagesize,omitempty"` + ShowCapacities *bool `json:"showcapacities,omitempty" doc:"flag to display the capacity of the zones"` + Tags []ResourceTag `json:"tags,omitempty" doc:"List zones by resource tags (key/value pairs)"` + _ bool `name:"listZones" description:"Lists zones"` +} + +// ListZonesResponse represents a list of zones +type ListZonesResponse struct { + Count int `json:"count"` + Zone []Zone `json:"zone"` +} diff --git a/vendor/github.com/exoscale/egoscale/zones_response.go b/vendor/github.com/exoscale/egoscale/zones_response.go new file mode 100644 index 000000000..0fe7d06d7 --- /dev/null +++ b/vendor/github.com/exoscale/egoscale/zones_response.go @@ -0,0 +1,43 @@ +// code generated; DO NOT EDIT. + +package egoscale + +import "fmt" + +// Response returns the struct to unmarshal +func (ListZones) Response() interface{} { + return new(ListZonesResponse) +} + +// ListRequest returns itself +func (ls *ListZones) ListRequest() (ListCommand, error) { + if ls == nil { + return nil, fmt.Errorf("%T cannot be nil", ls) + } + return ls, nil +} + +// SetPage sets the current apge +func (ls *ListZones) SetPage(page int) { + ls.Page = page +} + +// SetPageSize sets the page size +func (ls *ListZones) SetPageSize(pageSize int) { + ls.PageSize = pageSize +} + +// Each triggers the callback for each, valid answer or any non 404 issue +func (ListZones) Each(resp interface{}, callback IterateItemFunc) { + items, ok := resp.(*ListZonesResponse) + if !ok { + callback(nil, fmt.Errorf("wrong type, ListZonesResponse was expected, got %T", resp)) + return + } + + for i := range items.Zone { + if !callback(&items.Zone[i], nil) { + break + } + } +} diff --git a/vendor/github.com/fatih/structs/.gitignore b/vendor/github.com/fatih/structs/.gitignore new file mode 100644 index 000000000..836562412 --- /dev/null +++ b/vendor/github.com/fatih/structs/.gitignore @@ -0,0 +1,23 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test diff --git a/vendor/github.com/fatih/structs/.travis.yml b/vendor/github.com/fatih/structs/.travis.yml new file mode 100644 index 000000000..a08df7981 --- /dev/null +++ b/vendor/github.com/fatih/structs/.travis.yml @@ -0,0 +1,13 @@ +language: go +go: + - 1.7.x + - 1.8.x + - 1.9.x + - tip +sudo: false +before_install: +- go get github.com/axw/gocov/gocov +- go get github.com/mattn/goveralls +- if ! go get github.com/golang/tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi +script: +- $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/fatih/structs/LICENSE b/vendor/github.com/fatih/structs/LICENSE new file mode 100644 index 000000000..34504e4b3 --- /dev/null +++ b/vendor/github.com/fatih/structs/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Fatih Arslan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/fatih/structs/README.md b/vendor/github.com/fatih/structs/README.md new file mode 100644 index 000000000..a75eabf37 --- /dev/null +++ b/vendor/github.com/fatih/structs/README.md @@ -0,0 +1,163 @@ +# Structs [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/structs) [![Build Status](http://img.shields.io/travis/fatih/structs.svg?style=flat-square)](https://travis-ci.org/fatih/structs) [![Coverage Status](http://img.shields.io/coveralls/fatih/structs.svg?style=flat-square)](https://coveralls.io/r/fatih/structs) + +Structs contains various utilities to work with Go (Golang) structs. It was +initially used by me to convert a struct into a `map[string]interface{}`. With +time I've added other utilities for structs. It's basically a high level +package based on primitives from the reflect package. Feel free to add new +functions or improve the existing code. + +## Install + +```bash +go get github.com/fatih/structs +``` + +## Usage and Examples + +Just like the standard lib `strings`, `bytes` and co packages, `structs` has +many global functions to manipulate or organize your struct data. Lets define +and declare a struct: + +```go +type Server struct { + Name string `json:"name,omitempty"` + ID int + Enabled bool + users []string // not exported + http.Server // embedded +} + +server := &Server{ + Name: "gopher", + ID: 123456, + Enabled: true, +} +``` + +```go +// Convert a struct to a map[string]interface{} +// => {"Name":"gopher", "ID":123456, "Enabled":true} +m := structs.Map(server) + +// Convert the values of a struct to a []interface{} +// => ["gopher", 123456, true] +v := structs.Values(server) + +// Convert the names of a struct to a []string +// (see "Names methods" for more info about fields) +n := structs.Names(server) + +// Convert the values of a struct to a []*Field +// (see "Field methods" for more info about fields) +f := structs.Fields(server) + +// Return the struct name => "Server" +n := structs.Name(server) + +// Check if any field of a struct is initialized or not. +h := structs.HasZero(server) + +// Check if all fields of a struct is initialized or not. +z := structs.IsZero(server) + +// Check if server is a struct or a pointer to struct +i := structs.IsStruct(server) +``` + +### Struct methods + +The structs functions can be also used as independent methods by creating a new +`*structs.Struct`. This is handy if you want to have more control over the +structs (such as retrieving a single Field). + +```go +// Create a new struct type: +s := structs.New(server) + +m := s.Map() // Get a map[string]interface{} +v := s.Values() // Get a []interface{} +f := s.Fields() // Get a []*Field +n := s.Names() // Get a []string +f := s.Field(name) // Get a *Field based on the given field name +f, ok := s.FieldOk(name) // Get a *Field based on the given field name +n := s.Name() // Get the struct name +h := s.HasZero() // Check if any field is uninitialized +z := s.IsZero() // Check if all fields are uninitialized +``` + +### Field methods + +We can easily examine a single Field for more detail. Below you can see how we +get and interact with various field methods: + + +```go +s := structs.New(server) + +// Get the Field struct for the "Name" field +name := s.Field("Name") + +// Get the underlying value, value => "gopher" +value := name.Value().(string) + +// Set the field's value +name.Set("another gopher") + +// Get the field's kind, kind => "string" +name.Kind() + +// Check if the field is exported or not +if name.IsExported() { + fmt.Println("Name field is exported") +} + +// Check if the value is a zero value, such as "" for string, 0 for int +if !name.IsZero() { + fmt.Println("Name is initialized") +} + +// Check if the field is an anonymous (embedded) field +if !name.IsEmbedded() { + fmt.Println("Name is not an embedded field") +} + +// Get the Field's tag value for tag name "json", tag value => "name,omitempty" +tagValue := name.Tag("json") +``` + +Nested structs are supported too: + +```go +addrField := s.Field("Server").Field("Addr") + +// Get the value for addr +a := addrField.Value().(string) + +// Or get all fields +httpServer := s.Field("Server").Fields() +``` + +We can also get a slice of Fields from the Struct type to iterate over all +fields. This is handy if you wish to examine all fields: + +```go +s := structs.New(server) + +for _, f := range s.Fields() { + fmt.Printf("field name: %+v\n", f.Name()) + + if f.IsExported() { + fmt.Printf("value : %+v\n", f.Value()) + fmt.Printf("is zero : %+v\n", f.IsZero()) + } +} +``` + +## Credits + + * [Fatih Arslan](https://github.com/fatih) + * [Cihangir Savas](https://github.com/cihangir) + +## License + +The MIT License (MIT) - see LICENSE.md for more details diff --git a/vendor/github.com/fatih/structs/field.go b/vendor/github.com/fatih/structs/field.go new file mode 100644 index 000000000..e69783230 --- /dev/null +++ b/vendor/github.com/fatih/structs/field.go @@ -0,0 +1,141 @@ +package structs + +import ( + "errors" + "fmt" + "reflect" +) + +var ( + errNotExported = errors.New("field is not exported") + errNotSettable = errors.New("field is not settable") +) + +// Field represents a single struct field that encapsulates high level +// functions around the field. +type Field struct { + value reflect.Value + field reflect.StructField + defaultTag string +} + +// Tag returns the value associated with key in the tag string. If there is no +// such key in the tag, Tag returns the empty string. +func (f *Field) Tag(key string) string { + return f.field.Tag.Get(key) +} + +// Value returns the underlying value of the field. It panics if the field +// is not exported. +func (f *Field) Value() interface{} { + return f.value.Interface() +} + +// IsEmbedded returns true if the given field is an anonymous field (embedded) +func (f *Field) IsEmbedded() bool { + return f.field.Anonymous +} + +// IsExported returns true if the given field is exported. +func (f *Field) IsExported() bool { + return f.field.PkgPath == "" +} + +// IsZero returns true if the given field is not initialized (has a zero value). +// It panics if the field is not exported. +func (f *Field) IsZero() bool { + zero := reflect.Zero(f.value.Type()).Interface() + current := f.Value() + + return reflect.DeepEqual(current, zero) +} + +// Name returns the name of the given field +func (f *Field) Name() string { + return f.field.Name +} + +// Kind returns the fields kind, such as "string", "map", "bool", etc .. +func (f *Field) Kind() reflect.Kind { + return f.value.Kind() +} + +// Set sets the field to given value v. It returns an error if the field is not +// settable (not addressable or not exported) or if the given value's type +// doesn't match the fields type. +func (f *Field) Set(val interface{}) error { + // we can't set unexported fields, so be sure this field is exported + if !f.IsExported() { + return errNotExported + } + + // do we get here? not sure... + if !f.value.CanSet() { + return errNotSettable + } + + given := reflect.ValueOf(val) + + if f.value.Kind() != given.Kind() { + return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind()) + } + + f.value.Set(given) + return nil +} + +// Zero sets the field to its zero value. It returns an error if the field is not +// settable (not addressable or not exported). +func (f *Field) Zero() error { + zero := reflect.Zero(f.value.Type()).Interface() + return f.Set(zero) +} + +// Fields returns a slice of Fields. This is particular handy to get the fields +// of a nested struct . A struct tag with the content of "-" ignores the +// checking of that particular field. Example: +// +// // Field is ignored by this package. +// Field *http.Request `structs:"-"` +// +// It panics if field is not exported or if field's kind is not struct +func (f *Field) Fields() []*Field { + return getFields(f.value, f.defaultTag) +} + +// Field returns the field from a nested struct. It panics if the nested struct +// is not exported or if the field was not found. +func (f *Field) Field(name string) *Field { + field, ok := f.FieldOk(name) + if !ok { + panic("field not found") + } + + return field +} + +// FieldOk returns the field from a nested struct. The boolean returns whether +// the field was found (true) or not (false). +func (f *Field) FieldOk(name string) (*Field, bool) { + value := &f.value + // value must be settable so we need to make sure it holds the address of the + // variable and not a copy, so we can pass the pointer to strctVal instead of a + // copy (which is not assigned to any variable, hence not settable). + // see "https://blog.golang.org/laws-of-reflection#TOC_8." + if f.value.Kind() != reflect.Ptr { + a := f.value.Addr() + value = &a + } + v := strctVal(value.Interface()) + t := v.Type() + + field, ok := t.FieldByName(name) + if !ok { + return nil, false + } + + return &Field{ + field: field, + value: v.FieldByName(name), + }, true +} diff --git a/vendor/github.com/fatih/structs/structs.go b/vendor/github.com/fatih/structs/structs.go new file mode 100644 index 000000000..3a8770652 --- /dev/null +++ b/vendor/github.com/fatih/structs/structs.go @@ -0,0 +1,584 @@ +// Package structs contains various utilities functions to work with structs. +package structs + +import ( + "fmt" + + "reflect" +) + +var ( + // DefaultTagName is the default tag name for struct fields which provides + // a more granular to tweak certain structs. Lookup the necessary functions + // for more info. + DefaultTagName = "structs" // struct's field default tag name +) + +// Struct encapsulates a struct type to provide several high level functions +// around the struct. +type Struct struct { + raw interface{} + value reflect.Value + TagName string +} + +// New returns a new *Struct with the struct s. It panics if the s's kind is +// not struct. +func New(s interface{}) *Struct { + return &Struct{ + raw: s, + value: strctVal(s), + TagName: DefaultTagName, + } +} + +// Map converts the given struct to a map[string]interface{}, where the keys +// of the map are the field names and the values of the map the associated +// values of the fields. The default key string is the struct field name but +// can be changed in the struct field's tag value. The "structs" key in the +// struct's field tag value is the key name. Example: +// +// // Field appears in map as key "myName". +// Name string `structs:"myName"` +// +// A tag value with the content of "-" ignores that particular field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// A tag value with the content of "string" uses the stringer to get the value. Example: +// +// // The value will be output of Animal's String() func. +// // Map will panic if Animal does not implement String(). +// Field *Animal `structs:"field,string"` +// +// A tag value with the option of "flatten" used in a struct field is to flatten its fields +// in the output map. Example: +// +// // The FieldStruct's fields will be flattened into the output map. +// FieldStruct time.Time `structs:",flatten"` +// +// A tag value with the option of "omitnested" stops iterating further if the type +// is a struct. Example: +// +// // Field is not processed further by this package. +// Field time.Time `structs:"myName,omitnested"` +// Field *http.Request `structs:",omitnested"` +// +// A tag value with the option of "omitempty" ignores that particular field if +// the field value is empty. Example: +// +// // Field appears in map as key "myName", but the field is +// // skipped if empty. +// Field string `structs:"myName,omitempty"` +// +// // Field appears in map as key "Field" (the default), but +// // the field is skipped if empty. +// Field string `structs:",omitempty"` +// +// Note that only exported fields of a struct can be accessed, non exported +// fields will be neglected. +func (s *Struct) Map() map[string]interface{} { + out := make(map[string]interface{}) + s.FillMap(out) + return out +} + +// FillMap is the same as Map. Instead of returning the output, it fills the +// given map. +func (s *Struct) FillMap(out map[string]interface{}) { + if out == nil { + return + } + + fields := s.structFields() + + for _, field := range fields { + name := field.Name + val := s.value.FieldByName(name) + isSubStruct := false + var finalVal interface{} + + tagName, tagOpts := parseTag(field.Tag.Get(s.TagName)) + if tagName != "" { + name = tagName + } + + // if the value is a zero value and the field is marked as omitempty do + // not include + if tagOpts.Has("omitempty") { + zero := reflect.Zero(val.Type()).Interface() + current := val.Interface() + + if reflect.DeepEqual(current, zero) { + continue + } + } + + if !tagOpts.Has("omitnested") { + finalVal = s.nested(val) + + v := reflect.ValueOf(val.Interface()) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Map, reflect.Struct: + isSubStruct = true + } + } else { + finalVal = val.Interface() + } + + if tagOpts.Has("string") { + s, ok := val.Interface().(fmt.Stringer) + if ok { + out[name] = s.String() + } + continue + } + + if isSubStruct && (tagOpts.Has("flatten")) { + for k := range finalVal.(map[string]interface{}) { + out[k] = finalVal.(map[string]interface{})[k] + } + } else { + out[name] = finalVal + } + } +} + +// Values converts the given s struct's field values to a []interface{}. A +// struct tag with the content of "-" ignores the that particular field. +// Example: +// +// // Field is ignored by this package. +// Field int `structs:"-"` +// +// A value with the option of "omitnested" stops iterating further if the type +// is a struct. Example: +// +// // Fields is not processed further by this package. +// Field time.Time `structs:",omitnested"` +// Field *http.Request `structs:",omitnested"` +// +// A tag value with the option of "omitempty" ignores that particular field and +// is not added to the values if the field value is empty. Example: +// +// // Field is skipped if empty +// Field string `structs:",omitempty"` +// +// Note that only exported fields of a struct can be accessed, non exported +// fields will be neglected. +func (s *Struct) Values() []interface{} { + fields := s.structFields() + + var t []interface{} + + for _, field := range fields { + val := s.value.FieldByName(field.Name) + + _, tagOpts := parseTag(field.Tag.Get(s.TagName)) + + // if the value is a zero value and the field is marked as omitempty do + // not include + if tagOpts.Has("omitempty") { + zero := reflect.Zero(val.Type()).Interface() + current := val.Interface() + + if reflect.DeepEqual(current, zero) { + continue + } + } + + if tagOpts.Has("string") { + s, ok := val.Interface().(fmt.Stringer) + if ok { + t = append(t, s.String()) + } + continue + } + + if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { + // look out for embedded structs, and convert them to a + // []interface{} to be added to the final values slice + t = append(t, Values(val.Interface())...) + } else { + t = append(t, val.Interface()) + } + } + + return t +} + +// Fields returns a slice of Fields. A struct tag with the content of "-" +// ignores the checking of that particular field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// It panics if s's kind is not struct. +func (s *Struct) Fields() []*Field { + return getFields(s.value, s.TagName) +} + +// Names returns a slice of field names. A struct tag with the content of "-" +// ignores the checking of that particular field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// It panics if s's kind is not struct. +func (s *Struct) Names() []string { + fields := getFields(s.value, s.TagName) + + names := make([]string, len(fields)) + + for i, field := range fields { + names[i] = field.Name() + } + + return names +} + +func getFields(v reflect.Value, tagName string) []*Field { + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + t := v.Type() + + var fields []*Field + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + + if tag := field.Tag.Get(tagName); tag == "-" { + continue + } + + f := &Field{ + field: field, + value: v.FieldByName(field.Name), + } + + fields = append(fields, f) + + } + + return fields +} + +// Field returns a new Field struct that provides several high level functions +// around a single struct field entity. It panics if the field is not found. +func (s *Struct) Field(name string) *Field { + f, ok := s.FieldOk(name) + if !ok { + panic("field not found") + } + + return f +} + +// FieldOk returns a new Field struct that provides several high level functions +// around a single struct field entity. The boolean returns true if the field +// was found. +func (s *Struct) FieldOk(name string) (*Field, bool) { + t := s.value.Type() + + field, ok := t.FieldByName(name) + if !ok { + return nil, false + } + + return &Field{ + field: field, + value: s.value.FieldByName(name), + defaultTag: s.TagName, + }, true +} + +// IsZero returns true if all fields in a struct is a zero value (not +// initialized) A struct tag with the content of "-" ignores the checking of +// that particular field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// A value with the option of "omitnested" stops iterating further if the type +// is a struct. Example: +// +// // Field is not processed further by this package. +// Field time.Time `structs:"myName,omitnested"` +// Field *http.Request `structs:",omitnested"` +// +// Note that only exported fields of a struct can be accessed, non exported +// fields will be neglected. It panics if s's kind is not struct. +func (s *Struct) IsZero() bool { + fields := s.structFields() + + for _, field := range fields { + val := s.value.FieldByName(field.Name) + + _, tagOpts := parseTag(field.Tag.Get(s.TagName)) + + if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { + ok := IsZero(val.Interface()) + if !ok { + return false + } + + continue + } + + // zero value of the given field, such as "" for string, 0 for int + zero := reflect.Zero(val.Type()).Interface() + + // current value of the given field + current := val.Interface() + + if !reflect.DeepEqual(current, zero) { + return false + } + } + + return true +} + +// HasZero returns true if a field in a struct is not initialized (zero value). +// A struct tag with the content of "-" ignores the checking of that particular +// field. Example: +// +// // Field is ignored by this package. +// Field bool `structs:"-"` +// +// A value with the option of "omitnested" stops iterating further if the type +// is a struct. Example: +// +// // Field is not processed further by this package. +// Field time.Time `structs:"myName,omitnested"` +// Field *http.Request `structs:",omitnested"` +// +// Note that only exported fields of a struct can be accessed, non exported +// fields will be neglected. It panics if s's kind is not struct. +func (s *Struct) HasZero() bool { + fields := s.structFields() + + for _, field := range fields { + val := s.value.FieldByName(field.Name) + + _, tagOpts := parseTag(field.Tag.Get(s.TagName)) + + if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { + ok := HasZero(val.Interface()) + if ok { + return true + } + + continue + } + + // zero value of the given field, such as "" for string, 0 for int + zero := reflect.Zero(val.Type()).Interface() + + // current value of the given field + current := val.Interface() + + if reflect.DeepEqual(current, zero) { + return true + } + } + + return false +} + +// Name returns the structs's type name within its package. For more info refer +// to Name() function. +func (s *Struct) Name() string { + return s.value.Type().Name() +} + +// structFields returns the exported struct fields for a given s struct. This +// is a convenient helper method to avoid duplicate code in some of the +// functions. +func (s *Struct) structFields() []reflect.StructField { + t := s.value.Type() + + var f []reflect.StructField + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + // we can't access the value of unexported fields + if field.PkgPath != "" { + continue + } + + // don't check if it's omitted + if tag := field.Tag.Get(s.TagName); tag == "-" { + continue + } + + f = append(f, field) + } + + return f +} + +func strctVal(s interface{}) reflect.Value { + v := reflect.ValueOf(s) + + // if pointer get the underlying element≤ + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + + if v.Kind() != reflect.Struct { + panic("not struct") + } + + return v +} + +// Map converts the given struct to a map[string]interface{}. For more info +// refer to Struct types Map() method. It panics if s's kind is not struct. +func Map(s interface{}) map[string]interface{} { + return New(s).Map() +} + +// FillMap is the same as Map. Instead of returning the output, it fills the +// given map. +func FillMap(s interface{}, out map[string]interface{}) { + New(s).FillMap(out) +} + +// Values converts the given struct to a []interface{}. For more info refer to +// Struct types Values() method. It panics if s's kind is not struct. +func Values(s interface{}) []interface{} { + return New(s).Values() +} + +// Fields returns a slice of *Field. For more info refer to Struct types +// Fields() method. It panics if s's kind is not struct. +func Fields(s interface{}) []*Field { + return New(s).Fields() +} + +// Names returns a slice of field names. For more info refer to Struct types +// Names() method. It panics if s's kind is not struct. +func Names(s interface{}) []string { + return New(s).Names() +} + +// IsZero returns true if all fields is equal to a zero value. For more info +// refer to Struct types IsZero() method. It panics if s's kind is not struct. +func IsZero(s interface{}) bool { + return New(s).IsZero() +} + +// HasZero returns true if any field is equal to a zero value. For more info +// refer to Struct types HasZero() method. It panics if s's kind is not struct. +func HasZero(s interface{}) bool { + return New(s).HasZero() +} + +// IsStruct returns true if the given variable is a struct or a pointer to +// struct. +func IsStruct(s interface{}) bool { + v := reflect.ValueOf(s) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + // uninitialized zero value of a struct + if v.Kind() == reflect.Invalid { + return false + } + + return v.Kind() == reflect.Struct +} + +// Name returns the structs's type name within its package. It returns an +// empty string for unnamed types. It panics if s's kind is not struct. +func Name(s interface{}) string { + return New(s).Name() +} + +// nested retrieves recursively all types for the given value and returns the +// nested value. +func (s *Struct) nested(val reflect.Value) interface{} { + var finalVal interface{} + + v := reflect.ValueOf(val.Interface()) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Struct: + n := New(val.Interface()) + n.TagName = s.TagName + m := n.Map() + + // do not add the converted value if there are no exported fields, ie: + // time.Time + if len(m) == 0 { + finalVal = val.Interface() + } else { + finalVal = m + } + case reflect.Map: + // get the element type of the map + mapElem := val.Type() + switch val.Type().Kind() { + case reflect.Ptr, reflect.Array, reflect.Map, + reflect.Slice, reflect.Chan: + mapElem = val.Type().Elem() + if mapElem.Kind() == reflect.Ptr { + mapElem = mapElem.Elem() + } + } + + // only iterate over struct types, ie: map[string]StructType, + // map[string][]StructType, + if mapElem.Kind() == reflect.Struct || + (mapElem.Kind() == reflect.Slice && + mapElem.Elem().Kind() == reflect.Struct) { + m := make(map[string]interface{}, val.Len()) + for _, k := range val.MapKeys() { + m[k.String()] = s.nested(val.MapIndex(k)) + } + finalVal = m + break + } + + // TODO(arslan): should this be optional? + finalVal = val.Interface() + case reflect.Slice, reflect.Array: + if val.Type().Kind() == reflect.Interface { + finalVal = val.Interface() + break + } + + // TODO(arslan): should this be optional? + // do not iterate of non struct types, just pass the value. Ie: []int, + // []string, co... We only iterate further if it's a struct. + // i.e []foo or []*foo + if val.Type().Elem().Kind() != reflect.Struct && + !(val.Type().Elem().Kind() == reflect.Ptr && + val.Type().Elem().Elem().Kind() == reflect.Struct) { + finalVal = val.Interface() + break + } + + slices := make([]interface{}, val.Len()) + for x := 0; x < val.Len(); x++ { + slices[x] = s.nested(val.Index(x)) + } + finalVal = slices + default: + finalVal = val.Interface() + } + + return finalVal +} diff --git a/vendor/github.com/fatih/structs/tags.go b/vendor/github.com/fatih/structs/tags.go new file mode 100644 index 000000000..136a31eba --- /dev/null +++ b/vendor/github.com/fatih/structs/tags.go @@ -0,0 +1,32 @@ +package structs + +import "strings" + +// tagOptions contains a slice of tag options +type tagOptions []string + +// Has returns true if the given option is available in tagOptions +func (t tagOptions) Has(opt string) bool { + for _, tagOpt := range t { + if tagOpt == opt { + return true + } + } + + return false +} + +// parseTag splits a struct field's tag into its name and a list of options +// which comes after a name. A tag is in the form of: "name,option1,option2". +// The name can be neglectected. +func parseTag(tag string) (string, tagOptions) { + // tag is one of followings: + // "" + // "name" + // "name,opt" + // "name,opt,opt2" + // ",opt" + + res := strings.Split(tag, ",") + return res[0], res[1:] +} diff --git a/vendor/github.com/go-acme/lego/v3/platform/config/env/env.go b/vendor/github.com/go-acme/lego/v3/platform/config/env/env.go new file mode 100644 index 000000000..dd86395bb --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/platform/config/env/env.go @@ -0,0 +1,163 @@ +package env + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + "time" + + "github.com/go-acme/lego/v3/log" +) + +// Get environment variables +func Get(names ...string) (map[string]string, error) { + values := map[string]string{} + + var missingEnvVars []string + for _, envVar := range names { + value := GetOrFile(envVar) + if value == "" { + missingEnvVars = append(missingEnvVars, envVar) + } + values[envVar] = value + } + + if len(missingEnvVars) > 0 { + return nil, fmt.Errorf("some credentials information are missing: %s", strings.Join(missingEnvVars, ",")) + } + + return values, nil +} + +// GetWithFallback Get environment variable values +// The first name in each group is use as key in the result map +// +// // LEGO_ONE="ONE" +// // LEGO_TWO="TWO" +// env.GetWithFallback([]string{"LEGO_ONE", "LEGO_TWO"}) +// // => "LEGO_ONE" = "ONE" +// +// ---- +// +// // LEGO_ONE="" +// // LEGO_TWO="TWO" +// env.GetWithFallback([]string{"LEGO_ONE", "LEGO_TWO"}) +// // => "LEGO_ONE" = "TWO" +// +// ---- +// +// // LEGO_ONE="" +// // LEGO_TWO="" +// env.GetWithFallback([]string{"LEGO_ONE", "LEGO_TWO"}) +// // => error +// +func GetWithFallback(groups ...[]string) (map[string]string, error) { + values := map[string]string{} + + var missingEnvVars []string + for _, names := range groups { + if len(names) == 0 { + return nil, errors.New("undefined environment variable names") + } + + value, envVar := getOneWithFallback(names[0], names[1:]...) + if len(value) == 0 { + missingEnvVars = append(missingEnvVars, envVar) + continue + } + values[envVar] = value + } + + if len(missingEnvVars) > 0 { + return nil, fmt.Errorf("some credentials information are missing: %s", strings.Join(missingEnvVars, ",")) + } + + return values, nil +} + +func getOneWithFallback(main string, names ...string) (string, string) { + value := GetOrFile(main) + if len(value) > 0 { + return value, main + } + + for _, name := range names { + value := GetOrFile(name) + if len(value) > 0 { + return value, main + } + } + + return "", main +} + +// GetOrDefaultInt returns the given environment variable value as an integer. +// Returns the default if the envvar cannot be coopered to an int, or is not found. +func GetOrDefaultInt(envVar string, defaultValue int) int { + v, err := strconv.Atoi(GetOrFile(envVar)) + if err != nil { + return defaultValue + } + + return v +} + +// GetOrDefaultSecond returns the given environment variable value as an time.Duration (second). +// Returns the default if the envvar cannot be coopered to an int, or is not found. +func GetOrDefaultSecond(envVar string, defaultValue time.Duration) time.Duration { + v := GetOrDefaultInt(envVar, -1) + if v < 0 { + return defaultValue + } + + return time.Duration(v) * time.Second +} + +// GetOrDefaultString returns the given environment variable value as a string. +// Returns the default if the envvar cannot be find. +func GetOrDefaultString(envVar string, defaultValue string) string { + v := GetOrFile(envVar) + if len(v) == 0 { + return defaultValue + } + + return v +} + +// GetOrDefaultBool returns the given environment variable value as a boolean. +// Returns the default if the envvar cannot be coopered to a boolean, or is not found. +func GetOrDefaultBool(envVar string, defaultValue bool) bool { + v, err := strconv.ParseBool(GetOrFile(envVar)) + if err != nil { + return defaultValue + } + + return v +} + +// GetOrFile Attempts to resolve 'key' as an environment variable. +// Failing that, it will check to see if '_FILE' exists. +// If so, it will attempt to read from the referenced file to populate a value. +func GetOrFile(envVar string) string { + envVarValue := os.Getenv(envVar) + if envVarValue != "" { + return envVarValue + } + + fileVar := envVar + "_FILE" + fileVarValue := os.Getenv(fileVar) + if fileVarValue == "" { + return envVarValue + } + + fileContents, err := ioutil.ReadFile(fileVarValue) + if err != nil { + log.Printf("Failed to read the file %s (defined by env var %s): %s", fileVarValue, fileVar, err) + return "" + } + + return strings.TrimSuffix(string(fileContents), "\n") +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/acmedns/acmedns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/acmedns/acmedns.go new file mode 100644 index 000000000..fe82f45f3 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/acmedns/acmedns.go @@ -0,0 +1,162 @@ +// Package acmedns implements a DNS provider for solving DNS-01 challenges using Joohoi's acme-dns project. +// For more information see the ACME-DNS homepage: https://github.com/joohoi/acme-dns +package acmedns + +import ( + "errors" + "fmt" + + "github.com/cpu/goacmedns" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const ( + // envNamespace is the prefix for ACME-DNS environment variables. + envNamespace = "ACME_DNS_" + // apiBaseEnvVar is the environment variable name for the ACME-DNS API address + // (e.g. https://acmedns.your-domain.com). + apiBaseEnvVar = envNamespace + "API_BASE" + // storagePathEnvVar is the environment variable name for the ACME-DNS JSON account data file. + // A per-domain account will be registered/persisted to this file and used for TXT updates. + storagePathEnvVar = envNamespace + "STORAGE_PATH" +) + +// acmeDNSClient is an interface describing the goacmedns.Client functions the DNSProvider uses. +// It makes it easier for tests to shim a mock Client into the DNSProvider. +type acmeDNSClient interface { + // UpdateTXTRecord updates the provided account's TXT record + // to the given value or returns an error. + UpdateTXTRecord(goacmedns.Account, string) error + // RegisterAccount registers and returns a new account + // with the given allowFrom restriction or returns an error. + RegisterAccount([]string) (goacmedns.Account, error) +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface for +// an ACME-DNS server. +type DNSProvider struct { + client acmeDNSClient + storage goacmedns.Storage +} + +// NewDNSProvider creates an ACME-DNS provider using file based account storage. +// Its configuration is loaded from the environment by reading apiBaseEnvVar and storagePathEnvVar. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get(apiBaseEnvVar, storagePathEnvVar) + if err != nil { + return nil, fmt.Errorf("acme-dns: %v", err) + } + + client := goacmedns.NewClient(values[apiBaseEnvVar]) + storage := goacmedns.NewFileStorage(values[storagePathEnvVar], 0600) + return NewDNSProviderClient(client, storage) +} + +// NewDNSProviderClient creates an ACME-DNS DNSProvider with the given acmeDNSClient and goacmedns.Storage. +func NewDNSProviderClient(client acmeDNSClient, storage goacmedns.Storage) (*DNSProvider, error) { + if client == nil { + return nil, errors.New("ACME-DNS Client must be not nil") + } + + if storage == nil { + return nil, errors.New("ACME-DNS Storage must be not nil") + } + + return &DNSProvider{ + client: client, + storage: storage, + }, nil +} + +// ErrCNAMERequired is returned by Present when the Domain indicated had no +// existing ACME-DNS account in the Storage and additional setup is required. +// The user must create a CNAME in the DNS zone for Domain that aliases FQDN +// to Target in order to complete setup for the ACME-DNS account that was created. +type ErrCNAMERequired struct { + // The Domain that is being issued for. + Domain string + // The alias of the CNAME (left hand DNS label). + FQDN string + // The RDATA of the CNAME (right hand side, canonical name). + Target string +} + +// Error returns a descriptive message for the ErrCNAMERequired instance telling +// the user that a CNAME needs to be added to the DNS zone of c.Domain before +// the ACME-DNS hook will work. The CNAME to be created should be of the form: +// {{ c.FQDN }} CNAME {{ c.Target }} +func (e ErrCNAMERequired) Error() string { + return fmt.Sprintf("acme-dns: new account created for %q. "+ + "To complete setup for %q you must provision the following "+ + "CNAME in your DNS zone and re-run this provider when it is "+ + "in place:\n"+ + "%s CNAME %s.", + e.Domain, e.Domain, e.FQDN, e.Target) +} + +// Present creates a TXT record to fulfill the DNS-01 challenge. +// If there is an existing account for the domain in the provider's storage +// then it will be used to set the challenge response TXT record with the ACME-DNS server and issuance will continue. +// If there is not an account for the given domain present in the DNSProvider storage +// one will be created and registered with the ACME DNS server and an ErrCNAMERequired error is returned. +// This will halt issuance and indicate to the user that a one-time manual setup is required for the domain. +func (d *DNSProvider) Present(domain, _, keyAuth string) error { + // Compute the challenge response FQDN and TXT value for the domain based + // on the keyAuth. + fqdn, value := dns01.GetRecord(domain, keyAuth) + + // Check if credentials were previously saved for this domain. + account, err := d.storage.Fetch(domain) + // Errors other than goacmeDNS.ErrDomainNotFound are unexpected. + if err != nil && err != goacmedns.ErrDomainNotFound { + return err + } + if err == goacmedns.ErrDomainNotFound { + // The account did not exist. Create a new one and return an error + // indicating the required one-time manual CNAME setup. + return d.register(domain, fqdn) + } + + // Update the acme-dns TXT record. + return d.client.UpdateTXTRecord(account, value) +} + +// CleanUp removes the record matching the specified parameters. It is not +// implemented for the ACME-DNS provider. +func (d *DNSProvider) CleanUp(_, _, _ string) error { + // ACME-DNS doesn't support the notion of removing a record. + // For users of ACME-DNS it is expected the stale records remain in-place. + return nil +} + +// register creates a new ACME-DNS account for the given domain. +// If account creation works as expected a ErrCNAMERequired error is returned describing +// the one-time manual CNAME setup required to complete setup of the ACME-DNS hook for the domain. +// If any other error occurs it is returned as-is. +func (d *DNSProvider) register(domain, fqdn string) error { + // TODO(@cpu): Read CIDR whitelists from the environment + newAcct, err := d.client.RegisterAccount(nil) + if err != nil { + return err + } + + // Store the new account in the storage and call save to persist the data. + err = d.storage.Put(domain, newAcct) + if err != nil { + return err + } + err = d.storage.Save() + if err != nil { + return err + } + + // Stop issuance by returning an error. + // The user needs to perform a manual one-time CNAME setup in their DNS zone + // to complete the setup of the new account we created. + return ErrCNAMERequired{ + Domain: domain, + FQDN: fqdn, + Target: newAcct.FullDomain, + } +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/acmedns/acmedns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/acmedns/acmedns.toml new file mode 100644 index 000000000..2fb4a0d81 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/acmedns/acmedns.toml @@ -0,0 +1,16 @@ +Name = "Joohoi's ACME-DNS" +Description = '''''' +URL = "https://github.com/joohoi/acme-dns" +Code = "acme-dns" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + ACME_DNS_API_BASE = "The ACME-DNS API address" + ACME_DNS_STORAGE_PATH = "The ACME-DNS JSON account data file. A per-domain account will be registered/persisted to this file and used for TXT updates." + +[Links] + API = "https://github.com/joohoi/acme-dns#api" + GoClient = "https://github.com/cpu/goacmedns" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/alidns/alidns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/alidns/alidns.go new file mode 100644 index 000000000..da99495f4 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/alidns/alidns.go @@ -0,0 +1,220 @@ +// Package alidns implements a DNS provider for solving the DNS-01 challenge using Alibaba Cloud DNS. +package alidns + +import ( + "errors" + "fmt" + "strings" + "time" + + "github.com/aliyun/alibaba-cloud-sdk-go/sdk" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" + "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" + "github.com/aliyun/alibaba-cloud-sdk-go/services/alidns" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const defaultRegionID = "cn-hangzhou" + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + SecretKey string + RegionID string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPTimeout time.Duration +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("ALICLOUD_TTL", 600), + PropagationTimeout: env.GetOrDefaultSecond("ALICLOUD_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("ALICLOUD_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPTimeout: env.GetOrDefaultSecond("ALICLOUD_HTTP_TIMEOUT", 10*time.Second), + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config + client *alidns.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for Alibaba Cloud DNS. +// Credentials must be passed in the environment variables: ALICLOUD_ACCESS_KEY and ALICLOUD_SECRET_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("ALICLOUD_ACCESS_KEY", "ALICLOUD_SECRET_KEY") + if err != nil { + return nil, fmt.Errorf("alicloud: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["ALICLOUD_ACCESS_KEY"] + config.SecretKey = values["ALICLOUD_SECRET_KEY"] + config.RegionID = env.GetOrFile("ALICLOUD_REGION_ID") + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for alidns. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("alicloud: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" || config.SecretKey == "" { + return nil, fmt.Errorf("alicloud: credentials missing") + } + + if len(config.RegionID) == 0 { + config.RegionID = defaultRegionID + } + + conf := sdk.NewConfig().WithTimeout(config.HTTPTimeout) + credential := credentials.NewAccessKeyCredential(config.APIKey, config.SecretKey) + + client, err := alidns.NewClientWithOptions(config.RegionID, conf, credential) + if err != nil { + return nil, fmt.Errorf("alicloud: credentials failed: %v", err) + } + + return &DNSProvider{config: config, client: client}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + _, zoneName, err := d.getHostedZone(domain) + if err != nil { + return fmt.Errorf("alicloud: %v", err) + } + + recordAttributes := d.newTxtRecord(zoneName, fqdn, value) + + _, err = d.client.AddDomainRecord(recordAttributes) + if err != nil { + return fmt.Errorf("alicloud: API call failed: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + records, err := d.findTxtRecords(domain, fqdn) + if err != nil { + return fmt.Errorf("alicloud: %v", err) + } + + _, _, err = d.getHostedZone(domain) + if err != nil { + return fmt.Errorf("alicloud: %v", err) + } + + for _, rec := range records { + request := alidns.CreateDeleteDomainRecordRequest() + request.RecordId = rec.RecordId + _, err = d.client.DeleteDomainRecord(request) + if err != nil { + return fmt.Errorf("alicloud: %v", err) + } + } + return nil +} + +func (d *DNSProvider) getHostedZone(domain string) (string, string, error) { + request := alidns.CreateDescribeDomainsRequest() + + var domains []alidns.Domain + startPage := 1 + + for { + request.PageNumber = requests.NewInteger(startPage) + + response, err := d.client.DescribeDomains(request) + if err != nil { + return "", "", fmt.Errorf("API call failed: %v", err) + } + + domains = append(domains, response.Domains.Domain...) + + if response.PageNumber*response.PageSize >= response.TotalCount { + break + } + + startPage++ + } + + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return "", "", err + } + + var hostedZone alidns.Domain + for _, zone := range domains { + if zone.DomainName == dns01.UnFqdn(authZone) { + hostedZone = zone + } + } + + if hostedZone.DomainId == "" { + return "", "", fmt.Errorf("zone %s not found in AliDNS for domain %s", authZone, domain) + } + return fmt.Sprintf("%v", hostedZone.DomainId), hostedZone.DomainName, nil +} + +func (d *DNSProvider) newTxtRecord(zone, fqdn, value string) *alidns.AddDomainRecordRequest { + request := alidns.CreateAddDomainRecordRequest() + request.Type = "TXT" + request.DomainName = zone + request.RR = d.extractRecordName(fqdn, zone) + request.Value = value + request.TTL = requests.NewInteger(d.config.TTL) + return request +} + +func (d *DNSProvider) findTxtRecords(domain, fqdn string) ([]alidns.Record, error) { + _, zoneName, err := d.getHostedZone(domain) + if err != nil { + return nil, err + } + + request := alidns.CreateDescribeDomainRecordsRequest() + request.DomainName = zoneName + request.PageSize = requests.NewInteger(500) + + var records []alidns.Record + + result, err := d.client.DescribeDomainRecords(request) + if err != nil { + return records, fmt.Errorf("API call has failed: %v", err) + } + + recordName := d.extractRecordName(fqdn, zoneName) + for _, record := range result.DomainRecords.Record { + if record.RR == recordName { + records = append(records, record) + } + } + return records, nil +} + +func (d *DNSProvider) extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/alidns/alidns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/alidns/alidns.toml new file mode 100644 index 000000000..4f613f91e --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/alidns/alidns.toml @@ -0,0 +1,21 @@ +Name = "Alibaba Cloud DNS" +Description = '''''' +URL = "https://www.alibabacloud.com/product/dns" +Code = "alidns" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + ALICLOUD_ACCESS_KEY = "Access key ID" + ALICLOUD_SECRET_KEY = "Access Key secret" + [Configuration.Additional] + ALICLOUD_POLLING_INTERVAL = "Time between DNS propagation check" + ALICLOUD_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + ALICLOUD_TTL = "The TTL of the TXT record used for the DNS challenge" + ALICLOUD_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.alibabacloud.com/help/doc-detail/42875.htm" + GoClient = "https://github.com/aliyun/alibaba-cloud-sdk-go" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/auroradns/auroradns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/auroradns/auroradns.go new file mode 100644 index 000000000..9d40a14e6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/auroradns/auroradns.go @@ -0,0 +1,191 @@ +// Package auroradns implements a DNS provider for solving the DNS-01 challenge using Aurora DNS. +package auroradns + +import ( + "errors" + "fmt" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/nrdcg/auroradns" +) + +const defaultBaseURL = "https://api.auroradns.eu" + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + UserID string + Key string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("AURORA_TTL", 300), + PropagationTimeout: env.GetOrDefaultSecond("AURORA_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("AURORA_POLLING_INTERVAL", dns01.DefaultPollingInterval), + } +} + +// DNSProvider describes a provider for AuroraDNS +type DNSProvider struct { + recordIDs map[string]string + recordIDsMu sync.Mutex + config *Config + client *auroradns.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for AuroraDNS. +// Credentials must be passed in the environment variables: +// AURORA_USER_ID and AURORA_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("AURORA_USER_ID", "AURORA_KEY") + if err != nil { + return nil, fmt.Errorf("aurora: %v", err) + } + + config := NewDefaultConfig() + config.BaseURL = env.GetOrFile("AURORA_ENDPOINT") + config.UserID = values["AURORA_USER_ID"] + config.Key = values["AURORA_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for AuroraDNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("aurora: the configuration of the DNS provider is nil") + } + + if config.UserID == "" || config.Key == "" { + return nil, errors.New("aurora: some credentials information are missing") + } + + if config.BaseURL == "" { + config.BaseURL = defaultBaseURL + } + + tr, err := auroradns.NewTokenTransport(config.UserID, config.Key) + if err != nil { + return nil, fmt.Errorf("aurora: %v", err) + } + + client, err := auroradns.NewClient(tr.Client(), auroradns.WithBaseURL(config.BaseURL)) + if err != nil { + return nil, fmt.Errorf("aurora: %v", err) + } + + return &DNSProvider{ + config: config, + client: client, + recordIDs: make(map[string]string), + }, nil +} + +// Present creates a record with a secret +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return fmt.Errorf("aurora: could not determine zone for domain: '%s'. %s", domain, err) + } + + // 1. Aurora will happily create the TXT record when it is provided a fqdn, + // but it will only appear in the control panel and will not be + // propagated to DNS servers. Extract and use subdomain instead. + // 2. A trailing dot in the fqdn will cause Aurora to add a trailing dot to + // the subdomain, resulting in _acme-challenge.. rather + // than _acme-challenge. + + subdomain := fqdn[0 : len(fqdn)-len(authZone)-1] + + authZone = dns01.UnFqdn(authZone) + + zone, err := d.getZoneInformationByName(authZone) + if err != nil { + return fmt.Errorf("aurora: could not create record: %v", err) + } + + record := auroradns.Record{ + RecordType: "TXT", + Name: subdomain, + Content: value, + TTL: d.config.TTL, + } + + newRecord, _, err := d.client.CreateRecord(zone.ID, record) + if err != nil { + return fmt.Errorf("aurora: could not create record: %v", err) + } + + d.recordIDsMu.Lock() + d.recordIDs[fqdn] = newRecord.ID + d.recordIDsMu.Unlock() + + return nil +} + +// CleanUp removes a given record that was generated by Present +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + d.recordIDsMu.Lock() + recordID, ok := d.recordIDs[fqdn] + d.recordIDsMu.Unlock() + + if !ok { + return fmt.Errorf("unknown recordID for %q", fqdn) + } + + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return fmt.Errorf("could not determine zone for domain: %q. %v", domain, err) + } + + authZone = dns01.UnFqdn(authZone) + + zone, err := d.getZoneInformationByName(authZone) + if err != nil { + return err + } + + _, _, err = d.client.DeleteRecord(zone.ID, recordID) + if err != nil { + return err + } + + d.recordIDsMu.Lock() + delete(d.recordIDs, fqdn) + d.recordIDsMu.Unlock() + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) getZoneInformationByName(name string) (auroradns.Zone, error) { + zs, _, err := d.client.ListZones() + if err != nil { + return auroradns.Zone{}, err + } + + for _, element := range zs { + if element.Name == name { + return element, nil + } + } + + return auroradns.Zone{}, fmt.Errorf("could not find Zone record") +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/auroradns/auroradns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/auroradns/auroradns.toml new file mode 100644 index 000000000..be2e946ac --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/auroradns/auroradns.toml @@ -0,0 +1,21 @@ +Name = "Aurora DNS" +Description = '''''' +URL = "https://www.pcextreme.com/aurora/dns" +Code = "auroradns" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + AURORA_USER_ID = "User ID" + AURORA_KEY = "User API key" + AURORA_ENDPOINT = "API endpoint URL" + [Configuration.Additional] + AURORA_POLLING_INTERVAL = "Time between DNS propagation check" + AURORA_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + AURORA_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://libcloud.readthedocs.io/en/latest/dns/drivers/auroradns.html#api-docs" + GoClient = "https://github.com/nrdcg/auroradns" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/azure/azure.go b/vendor/github.com/go-acme/lego/v3/providers/dns/azure/azure.go new file mode 100644 index 000000000..eb6358c14 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/azure/azure.go @@ -0,0 +1,274 @@ +// Package azure implements a DNS provider for solving the DNS-01 challenge using azure DNS. +// Azure doesn't like trailing dots on domain names, most of the acme code does. +package azure + +import ( + "context" + "errors" + "fmt" + "io/ioutil" + "net/http" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2017-09-01/dns" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/azure/auth" + "github.com/Azure/go-autorest/autorest/to" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const defaultMetadataEndpoint = "http://169.254.169.254" + +// Config is used to configure the creation of the DNSProvider +type Config struct { + // optional if using instance metadata service + ClientID string + ClientSecret string + TenantID string + + SubscriptionID string + ResourceGroup string + + MetadataEndpoint string + + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("AZURE_TTL", 60), + PropagationTimeout: env.GetOrDefaultSecond("AZURE_PROPAGATION_TIMEOUT", 2*time.Minute), + PollingInterval: env.GetOrDefaultSecond("AZURE_POLLING_INTERVAL", 2*time.Second), + MetadataEndpoint: env.GetOrFile("AZURE_METADATA_ENDPOINT"), + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config + authorizer autorest.Authorizer +} + +// NewDNSProvider returns a DNSProvider instance configured for azure. +// Credentials can be passed in the environment variables: +// AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_SUBSCRIPTION_ID, AZURE_TENANT_ID, AZURE_RESOURCE_GROUP +// If the credentials are _not_ set via the environment, +// then it will attempt to get a bearer token via the instance metadata service. +// see: https://github.com/Azure/go-autorest/blob/v10.14.0/autorest/azure/auth/auth.go#L38-L42 +func NewDNSProvider() (*DNSProvider, error) { + config := NewDefaultConfig() + config.SubscriptionID = env.GetOrFile("AZURE_SUBSCRIPTION_ID") + config.ResourceGroup = env.GetOrFile("AZURE_RESOURCE_GROUP") + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Azure. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("azure: the configuration of the DNS provider is nil") + } + + if config.HTTPClient == nil { + config.HTTPClient = http.DefaultClient + } + + authorizer, err := getAuthorizer(config) + if err != nil { + return nil, err + } + + if config.SubscriptionID == "" { + subsID, err := getMetadata(config, "subscriptionId") + if err != nil { + return nil, fmt.Errorf("azure: %v", err) + } + + if subsID == "" { + return nil, errors.New("azure: SubscriptionID is missing") + } + config.SubscriptionID = subsID + } + + if config.ResourceGroup == "" { + resGroup, err := getMetadata(config, "resourceGroupName") + if err != nil { + return nil, fmt.Errorf("azure: %v", err) + } + + if resGroup == "" { + return nil, errors.New("azure: ResourceGroup is missing") + } + config.ResourceGroup = resGroup + } + + return &DNSProvider{config: config, authorizer: authorizer}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + ctx := context.Background() + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZoneID(ctx, fqdn) + if err != nil { + return fmt.Errorf("azure: %v", err) + } + + rsc := dns.NewRecordSetsClient(d.config.SubscriptionID) + rsc.Authorizer = d.authorizer + + relative := toRelativeRecord(fqdn, dns01.ToFqdn(zone)) + + // Get existing record set + rset, err := rsc.Get(ctx, d.config.ResourceGroup, zone, relative, dns.TXT) + if err != nil { + detailedError, ok := err.(autorest.DetailedError) + if !ok || detailedError.StatusCode != http.StatusNotFound { + return fmt.Errorf("azure: %v", err) + } + } + + // Construct unique TXT records using map + uniqRecords := map[string]struct{}{value: {}} + if rset.RecordSetProperties != nil && rset.TxtRecords != nil { + for _, txtRecord := range *rset.TxtRecords { + // Assume Value doesn't contain multiple strings + if txtRecord.Value != nil && len(*txtRecord.Value) > 0 { + uniqRecords[(*txtRecord.Value)[0]] = struct{}{} + } + } + } + + var txtRecords []dns.TxtRecord + for txt := range uniqRecords { + txtRecords = append(txtRecords, dns.TxtRecord{Value: &[]string{txt}}) + } + + rec := dns.RecordSet{ + Name: &relative, + RecordSetProperties: &dns.RecordSetProperties{ + TTL: to.Int64Ptr(int64(d.config.TTL)), + TxtRecords: &txtRecords, + }, + } + + _, err = rsc.CreateOrUpdate(ctx, d.config.ResourceGroup, zone, relative, dns.TXT, rec, "", "") + if err != nil { + return fmt.Errorf("azure: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + ctx := context.Background() + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZoneID(ctx, fqdn) + if err != nil { + return fmt.Errorf("azure: %v", err) + } + + relative := toRelativeRecord(fqdn, dns01.ToFqdn(zone)) + rsc := dns.NewRecordSetsClient(d.config.SubscriptionID) + rsc.Authorizer = d.authorizer + + _, err = rsc.Delete(ctx, d.config.ResourceGroup, zone, relative, dns.TXT, "") + if err != nil { + return fmt.Errorf("azure: %v", err) + } + return nil +} + +// Checks that azure has a zone for this domain name. +func (d *DNSProvider) getHostedZoneID(ctx context.Context, fqdn string) (string, error) { + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return "", err + } + + dc := dns.NewZonesClient(d.config.SubscriptionID) + dc.Authorizer = d.authorizer + + zone, err := dc.Get(ctx, d.config.ResourceGroup, dns01.UnFqdn(authZone)) + if err != nil { + return "", err + } + + // zone.Name shouldn't have a trailing dot(.) + return to.String(zone.Name), nil +} + +// Returns the relative record to the domain +func toRelativeRecord(domain, zone string) string { + return dns01.UnFqdn(strings.TrimSuffix(domain, zone)) +} + +func getAuthorizer(config *Config) (autorest.Authorizer, error) { + if config.ClientID != "" && config.ClientSecret != "" && config.TenantID != "" { + oauthConfig, err := adal.NewOAuthConfig(azure.PublicCloud.ActiveDirectoryEndpoint, config.TenantID) + if err != nil { + return nil, err + } + + spt, err := adal.NewServicePrincipalToken(*oauthConfig, config.ClientID, config.ClientSecret, azure.PublicCloud.ResourceManagerEndpoint) + if err != nil { + return nil, err + } + + spt.SetSender(config.HTTPClient) + return autorest.NewBearerAuthorizer(spt), nil + } + + return auth.NewAuthorizerFromEnvironment() +} + +// Fetches metadata from environment or he instance metadata service +// borrowed from https://github.com/Microsoft/azureimds/blob/master/imdssample.go +func getMetadata(config *Config, field string) (string, error) { + metadataEndpoint := config.MetadataEndpoint + if len(metadataEndpoint) == 0 { + metadataEndpoint = defaultMetadataEndpoint + } + + resource := fmt.Sprintf("%s/metadata/instance/compute/%s", metadataEndpoint, field) + req, err := http.NewRequest(http.MethodGet, resource, nil) + if err != nil { + return "", err + } + + req.Header.Add("Metadata", "True") + + q := req.URL.Query() + q.Add("format", "text") + q.Add("api-version", "2017-12-01") + req.URL.RawQuery = q.Encode() + + resp, err := config.HTTPClient.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return string(respBody), nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/azure/azure.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/azure/azure.toml new file mode 100644 index 000000000..b28bcbd90 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/azure/azure.toml @@ -0,0 +1,25 @@ +Name = "Azure" +Description = '''''' +URL = "https://azure.microsoft.com/services/dns/" +Code = "azure" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + AZURE_CLIENT_ID = "Client ID" + AZURE_CLIENT_SECRET = "Client secret" + AZURE_SUBSCRIPTION_ID = "Subscription ID" + AZURE_TENANT_ID = "Tenant ID" + AZURE_RESOURCE_GROUP = "Resource group" + 'instance metadata service' = "If the credentials are **not** set via the environment, then it will attempt to get a bearer token via the [instance metadata service](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service)." + [Configuration.Additional] + AZURE_POLLING_INTERVAL = "Time between DNS propagation check" + AZURE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + AZURE_TTL = "The TTL of the TXT record used for the DNS challenge" + AZURE_METADATA_ENDPOINT = "Metadata Service endpoint URL" + +[Links] + API = "https://docs.microsoft.com/en-us/go/azure/" + GoClient = "https://github.com/Azure/azure-sdk-for-go" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/bindman/bindman.go b/vendor/github.com/go-acme/lego/v3/providers/dns/bindman/bindman.go new file mode 100644 index 000000000..fe3380030 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/bindman/bindman.go @@ -0,0 +1,99 @@ +// Package bindman implements a DNS provider for solving the DNS-01 challenge. +package bindman + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/labbsr0x/bindman-dns-webhook/src/client" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + PropagationTimeout time.Duration + PollingInterval time.Duration + BaseURL string + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("BINDMAN_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("BINDMAN_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("BINDMAN_HTTP_TIMEOUT", time.Minute), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses +// Bindman's Address Manager REST API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + client *client.DNSWebhookClient +} + +// NewDNSProvider returns a DNSProvider instance configured for Bindman. +// BINDMAN_MANAGER_ADDRESS should have the scheme, hostname, and port (if required) of the authoritative Bindman Manager server. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("BINDMAN_MANAGER_ADDRESS") + if err != nil { + return nil, fmt.Errorf("bindman: %v", err) + } + + config := NewDefaultConfig() + config.BaseURL = values["BINDMAN_MANAGER_ADDRESS"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Bindman. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("bindman: the configuration of the DNS provider is nil") + } + + if config.BaseURL == "" { + return nil, fmt.Errorf("bindman: bindman manager address missing") + } + + bClient, err := client.New(config.BaseURL, config.HTTPClient) + if err != nil { + return nil, fmt.Errorf("bindman: %v", err) + } + + return &DNSProvider{config: config, client: bClient}, nil +} + +// Present creates a TXT record using the specified parameters. +// This will *not* create a subzone to contain the TXT record, +// so make sure the FQDN specified is within an extant zone. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + if err := d.client.AddRecord(fqdn, "TXT", value); err != nil { + return fmt.Errorf("bindman: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + if err := d.client.RemoveRecord(fqdn, "TXT"); err != nil { + return fmt.Errorf("bindman: %v", err) + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/bindman/bindman.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/bindman/bindman.toml new file mode 100644 index 000000000..92b8a539c --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/bindman/bindman.toml @@ -0,0 +1,22 @@ +Name = "Bindman" +Description = '''''' +URL = "https://github.com/labbsr0x/bindman-dns-webhook" +Code = "bindman" +Since = "v2.6.0" + +Example = ''' +BINDMAN_MANAGER_ADDRESS= \ +lego --dns bindman --domains my.domain.com --email my@email.com run +''' + +[Configuration] + [Configuration.Credentials] + BINDMAN_MANAGER_ADDRESS = "The server URL, should have scheme, hostname, and port (if required) of the Bindman-DNS Manager server" + [Configuration.Additional] + BINDMAN_POLLING_INTERVAL = "Time between DNS propagation check" + BINDMAN_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + BINDMAN_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://gitlab.isc.org/isc-projects/bind9" + GoClient = "https://github.com/labbsr0x/bindman-dns-webhook" \ No newline at end of file diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/bluecat.go b/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/bluecat.go new file mode 100644 index 000000000..a6b31a2b2 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/bluecat.go @@ -0,0 +1,201 @@ +// Package bluecat implements a DNS provider for solving the DNS-01 challenge using a self-hosted Bluecat Address Manager. +package bluecat + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const ( + configType = "Configuration" + viewType = "View" + zoneType = "Zone" + txtType = "TXTRecord" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + UserName string + Password string + ConfigName string + DNSView string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("BLUECAT_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("BLUECAT_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("BLUECAT_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("BLUECAT_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses +// Bluecat's Address Manager REST API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + token string +} + +// NewDNSProvider returns a DNSProvider instance configured for Bluecat DNS. +// Credentials must be passed in the environment variables: BLUECAT_SERVER_URL, BLUECAT_USER_NAME and BLUECAT_PASSWORD. +// BLUECAT_SERVER_URL should have the scheme, hostname, and port (if required) of the authoritative Bluecat BAM server. +// The REST endpoint will be appended. +// In addition, the Configuration name and external DNS View Name must be passed in BLUECAT_CONFIG_NAME and BLUECAT_DNS_VIEW +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("BLUECAT_SERVER_URL", "BLUECAT_USER_NAME", "BLUECAT_PASSWORD", "BLUECAT_CONFIG_NAME", "BLUECAT_DNS_VIEW") + if err != nil { + return nil, fmt.Errorf("bluecat: %v", err) + } + + config := NewDefaultConfig() + config.BaseURL = values["BLUECAT_SERVER_URL"] + config.UserName = values["BLUECAT_USER_NAME"] + config.Password = values["BLUECAT_PASSWORD"] + config.ConfigName = values["BLUECAT_CONFIG_NAME"] + config.DNSView = values["BLUECAT_DNS_VIEW"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Bluecat DNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("bluecat: the configuration of the DNS provider is nil") + } + + if config.BaseURL == "" || config.UserName == "" || config.Password == "" || config.ConfigName == "" || config.DNSView == "" { + return nil, fmt.Errorf("bluecat: credentials missing") + } + + return &DNSProvider{config: config}, nil +} + +// Present creates a TXT record using the specified parameters +// This will *not* create a subzone to contain the TXT record, +// so make sure the FQDN specified is within an extant zone. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + err := d.login() + if err != nil { + return err + } + + viewID, err := d.lookupViewID(d.config.DNSView) + if err != nil { + return err + } + + parentZoneID, name, err := d.lookupParentZoneID(viewID, fqdn) + if err != nil { + return err + } + + queryArgs := map[string]string{ + "parentId": strconv.FormatUint(uint64(parentZoneID), 10), + } + + body := bluecatEntity{ + Name: name, + Type: "TXTRecord", + Properties: fmt.Sprintf("ttl=%d|absoluteName=%s|txt=%s|", d.config.TTL, fqdn, value), + } + + resp, err := d.sendRequest(http.MethodPost, "addEntity", body, queryArgs) + if err != nil { + return err + } + defer resp.Body.Close() + + addTxtBytes, _ := ioutil.ReadAll(resp.Body) + addTxtResp := string(addTxtBytes) + // addEntity responds only with body text containing the ID of the created record + _, err = strconv.ParseUint(addTxtResp, 10, 64) + if err != nil { + return fmt.Errorf("bluecat: addEntity request failed: %s", addTxtResp) + } + + err = d.deploy(parentZoneID) + if err != nil { + return err + } + + return d.logout() +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + err := d.login() + if err != nil { + return err + } + + viewID, err := d.lookupViewID(d.config.DNSView) + if err != nil { + return err + } + + parentID, name, err := d.lookupParentZoneID(viewID, fqdn) + if err != nil { + return err + } + + queryArgs := map[string]string{ + "parentId": strconv.FormatUint(uint64(parentID), 10), + "name": name, + "type": txtType, + } + + resp, err := d.sendRequest(http.MethodGet, "getEntityByName", nil, queryArgs) + if err != nil { + return err + } + defer resp.Body.Close() + + var txtRec entityResponse + err = json.NewDecoder(resp.Body).Decode(&txtRec) + if err != nil { + return fmt.Errorf("bluecat: %v", err) + } + queryArgs = map[string]string{ + "objectId": strconv.FormatUint(uint64(txtRec.ID), 10), + } + + resp, err = d.sendRequest(http.MethodDelete, http.MethodDelete, nil, queryArgs) + if err != nil { + return err + } + defer resp.Body.Close() + + err = d.deploy(parentID) + if err != nil { + return err + } + + return d.logout() +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/bluecat.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/bluecat.toml new file mode 100644 index 000000000..a6a91fa0a --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/bluecat.toml @@ -0,0 +1,20 @@ +Name = "Bluecat" +Description = '''''' +URL = "https://www.bluecatnetworks.com" +Code = "bluecat" +Since = "v0.5.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + BLUECAT_SERVER_URL = "The server URL, should have scheme, hostname, and port (if required) of the authoritative Bluecat BAM serve" + BLUECAT_USER_NAME = "API username" + BLUECAT_PASSWORD = "API password" + BLUECAT_CONFIG_NAME = "Configuration name" + BLUECAT_DNS_VIEW = "External DNS View Name" + [Configuration.Additional] + BLUECAT_POLLING_INTERVAL = "Time between DNS propagation check" + BLUECAT_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + BLUECAT_TTL = "The TTL of the TXT record used for the DNS challenge" + BLUECAT_HTTP_TIMEOUT = "API request timeout" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/client.go new file mode 100644 index 000000000..d910594ce --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/bluecat/client.go @@ -0,0 +1,249 @@ +package bluecat + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "regexp" + "strconv" + "strings" +) + +// JSON body for Bluecat entity requests and responses +type bluecatEntity struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + Properties string `json:"properties"` +} + +type entityResponse struct { + ID uint `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Properties string `json:"properties"` +} + +// Starts a new Bluecat API Session. Authenticates using customerName, userName, +// password and receives a token to be used in for subsequent requests. +func (d *DNSProvider) login() error { + queryArgs := map[string]string{ + "username": d.config.UserName, + "password": d.config.Password, + } + + resp, err := d.sendRequest(http.MethodGet, "login", nil, queryArgs) + if err != nil { + return err + } + defer resp.Body.Close() + + authBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("bluecat: %v", err) + } + authResp := string(authBytes) + + if strings.Contains(authResp, "Authentication Error") { + msg := strings.Trim(authResp, "\"") + return fmt.Errorf("bluecat: request failed: %s", msg) + } + + // Upon success, API responds with "Session Token-> BAMAuthToken: dQfuRMTUxNjc3MjcyNDg1ODppcGFybXM= <- for User : username" + d.token = regexp.MustCompile("BAMAuthToken: [^ ]+").FindString(authResp) + return nil +} + +// Destroys Bluecat Session +func (d *DNSProvider) logout() error { + if len(d.token) == 0 { + // nothing to do + return nil + } + + resp, err := d.sendRequest(http.MethodGet, "logout", nil, nil) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("bluecat: request failed to delete session with HTTP status code %d", resp.StatusCode) + } + + authBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + authResp := string(authBytes) + + if !strings.Contains(authResp, "successfully") { + msg := strings.Trim(authResp, "\"") + return fmt.Errorf("bluecat: request failed to delete session: %s", msg) + } + + d.token = "" + + return nil +} + +// Lookup the entity ID of the configuration named in our properties +func (d *DNSProvider) lookupConfID() (uint, error) { + queryArgs := map[string]string{ + "parentId": strconv.Itoa(0), + "name": d.config.ConfigName, + "type": configType, + } + + resp, err := d.sendRequest(http.MethodGet, "getEntityByName", nil, queryArgs) + if err != nil { + return 0, err + } + defer resp.Body.Close() + + var conf entityResponse + err = json.NewDecoder(resp.Body).Decode(&conf) + if err != nil { + return 0, fmt.Errorf("bluecat: %v", err) + } + return conf.ID, nil +} + +// Find the DNS view with the given name within +func (d *DNSProvider) lookupViewID(viewName string) (uint, error) { + confID, err := d.lookupConfID() + if err != nil { + return 0, err + } + + queryArgs := map[string]string{ + "parentId": strconv.FormatUint(uint64(confID), 10), + "name": viewName, + "type": viewType, + } + + resp, err := d.sendRequest(http.MethodGet, "getEntityByName", nil, queryArgs) + if err != nil { + return 0, err + } + defer resp.Body.Close() + + var view entityResponse + err = json.NewDecoder(resp.Body).Decode(&view) + if err != nil { + return 0, fmt.Errorf("bluecat: %v", err) + } + + return view.ID, nil +} + +// Return the entityId of the parent zone by recursing from the root view +// Also return the simple name of the host +func (d *DNSProvider) lookupParentZoneID(viewID uint, fqdn string) (uint, string, error) { + parentViewID := viewID + name := "" + + if fqdn != "" { + zones := strings.Split(strings.Trim(fqdn, "."), ".") + last := len(zones) - 1 + name = zones[0] + + for i := last; i > -1; i-- { + zoneID, err := d.getZone(parentViewID, zones[i]) + if err != nil || zoneID == 0 { + return parentViewID, name, err + } + if i > 0 { + name = strings.Join(zones[0:i], ".") + } + parentViewID = zoneID + } + } + + return parentViewID, name, nil +} + +// Get the DNS zone with the specified name under the parentId +func (d *DNSProvider) getZone(parentID uint, name string) (uint, error) { + queryArgs := map[string]string{ + "parentId": strconv.FormatUint(uint64(parentID), 10), + "name": name, + "type": zoneType, + } + + resp, err := d.sendRequest(http.MethodGet, "getEntityByName", nil, queryArgs) + + // Return an empty zone if the named zone doesn't exist + if resp != nil && resp.StatusCode == http.StatusNotFound { + return 0, fmt.Errorf("bluecat: could not find zone named %s", name) + } + if err != nil { + return 0, err + } + defer resp.Body.Close() + + var zone entityResponse + err = json.NewDecoder(resp.Body).Decode(&zone) + if err != nil { + return 0, fmt.Errorf("bluecat: %v", err) + } + + return zone.ID, nil +} + +// Deploy the DNS config for the specified entity to the authoritative servers +func (d *DNSProvider) deploy(entityID uint) error { + queryArgs := map[string]string{ + "entityId": strconv.FormatUint(uint64(entityID), 10), + } + + resp, err := d.sendRequest(http.MethodPost, "quickDeploy", nil, queryArgs) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +// Send a REST request, using query parameters specified. The Authorization +// header will be set if we have an active auth token +func (d *DNSProvider) sendRequest(method, resource string, payload interface{}, queryArgs map[string]string) (*http.Response, error) { + url := fmt.Sprintf("%s/Services/REST/v1/%s", d.config.BaseURL, resource) + + body, err := json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("bluecat: %v", err) + } + + req, err := http.NewRequest(method, url, bytes.NewReader(body)) + if err != nil { + return nil, fmt.Errorf("bluecat: %v", err) + } + req.Header.Set("Content-Type", "application/json") + if len(d.token) > 0 { + req.Header.Set("Authorization", d.token) + } + + // Add all query parameters + q := req.URL.Query() + for argName, argVal := range queryArgs { + q.Add(argName, argVal) + } + req.URL.RawQuery = q.Encode() + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return nil, fmt.Errorf("bluecat: %v", err) + } + + if resp.StatusCode >= 400 { + errBytes, _ := ioutil.ReadAll(resp.Body) + errResp := string(errBytes) + return nil, fmt.Errorf("bluecat: request failed with HTTP status code %d\n Full message: %s", + resp.StatusCode, errResp) + } + + return resp, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/cloudflare/cloudflare.go b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudflare/cloudflare.go new file mode 100644 index 000000000..675a39f0e --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudflare/cloudflare.go @@ -0,0 +1,157 @@ +// Package cloudflare implements a DNS provider for solving the DNS-01 challenge using cloudflare DNS. +package cloudflare + +import ( + "errors" + "fmt" + "net/http" + "time" + + cloudflare "github.com/cloudflare/cloudflare-go" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const ( + minTTL = 120 +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + AuthEmail string + AuthKey string + TTL int + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("CLOUDFLARE_TTL", minTTL), + PropagationTimeout: env.GetOrDefaultSecond("CLOUDFLARE_PROPAGATION_TIMEOUT", 2*time.Minute), + PollingInterval: env.GetOrDefaultSecond("CLOUDFLARE_POLLING_INTERVAL", 2*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("CLOUDFLARE_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + client *cloudflare.API + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for Cloudflare. +// Credentials must be passed in the environment variables: +// CLOUDFLARE_EMAIL and CLOUDFLARE_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.GetWithFallback( + []string{"CLOUDFLARE_EMAIL", "CF_API_EMAIL"}, + []string{"CLOUDFLARE_API_KEY", "CF_API_KEY"}) + if err != nil { + return nil, fmt.Errorf("cloudflare: %v", err) + } + + config := NewDefaultConfig() + config.AuthEmail = values["CLOUDFLARE_EMAIL"] + config.AuthKey = values["CLOUDFLARE_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Cloudflare. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("cloudflare: the configuration of the DNS provider is nil") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("cloudflare: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + client, err := cloudflare.New(config.AuthKey, config.AuthEmail, cloudflare.HTTPClient(config.HTTPClient)) + if err != nil { + return nil, err + } + + return &DNSProvider{client: client, config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("cloudflare: %v", err) + } + + zoneID, err := d.client.ZoneIDByName(dns01.UnFqdn(authZone)) + if err != nil { + return fmt.Errorf("cloudflare: failed to find zone %s: %v", authZone, err) + } + + dnsRecord := cloudflare.DNSRecord{ + Type: "TXT", + Name: dns01.UnFqdn(fqdn), + Content: value, + TTL: d.config.TTL, + } + + response, err := d.client.CreateDNSRecord(zoneID, dnsRecord) + if err != nil { + return fmt.Errorf("cloudflare: failed to create TXT record: %v", err) + } + + if !response.Success { + return fmt.Errorf("cloudflare: failed to create TXT record: %+v %+v", response.Errors, response.Messages) + } + + log.Infof("cloudflare: new record for %s, ID %s", domain, response.Result.ID) + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("cloudflare: %v", err) + } + + zoneID, err := d.client.ZoneIDByName(dns01.UnFqdn(authZone)) + if err != nil { + return fmt.Errorf("cloudflare: failed to find zone %s: %v", authZone, err) + } + + dnsRecord := cloudflare.DNSRecord{ + Type: "TXT", + Name: dns01.UnFqdn(fqdn), + } + + records, err := d.client.DNSRecords(zoneID, dnsRecord) + if err != nil { + return fmt.Errorf("cloudflare: failed to find TXT records: %v", err) + } + + for _, record := range records { + err = d.client.DeleteDNSRecord(zoneID, record.ID) + if err != nil { + log.Printf("cloudflare: failed to delete TXT record: %v", err) + } + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/cloudflare/cloudflare.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudflare/cloudflare.toml new file mode 100644 index 000000000..d4e0a0fdd --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudflare/cloudflare.toml @@ -0,0 +1,31 @@ +Name = "Cloudflare" +Description = '''''' +URL = "https://www.cloudflare.com/dns/" +Code = "cloudflare" +Since = "v0.3.0" + +Example = ''' +CLOUDFLARE_EMAIL=foo@bar.com \ +CLOUDFLARE_API_KEY=b9841238feb177a84330febba8a83208921177bffe733 \ +lego --dns cloudflare --domains my.domain.com --email my@email.com run +''' + +Additional = ''' +The Global API Key needs to be used, not the Origin CA Key. +''' + +[Configuration] + [Configuration.Credentials] + CF_API_EMAIL = "Account email" + CF_API_KEY = "API key" + CLOUDFLARE_EMAIL = "Alias to CF_API_EMAIL" + CLOUDFLARE_API_KEY = "Alias to CLOUDFLARE_API_KEY" + [Configuration.Additional] + CLOUDFLARE_POLLING_INTERVAL = "Time between DNS propagation check" + CLOUDFLARE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + CLOUDFLARE_TTL = "The TTL of the TXT record used for the DNS challenge" + CLOUDFLARE_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://api.cloudflare.com/" + GoClient = "https://github.com/cloudflare/cloudflare-go" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/cloudns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/cloudns.go new file mode 100644 index 000000000..9d46d9944 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/cloudns.go @@ -0,0 +1,121 @@ +// Package cloudns implements a DNS provider for solving the DNS-01 challenge using ClouDNS DNS. +package cloudns + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/go-acme/lego/v3/providers/dns/cloudns/internal" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + AuthID string + AuthPassword string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("CLOUDNS_PROPAGATION_TIMEOUT", 120*time.Second), + PollingInterval: env.GetOrDefaultSecond("CLOUDNS_POLLING_INTERVAL", 4*time.Second), + TTL: env.GetOrDefaultInt("CLOUDNS_TTL", 60), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("CLOUDNS_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config + client *internal.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for ClouDNS. +// Credentials must be passed in the environment variables: +// CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("CLOUDNS_AUTH_ID", "CLOUDNS_AUTH_PASSWORD") + if err != nil { + return nil, fmt.Errorf("ClouDNS: %v", err) + } + + config := NewDefaultConfig() + config.AuthID = values["CLOUDNS_AUTH_ID"] + config.AuthPassword = values["CLOUDNS_AUTH_PASSWORD"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for ClouDNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("ClouDNS: the configuration of the DNS provider is nil") + } + + client, err := internal.NewClient(config.AuthID, config.AuthPassword) + if err != nil { + return nil, fmt.Errorf("ClouDNS: %v", err) + } + + client.HTTPClient = config.HTTPClient + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zone, err := d.client.GetZone(fqdn) + if err != nil { + return fmt.Errorf("ClouDNS: %v", err) + } + + err = d.client.AddTxtRecord(zone.Name, fqdn, value, d.config.TTL) + if err != nil { + return fmt.Errorf("ClouDNS: %v", err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zone, err := d.client.GetZone(fqdn) + if err != nil { + return fmt.Errorf("ClouDNS: %v", err) + } + + record, err := d.client.FindTxtRecord(zone.Name, fqdn) + if err != nil { + return fmt.Errorf("ClouDNS: %v", err) + } + + if record == nil { + return nil + } + + err = d.client.RemoveTxtRecord(record.ID, zone.Name) + if err != nil { + return fmt.Errorf("ClouDNS: %v", err) + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/cloudns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/cloudns.toml new file mode 100644 index 000000000..95176a993 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/cloudns.toml @@ -0,0 +1,20 @@ +Name = "ClouDNS" +Description = '''''' +URL = "https://www.cloudns.net" +Code = "cloudns" +Since = "v2.3.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + CLOUDNS_AUTH_ID = "The API user ID" + CLOUDNS_AUTH_PASSWORD = "The password for API user ID" + [Configuration.Additional] + CLOUDNS_POLLING_INTERVAL = "Time between DNS propagation check" + CLOUDNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + CLOUDNS_TTL = "The TTL of the TXT record used for the DNS challenge" + CLOUDNS_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.cloudns.net/wiki/article/42/" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/internal/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/internal/client.go new file mode 100644 index 000000000..df519ae17 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudns/internal/client.go @@ -0,0 +1,271 @@ +package internal + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/go-acme/lego/v3/challenge/dns01" +) + +const defaultBaseURL = "https://api.cloudns.net/dns/" + +type apiResponse struct { + Status string `json:"status"` + StatusDescription string `json:"statusDescription"` +} + +type Zone struct { + Name string + Type string + Zone string + Status string // is an integer, but cast as string +} + +// TXTRecord a TXT record +type TXTRecord struct { + ID int `json:"id,string"` + Type string `json:"type"` + Host string `json:"host"` + Record string `json:"record"` + Failover int `json:"failover,string"` + TTL int `json:"ttl,string"` + Status int `json:"status"` +} + +type TXTRecords map[string]TXTRecord + +// NewClient creates a ClouDNS client +func NewClient(authID string, authPassword string) (*Client, error) { + if authID == "" { + return nil, fmt.Errorf("credentials missing: authID") + } + + if authPassword == "" { + return nil, fmt.Errorf("credentials missing: authPassword") + } + + baseURL, err := url.Parse(defaultBaseURL) + if err != nil { + return nil, err + } + + return &Client{ + authID: authID, + authPassword: authPassword, + HTTPClient: &http.Client{}, + BaseURL: baseURL, + }, nil +} + +// Client ClouDNS client +type Client struct { + authID string + authPassword string + HTTPClient *http.Client + BaseURL *url.URL +} + +// GetZone Get domain name information for a FQDN +func (c *Client) GetZone(authFQDN string) (*Zone, error) { + authZone, err := dns01.FindZoneByFqdn(authFQDN) + if err != nil { + return nil, err + } + + authZoneName := dns01.UnFqdn(authZone) + + reqURL := *c.BaseURL + reqURL.Path += "get-zone-info.json" + + q := reqURL.Query() + q.Add("domain-name", authZoneName) + reqURL.RawQuery = q.Encode() + + result, err := c.doRequest(http.MethodGet, &reqURL) + if err != nil { + return nil, err + } + + var zone Zone + + if len(result) > 0 { + if err = json.Unmarshal(result, &zone); err != nil { + return nil, fmt.Errorf("zone unmarshaling error: %v", err) + } + } + + if zone.Name == authZoneName { + return &zone, nil + } + + return nil, fmt.Errorf("zone %s not found for authFQDN %s", authZoneName, authFQDN) +} + +// FindTxtRecord return the TXT record a zone ID and a FQDN +func (c *Client) FindTxtRecord(zoneName, fqdn string) (*TXTRecord, error) { + host := dns01.UnFqdn(strings.TrimSuffix(dns01.UnFqdn(fqdn), zoneName)) + + reqURL := *c.BaseURL + reqURL.Path += "records.json" + + q := reqURL.Query() + q.Add("domain-name", zoneName) + q.Add("host", host) + q.Add("type", "TXT") + reqURL.RawQuery = q.Encode() + + result, err := c.doRequest(http.MethodGet, &reqURL) + if err != nil { + return nil, err + } + + // the API returns [] when there is no records. + if string(result) == "[]" { + return nil, nil + } + + var records TXTRecords + if err = json.Unmarshal(result, &records); err != nil { + return nil, fmt.Errorf("TXT record unmarshaling error: %v: %s", err, string(result)) + } + + for _, record := range records { + if record.Host == host && record.Type == "TXT" { + return &record, nil + } + } + + return nil, nil +} + +// AddTxtRecord add a TXT record +func (c *Client) AddTxtRecord(zoneName string, fqdn, value string, ttl int) error { + host := dns01.UnFqdn(strings.TrimSuffix(dns01.UnFqdn(fqdn), zoneName)) + + reqURL := *c.BaseURL + reqURL.Path += "add-record.json" + + q := reqURL.Query() + q.Add("domain-name", zoneName) + q.Add("host", host) + q.Add("record", value) + q.Add("ttl", strconv.Itoa(ttlRounder(ttl))) + q.Add("record-type", "TXT") + reqURL.RawQuery = q.Encode() + + raw, err := c.doRequest(http.MethodPost, &reqURL) + if err != nil { + return err + } + + resp := apiResponse{} + if err = json.Unmarshal(raw, &resp); err != nil { + return fmt.Errorf("apiResponse unmarshaling error: %v: %s", err, string(raw)) + } + + if resp.Status != "Success" { + return fmt.Errorf("fail to add TXT record: %s %s", resp.Status, resp.StatusDescription) + } + + return nil +} + +// RemoveTxtRecord remove a TXT record +func (c *Client) RemoveTxtRecord(recordID int, zoneName string) error { + reqURL := *c.BaseURL + reqURL.Path += "delete-record.json" + + q := reqURL.Query() + q.Add("domain-name", zoneName) + q.Add("record-id", strconv.Itoa(recordID)) + reqURL.RawQuery = q.Encode() + + raw, err := c.doRequest(http.MethodPost, &reqURL) + if err != nil { + return err + } + + resp := apiResponse{} + if err = json.Unmarshal(raw, &resp); err != nil { + return fmt.Errorf("apiResponse unmarshaling error: %v: %s", err, string(raw)) + } + + if resp.Status != "Success" { + return fmt.Errorf("fail to add TXT record: %s %s", resp.Status, resp.StatusDescription) + } + + return nil +} + +func (c *Client) doRequest(method string, url *url.URL) (json.RawMessage, error) { + req, err := c.buildRequest(method, url) + if err != nil { + return nil, err + } + + resp, err := c.HTTPClient.Do(req) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, errors.New(toUnreadableBodyMessage(req, content)) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("invalid code (%v), error: %s", resp.StatusCode, content) + } + return content, nil +} + +func (c *Client) buildRequest(method string, url *url.URL) (*http.Request, error) { + q := url.Query() + q.Add("auth-id", c.authID) + q.Add("auth-password", c.authPassword) + url.RawQuery = q.Encode() + + req, err := http.NewRequest(method, url.String(), nil) + if err != nil { + return nil, fmt.Errorf("invalid request: %v", err) + } + + return req, nil +} + +func toUnreadableBodyMessage(req *http.Request, rawBody []byte) string { + return fmt.Sprintf("the request %s sent a response with a body which is an invalid format: %q", req.URL, string(rawBody)) +} + +// https://www.cloudns.net/wiki/article/58/ +// Available TTL's: +// 60 = 1 minute +// 300 = 5 minutes +// 900 = 15 minutes +// 1800 = 30 minutes +// 3600 = 1 hour +// 21600 = 6 hours +// 43200 = 12 hours +// 86400 = 1 day +// 172800 = 2 days +// 259200 = 3 days +// 604800 = 1 week +// 1209600 = 2 weeks +// 2592000 = 1 month +func ttlRounder(ttl int) int { + for _, validTTL := range []int{60, 300, 900, 1800, 3600, 21600, 43200, 86400, 172800, 259200, 604800, 1209600} { + if ttl <= validTTL { + return validTTL + } + } + + return 2592000 +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/cloudxns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/cloudxns.go new file mode 100644 index 000000000..4d395c2d5 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/cloudxns.go @@ -0,0 +1,108 @@ +// Package cloudxns implements a DNS provider for solving the DNS-01 challenge using CloudXNS DNS. +package cloudxns + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/go-acme/lego/v3/providers/dns/cloudxns/internal" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + SecretKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("CLOUDXNS_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("CLOUDXNS_POLLING_INTERVAL", dns01.DefaultPollingInterval), + TTL: env.GetOrDefaultInt("CLOUDXNS_TTL", dns01.DefaultTTL), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("CLOUDXNS_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config + client *internal.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for CloudXNS. +// Credentials must be passed in the environment variables: +// CLOUDXNS_API_KEY and CLOUDXNS_SECRET_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("CLOUDXNS_API_KEY", "CLOUDXNS_SECRET_KEY") + if err != nil { + return nil, fmt.Errorf("CloudXNS: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["CLOUDXNS_API_KEY"] + config.SecretKey = values["CLOUDXNS_SECRET_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for CloudXNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("CloudXNS: the configuration of the DNS provider is nil") + } + + client, err := internal.NewClient(config.APIKey, config.SecretKey) + if err != nil { + return nil, err + } + + client.HTTPClient = config.HTTPClient + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + info, err := d.client.GetDomainInformation(fqdn) + if err != nil { + return err + } + + return d.client.AddTxtRecord(info, fqdn, value, d.config.TTL) +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + info, err := d.client.GetDomainInformation(fqdn) + if err != nil { + return err + } + + record, err := d.client.FindTxtRecord(info.ID, fqdn) + if err != nil { + return err + } + + return d.client.RemoveTxtRecord(record.RecordID, info.ID) +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/cloudxns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/cloudxns.toml new file mode 100644 index 000000000..d5bc6d4e8 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/cloudxns.toml @@ -0,0 +1,20 @@ +Name = "CloudXNS" +Description = """""" +URL = "https://www.cloudxns.net/" +Code = "cloudxns" +Since = "v0.5.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + CLOUDXNS_API_KEY = "The API key" + CLOUDXNS_SECRET_KEY = "THe API secret key" + [Configuration.Additional] + CLOUDXNS_POLLING_INTERVAL = "Time between DNS propagation check" + CLOUDXNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + CLOUDXNS_TTL = "The TTL of the TXT record used for the DNS challenge" + CLOUDXNS_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.cloudxns.net/Public/Doc/CloudXNS_api2.0_doc_zh-cn.zip" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/internal/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/internal/client.go new file mode 100644 index 000000000..6578dbe1f --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/cloudxns/internal/client.go @@ -0,0 +1,208 @@ +package internal + +import ( + "bytes" + "crypto/md5" + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" +) + +const defaultBaseURL = "https://www.cloudxns.net/api2/" + +type apiResponse struct { + Code int `json:"code"` + Message string `json:"message"` + Data json.RawMessage `json:"data,omitempty"` +} + +// Data Domain information +type Data struct { + ID string `json:"id"` + Domain string `json:"domain"` + TTL int `json:"ttl,omitempty"` +} + +// TXTRecord a TXT record +type TXTRecord struct { + ID int `json:"domain_id,omitempty"` + RecordID string `json:"record_id,omitempty"` + + Host string `json:"host"` + Value string `json:"value"` + Type string `json:"type"` + LineID int `json:"line_id,string"` + TTL int `json:"ttl,string"` +} + +// NewClient creates a CloudXNS client +func NewClient(apiKey string, secretKey string) (*Client, error) { + if apiKey == "" { + return nil, fmt.Errorf("CloudXNS: credentials missing: apiKey") + } + + if secretKey == "" { + return nil, fmt.Errorf("CloudXNS: credentials missing: secretKey") + } + + return &Client{ + apiKey: apiKey, + secretKey: secretKey, + HTTPClient: &http.Client{}, + BaseURL: defaultBaseURL, + }, nil +} + +// Client CloudXNS client +type Client struct { + apiKey string + secretKey string + HTTPClient *http.Client + BaseURL string +} + +// GetDomainInformation Get domain name information for a FQDN +func (c *Client) GetDomainInformation(fqdn string) (*Data, error) { + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return nil, err + } + + result, err := c.doRequest(http.MethodGet, "domain", nil) + if err != nil { + return nil, err + } + + var domains []Data + if len(result) > 0 { + err = json.Unmarshal(result, &domains) + if err != nil { + return nil, fmt.Errorf("CloudXNS: domains unmarshaling error: %v", err) + } + } + + for _, data := range domains { + if data.Domain == authZone { + return &data, nil + } + } + + return nil, fmt.Errorf("CloudXNS: zone %s not found for domain %s", authZone, fqdn) +} + +// FindTxtRecord return the TXT record a zone ID and a FQDN +func (c *Client) FindTxtRecord(zoneID, fqdn string) (*TXTRecord, error) { + result, err := c.doRequest(http.MethodGet, fmt.Sprintf("record/%s?host_id=0&offset=0&row_num=2000", zoneID), nil) + if err != nil { + return nil, err + } + + var records []TXTRecord + err = json.Unmarshal(result, &records) + if err != nil { + return nil, fmt.Errorf("CloudXNS: TXT record unmarshaling error: %v", err) + } + + for _, record := range records { + if record.Host == dns01.UnFqdn(fqdn) && record.Type == "TXT" { + return &record, nil + } + } + + return nil, fmt.Errorf("CloudXNS: no existing record found for %q", fqdn) +} + +// AddTxtRecord add a TXT record +func (c *Client) AddTxtRecord(info *Data, fqdn, value string, ttl int) error { + id, err := strconv.Atoi(info.ID) + if err != nil { + return fmt.Errorf("CloudXNS: invalid zone ID: %v", err) + } + + payload := TXTRecord{ + ID: id, + Host: dns01.UnFqdn(strings.TrimSuffix(fqdn, info.Domain)), + Value: value, + Type: "TXT", + LineID: 1, + TTL: ttl, + } + + body, err := json.Marshal(payload) + if err != nil { + return fmt.Errorf("CloudXNS: record unmarshaling error: %v", err) + } + + _, err = c.doRequest(http.MethodPost, "record", body) + return err +} + +// RemoveTxtRecord remove a TXT record +func (c *Client) RemoveTxtRecord(recordID, zoneID string) error { + _, err := c.doRequest(http.MethodDelete, fmt.Sprintf("record/%s/%s", recordID, zoneID), nil) + return err +} + +func (c *Client) doRequest(method, uri string, body []byte) (json.RawMessage, error) { + req, err := c.buildRequest(method, uri, body) + if err != nil { + return nil, err + } + + resp, err := c.HTTPClient.Do(req) + if err != nil { + return nil, fmt.Errorf("CloudXNS: %v", err) + } + + defer resp.Body.Close() + + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("CloudXNS: %s", toUnreadableBodyMessage(req, content)) + } + + var r apiResponse + err = json.Unmarshal(content, &r) + if err != nil { + return nil, fmt.Errorf("CloudXNS: response unmashaling error: %v: %s", err, toUnreadableBodyMessage(req, content)) + } + + if r.Code != 1 { + return nil, fmt.Errorf("CloudXNS: invalid code (%v), error: %s", r.Code, r.Message) + } + return r.Data, nil +} + +func (c *Client) buildRequest(method, uri string, body []byte) (*http.Request, error) { + url := c.BaseURL + uri + + req, err := http.NewRequest(method, url, bytes.NewReader(body)) + if err != nil { + return nil, fmt.Errorf("CloudXNS: invalid request: %v", err) + } + + requestDate := time.Now().Format(time.RFC1123Z) + + req.Header.Set("API-KEY", c.apiKey) + req.Header.Set("API-REQUEST-DATE", requestDate) + req.Header.Set("API-HMAC", c.hmac(url, requestDate, string(body))) + req.Header.Set("API-FORMAT", "json") + + return req, nil +} + +func (c *Client) hmac(url, date, body string) string { + sum := md5.Sum([]byte(c.apiKey + url + body + date + c.secretKey)) + return hex.EncodeToString(sum[:]) +} + +func toUnreadableBodyMessage(req *http.Request, rawBody []byte) string { + return fmt.Sprintf("the request %s sent a response with a body which is an invalid format: %q", req.URL, string(rawBody)) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/conoha.go b/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/conoha.go new file mode 100644 index 000000000..6b9e59403 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/conoha.go @@ -0,0 +1,148 @@ +// Package conoha implements a DNS provider for solving the DNS-01 challenge using ConoHa DNS. +package conoha + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/go-acme/lego/v3/providers/dns/conoha/internal" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Region string + TenantID string + Username string + Password string + TTL int + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + Region: env.GetOrDefaultString("CONOHA_REGION", "tyo1"), + TTL: env.GetOrDefaultInt("CONOHA_TTL", 60), + PropagationTimeout: env.GetOrDefaultSecond("CONOHA_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("CONOHA_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("CONOHA_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config + client *internal.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for ConoHa DNS. +// Credentials must be passed in the environment variables: CONOHA_TENANT_ID, CONOHA_API_USERNAME, CONOHA_API_PASSWORD +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("CONOHA_TENANT_ID", "CONOHA_API_USERNAME", "CONOHA_API_PASSWORD") + if err != nil { + return nil, fmt.Errorf("conoha: %v", err) + } + + config := NewDefaultConfig() + config.TenantID = values["CONOHA_TENANT_ID"] + config.Username = values["CONOHA_API_USERNAME"] + config.Password = values["CONOHA_API_PASSWORD"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for ConoHa DNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("conoha: the configuration of the DNS provider is nil") + } + + if config.TenantID == "" || config.Username == "" || config.Password == "" { + return nil, errors.New("conoha: some credentials information are missing") + } + + auth := internal.Auth{ + TenantID: config.TenantID, + PasswordCredentials: internal.PasswordCredentials{ + Username: config.Username, + Password: config.Password, + }, + } + + client, err := internal.NewClient(config.Region, auth, config.HTTPClient) + if err != nil { + return nil, fmt.Errorf("conoha: failed to create client: %v", err) + } + + return &DNSProvider{config: config, client: client}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return err + } + + id, err := d.client.GetDomainID(authZone) + if err != nil { + return fmt.Errorf("conoha: failed to get domain ID: %v", err) + } + + record := internal.Record{ + Name: fqdn, + Type: "TXT", + Data: value, + TTL: d.config.TTL, + } + + err = d.client.CreateRecord(id, record) + if err != nil { + return fmt.Errorf("conoha: failed to create record: %v", err) + } + + return nil +} + +// CleanUp clears ConoHa DNS TXT record +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return err + } + + domID, err := d.client.GetDomainID(authZone) + if err != nil { + return fmt.Errorf("conoha: failed to get domain ID: %v", err) + } + + recID, err := d.client.GetRecordID(domID, fqdn, "TXT", value) + if err != nil { + return fmt.Errorf("conoha: failed to get record ID: %v", err) + } + + err = d.client.DeleteRecord(domID, recID) + if err != nil { + return fmt.Errorf("conoha: failed to delete record: %v", err) + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/conoha.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/conoha.toml new file mode 100644 index 000000000..730145192 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/conoha.toml @@ -0,0 +1,22 @@ +Name = "ConoHa" +Description = '''''' +URL = "https://www.conoha.jp/" +Code = "conoha" +Since = "v1.2.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + CONOHA_TENANT_ID = "Tenant ID" + CONOHA_API_USERNAME = "The API username" + CONOHA_API_PASSWORD = "The API password" + [Configuration.Additional] + CONOHA_POLLING_INTERVAL = "Time between DNS propagation check" + CONOHA_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + CONOHA_TTL = "The TTL of the TXT record used for the DNS challenge" + CONOHA_HTTP_TIMEOUT = "API request timeout" + CONOHA_REGION = "The region" + +[Links] + API = "https://www.conoha.jp/docs/" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/internal/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/internal/client.go new file mode 100644 index 000000000..3136a24d6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/conoha/internal/client.go @@ -0,0 +1,205 @@ +package internal + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" +) + +const ( + identityBaseURL = "https://identity.%s.conoha.io" + dnsServiceBaseURL = "https://dns-service.%s.conoha.io" +) + +// IdentityRequest is an authentication request body. +type IdentityRequest struct { + Auth Auth `json:"auth"` +} + +// Auth is an authentication information. +type Auth struct { + TenantID string `json:"tenantId"` + PasswordCredentials PasswordCredentials `json:"passwordCredentials"` +} + +// PasswordCredentials is API-user's credentials. +type PasswordCredentials struct { + Username string `json:"username"` + Password string `json:"password"` +} + +// IdentityResponse is an authentication response body. +type IdentityResponse struct { + Access Access `json:"access"` +} + +// Access is an identity information. +type Access struct { + Token Token `json:"token"` +} + +// Token is an api access token. +type Token struct { + ID string `json:"id"` +} + +// DomainListResponse is a response of a domain listing request. +type DomainListResponse struct { + Domains []Domain `json:"domains"` +} + +// Domain is a hosted domain entry. +type Domain struct { + ID string `json:"id"` + Name string `json:"name"` +} + +// RecordListResponse is a response of record listing request. +type RecordListResponse struct { + Records []Record `json:"records"` +} + +// Record is a record entry. +type Record struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + Data string `json:"data"` + TTL int `json:"ttl"` +} + +// Client is a ConoHa API client. +type Client struct { + token string + endpoint string + httpClient *http.Client +} + +// NewClient returns a client instance logged into the ConoHa service. +func NewClient(region string, auth Auth, httpClient *http.Client) (*Client, error) { + if httpClient == nil { + httpClient = &http.Client{} + } + + c := &Client{httpClient: httpClient} + + c.endpoint = fmt.Sprintf(identityBaseURL, region) + + identity, err := c.getIdentity(auth) + if err != nil { + return nil, fmt.Errorf("failed to login: %v", err) + } + + c.token = identity.Access.Token.ID + c.endpoint = fmt.Sprintf(dnsServiceBaseURL, region) + + return c, nil +} + +func (c *Client) getIdentity(auth Auth) (*IdentityResponse, error) { + req := &IdentityRequest{Auth: auth} + + identity := &IdentityResponse{} + + err := c.do(http.MethodPost, "/v2.0/tokens", req, identity) + if err != nil { + return nil, err + } + + return identity, nil +} + +// GetDomainID returns an ID of specified domain. +func (c *Client) GetDomainID(domainName string) (string, error) { + domainList := &DomainListResponse{} + + err := c.do(http.MethodGet, "/v1/domains", nil, domainList) + if err != nil { + return "", err + } + + for _, domain := range domainList.Domains { + if domain.Name == domainName { + return domain.ID, nil + } + } + return "", fmt.Errorf("no such domain: %s", domainName) +} + +// GetRecordID returns an ID of specified record. +func (c *Client) GetRecordID(domainID, recordName, recordType, data string) (string, error) { + recordList := &RecordListResponse{} + + err := c.do(http.MethodGet, fmt.Sprintf("/v1/domains/%s/records", domainID), nil, recordList) + if err != nil { + return "", err + } + + for _, record := range recordList.Records { + if record.Name == recordName && record.Type == recordType && record.Data == data { + return record.ID, nil + } + } + return "", errors.New("no such record") +} + +// CreateRecord adds new record. +func (c *Client) CreateRecord(domainID string, record Record) error { + return c.do(http.MethodPost, fmt.Sprintf("/v1/domains/%s/records", domainID), record, nil) +} + +// DeleteRecord removes specified record. +func (c *Client) DeleteRecord(domainID, recordID string) error { + return c.do(http.MethodDelete, fmt.Sprintf("/v1/domains/%s/records/%s", domainID, recordID), nil, nil) +} + +func (c *Client) do(method, path string, payload, result interface{}) error { + body := bytes.NewReader(nil) + + if payload != nil { + bodyBytes, err := json.Marshal(payload) + if err != nil { + return err + } + body = bytes.NewReader(bodyBytes) + } + + req, err := http.NewRequest(method, c.endpoint+path, body) + if err != nil { + return err + } + + req.Header.Set("Accept", "application/json") + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Auth-Token", c.token) + + resp, err := c.httpClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + defer resp.Body.Close() + + return fmt.Errorf("HTTP request failed with status code %d: %s", resp.StatusCode, string(respBody)) + } + + if result != nil { + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + defer resp.Body.Close() + + return json.Unmarshal(respBody, result) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/designate/designate.go b/vendor/github.com/go-acme/lego/v3/providers/dns/designate/designate.go new file mode 100644 index 000000000..395f011f8 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/designate/designate.go @@ -0,0 +1,249 @@ +// Package designate implements a DNS provider for solving the DNS-01 challenge using the Designate DNSaaS for Openstack. +package designate + +import ( + "errors" + "fmt" + "log" + "os" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack" + "github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets" + "github.com/gophercloud/gophercloud/openstack/dns/v2/zones" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + opts gophercloud.AuthOptions +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("DESIGNATE_TTL", 10), + PropagationTimeout: env.GetOrDefaultSecond("DESIGNATE_PROPAGATION_TIMEOUT", 10*time.Minute), + PollingInterval: env.GetOrDefaultSecond("DESIGNATE_POLLING_INTERVAL", 10*time.Second), + } +} + +// DNSProvider describes a provider for Designate +type DNSProvider struct { + config *Config + client *gophercloud.ServiceClient + dnsEntriesMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance configured for Designate. +// Credentials must be passed in the environment variables: +// OS_AUTH_URL, OS_USERNAME, OS_PASSWORD, OS_TENANT_NAME, OS_REGION_NAME. +func NewDNSProvider() (*DNSProvider, error) { + _, err := env.Get("OS_AUTH_URL", "OS_USERNAME", "OS_PASSWORD", "OS_TENANT_NAME", "OS_REGION_NAME") + if err != nil { + return nil, fmt.Errorf("designate: %v", err) + } + + opts, err := openstack.AuthOptionsFromEnv() + if err != nil { + return nil, fmt.Errorf("designate: %v", err) + } + + config := NewDefaultConfig() + config.opts = opts + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Designate. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("designate: the configuration of the DNS provider is nil") + } + + provider, err := openstack.AuthenticatedClient(config.opts) + if err != nil { + return nil, fmt.Errorf("designate: failed to authenticate: %v", err) + } + + dnsClient, err := openstack.NewDNSV2(provider, gophercloud.EndpointOpts{ + Region: os.Getenv("OS_REGION_NAME"), + }) + if err != nil { + return nil, fmt.Errorf("designate: failed to get DNS provider: %v", err) + } + + return &DNSProvider{client: dnsClient, config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("designate: couldn't get zone ID in Present: %v", err) + } + + zoneID, err := d.getZoneID(authZone) + if err != nil { + return fmt.Errorf("designate: %v", err) + } + + // use mutex to prevent race condition between creating the record and verifying it + d.dnsEntriesMu.Lock() + defer d.dnsEntriesMu.Unlock() + + existingRecord, err := d.getRecord(zoneID, fqdn) + if err != nil { + return fmt.Errorf("designate: %v", err) + } + + if existingRecord != nil { + if contains(existingRecord.Records, value) { + log.Printf("designate: the record already exists: %s", value) + return nil + } + + return d.updateRecord(existingRecord, value) + } + + err = d.createRecord(zoneID, fqdn, value) + if err != nil { + return fmt.Errorf("designate: %v", err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return err + } + + zoneID, err := d.getZoneID(authZone) + if err != nil { + return fmt.Errorf("designate: couldn't get zone ID in CleanUp: %v", err) + } + + // use mutex to prevent race condition between getting the record and deleting it + d.dnsEntriesMu.Lock() + defer d.dnsEntriesMu.Unlock() + + record, err := d.getRecord(zoneID, fqdn) + if err != nil { + return fmt.Errorf("designate: couldn't get Record ID in CleanUp: %v", err) + } + + if record == nil { + // Record is already deleted + return nil + } + + err = recordsets.Delete(d.client, zoneID, record.ID).ExtractErr() + if err != nil { + return fmt.Errorf("designate: error for %s in CleanUp: %v", fqdn, err) + } + return nil +} + +func contains(values []string, value string) bool { + for _, v := range values { + if v == value { + return true + } + } + return false +} + +func (d *DNSProvider) createRecord(zoneID, fqdn, value string) error { + createOpts := recordsets.CreateOpts{ + Name: fqdn, + Type: "TXT", + TTL: d.config.TTL, + Description: "ACME verification record", + Records: []string{value}, + } + + actual, err := recordsets.Create(d.client, zoneID, createOpts).Extract() + if err != nil { + return fmt.Errorf("error for %s in Present while creating record: %v", fqdn, err) + } + + if actual.Name != fqdn || actual.TTL != d.config.TTL { + return fmt.Errorf("the created record doesn't match what we wanted to create") + } + + return nil +} + +func (d *DNSProvider) updateRecord(record *recordsets.RecordSet, value string) error { + if contains(record.Records, value) { + log.Printf("skip: the record already exists: %s", value) + return nil + } + + values := append([]string{value}, record.Records...) + + updateOpts := recordsets.UpdateOpts{ + Description: &record.Description, + TTL: &record.TTL, + Records: values, + } + + result := recordsets.Update(d.client, record.ZoneID, record.ID, updateOpts) + return result.Err +} + +func (d *DNSProvider) getZoneID(wanted string) (string, error) { + allPages, err := zones.List(d.client, nil).AllPages() + if err != nil { + return "", err + } + allZones, err := zones.ExtractZones(allPages) + if err != nil { + return "", err + } + + for _, zone := range allZones { + if zone.Name == wanted { + return zone.ID, nil + } + } + return "", fmt.Errorf("zone id not found for %s", wanted) +} + +func (d *DNSProvider) getRecord(zoneID string, wanted string) (*recordsets.RecordSet, error) { + allPages, err := recordsets.ListByZone(d.client, zoneID, nil).AllPages() + if err != nil { + return nil, err + } + allRecords, err := recordsets.ExtractRecordSets(allPages) + if err != nil { + return nil, err + } + + for _, record := range allRecords { + if record.Name == wanted { + return &record, nil + } + } + + return nil, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/designate/designate.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/designate/designate.toml new file mode 100644 index 000000000..697a8f77d --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/designate/designate.toml @@ -0,0 +1,25 @@ +Name = "Designate DNSaaS for Openstack" +Description = '''''' +URL = "https://docs.openstack.org/designate/latest/" +Code = "designate" +Since = "v2.2.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + OS_AUTH_URL = "Identity endpoint URL" + OS_USERNAME = "Username" + OS_PASSWORD = "Password" + OS_PROJECT_NAME = "Project name" + OS_TENANT_NAME = "Tenant name (deprecated see OS_PROJECT_NAME and OS_PROJECT_ID)" + OS_REGION_NAME = "Region name" + [Configuration.Additional] + OS_PROJECT_ID = "Project ID" + DESIGNATE_POLLING_INTERVAL = "Time between DNS propagation check" + DESIGNATE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DESIGNATE_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://docs.openstack.org/designate/latest/" + GoClient = "https://godoc.org/github.com/gophercloud/gophercloud/openstack/dns/v2" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/client.go new file mode 100644 index 000000000..1c73ecb91 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/client.go @@ -0,0 +1,132 @@ +package digitalocean + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + + "github.com/go-acme/lego/v3/challenge/dns01" +) + +const defaultBaseURL = "https://api.digitalocean.com" + +// txtRecordResponse represents a response from DO's API after making a TXT record +type txtRecordResponse struct { + DomainRecord record `json:"domain_record"` +} + +type record struct { + ID int `json:"id,omitempty"` + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + Data string `json:"data,omitempty"` + TTL int `json:"ttl,omitempty"` +} + +type apiError struct { + ID string `json:"id"` + Message string `json:"message"` +} + +func (d *DNSProvider) removeTxtRecord(domain string, recordID int) error { + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return fmt.Errorf("could not determine zone for domain: '%s'. %s", domain, err) + } + + reqURL := fmt.Sprintf("%s/v2/domains/%s/records/%d", d.config.BaseURL, dns01.UnFqdn(authZone), recordID) + req, err := d.newRequest(http.MethodDelete, reqURL, nil) + if err != nil { + return err + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode >= 400 { + return readError(req, resp) + } + + return nil +} + +func (d *DNSProvider) addTxtRecord(fqdn, value string) (*txtRecordResponse, error) { + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(fqdn)) + if err != nil { + return nil, fmt.Errorf("could not determine zone for domain: '%s'. %s", fqdn, err) + } + + reqData := record{Type: "TXT", Name: fqdn, Data: value, TTL: d.config.TTL} + body, err := json.Marshal(reqData) + if err != nil { + return nil, err + } + + reqURL := fmt.Sprintf("%s/v2/domains/%s/records", d.config.BaseURL, dns01.UnFqdn(authZone)) + req, err := d.newRequest(http.MethodPost, reqURL, bytes.NewReader(body)) + if err != nil { + return nil, err + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode >= 400 { + return nil, readError(req, resp) + } + + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, errors.New(toUnreadableBodyMessage(req, content)) + } + + // Everything looks good; but we'll need the ID later to delete the record + respData := &txtRecordResponse{} + err = json.Unmarshal(content, respData) + if err != nil { + return nil, fmt.Errorf("%v: %s", err, toUnreadableBodyMessage(req, content)) + } + + return respData, nil +} + +func (d *DNSProvider) newRequest(method, reqURL string, body io.Reader) (*http.Request, error) { + req, err := http.NewRequest(method, reqURL, body) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", d.config.AuthToken)) + + return req, nil +} + +func readError(req *http.Request, resp *http.Response) error { + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return errors.New(toUnreadableBodyMessage(req, content)) + } + + var errInfo apiError + err = json.Unmarshal(content, &errInfo) + if err != nil { + return fmt.Errorf("apiError unmarshaling error: %v: %s", err, toUnreadableBodyMessage(req, content)) + } + + return fmt.Errorf("HTTP %d: %s: %s", resp.StatusCode, errInfo.ID, errInfo.Message) +} + +func toUnreadableBodyMessage(req *http.Request, rawBody []byte) string { + return fmt.Sprintf("the request %s sent a response with a body which is an invalid format: %q", req.URL, string(rawBody)) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/digitalocean.go b/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/digitalocean.go new file mode 100644 index 000000000..8c20f9f93 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/digitalocean.go @@ -0,0 +1,131 @@ +// Package digitalocean implements a DNS provider for solving the DNS-01 challenge using digitalocean DNS. +package digitalocean + +import ( + "errors" + "fmt" + "net/http" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + AuthToken string + TTL int + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + BaseURL: defaultBaseURL, + TTL: env.GetOrDefaultInt("DO_TTL", 30), + PropagationTimeout: env.GetOrDefaultSecond("DO_PROPAGATION_TIMEOUT", 60*time.Second), + PollingInterval: env.GetOrDefaultSecond("DO_POLLING_INTERVAL", 5*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("DO_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +// that uses DigitalOcean's REST API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + recordIDs map[string]int + recordIDsMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance configured for Digital +// Ocean. Credentials must be passed in the environment variable: +// DO_AUTH_TOKEN. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("DO_AUTH_TOKEN") + if err != nil { + return nil, fmt.Errorf("digitalocean: %v", err) + } + + config := NewDefaultConfig() + config.AuthToken = values["DO_AUTH_TOKEN"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Digital Ocean. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("digitalocean: the configuration of the DNS provider is nil") + } + + if config.AuthToken == "" { + return nil, fmt.Errorf("digitalocean: credentials missing") + } + + if config.BaseURL == "" { + config.BaseURL = defaultBaseURL + } + + return &DNSProvider{ + config: config, + recordIDs: make(map[string]int), + }, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + respData, err := d.addTxtRecord(fqdn, value) + if err != nil { + return fmt.Errorf("digitalocean: %v", err) + } + + d.recordIDsMu.Lock() + d.recordIDs[fqdn] = respData.DomainRecord.ID + d.recordIDsMu.Unlock() + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("digitalocean: %v", err) + } + + // get the record's unique ID from when we created it + d.recordIDsMu.Lock() + recordID, ok := d.recordIDs[fqdn] + d.recordIDsMu.Unlock() + if !ok { + return fmt.Errorf("digitalocean: unknown record ID for '%s'", fqdn) + } + + err = d.removeTxtRecord(authZone, recordID) + if err != nil { + return fmt.Errorf("digitalocean: %v", err) + } + + // Delete record ID from map + d.recordIDsMu.Lock() + delete(d.recordIDs, fqdn) + d.recordIDsMu.Unlock() + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/digitalocean.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/digitalocean.toml new file mode 100644 index 000000000..7dbb123d3 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/digitalocean/digitalocean.toml @@ -0,0 +1,19 @@ +Name = "Digital Ocean" +Description = '''''' +URL = "https://www.digitalocean.com/docs/networking/dns/" +Code = "digitalocean" +Since = "v0.3.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + DO_AUTH_TOKEN = "Authentication token" + [Configuration.Additional] + DO_POLLING_INTERVAL = "Time between DNS propagation check" + DO_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DO_TTL = "The TTL of the TXT record used for the DNS challenge" + DO_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://developers.digitalocean.com/documentation/v2/#domain-records" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dns_providers.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dns_providers.go new file mode 100644 index 000000000..a4a973230 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dns_providers.go @@ -0,0 +1,195 @@ +package dns + +import ( + "fmt" + + "github.com/go-acme/lego/v3/challenge" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/providers/dns/acmedns" + "github.com/go-acme/lego/v3/providers/dns/alidns" + "github.com/go-acme/lego/v3/providers/dns/auroradns" + "github.com/go-acme/lego/v3/providers/dns/azure" + "github.com/go-acme/lego/v3/providers/dns/bindman" + "github.com/go-acme/lego/v3/providers/dns/bluecat" + "github.com/go-acme/lego/v3/providers/dns/cloudflare" + "github.com/go-acme/lego/v3/providers/dns/cloudns" + "github.com/go-acme/lego/v3/providers/dns/cloudxns" + "github.com/go-acme/lego/v3/providers/dns/conoha" + "github.com/go-acme/lego/v3/providers/dns/designate" + "github.com/go-acme/lego/v3/providers/dns/digitalocean" + "github.com/go-acme/lego/v3/providers/dns/dnsimple" + "github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy" + "github.com/go-acme/lego/v3/providers/dns/dnspod" + "github.com/go-acme/lego/v3/providers/dns/dode" + "github.com/go-acme/lego/v3/providers/dns/dreamhost" + "github.com/go-acme/lego/v3/providers/dns/duckdns" + "github.com/go-acme/lego/v3/providers/dns/dyn" + "github.com/go-acme/lego/v3/providers/dns/easydns" + "github.com/go-acme/lego/v3/providers/dns/exec" + "github.com/go-acme/lego/v3/providers/dns/exoscale" + "github.com/go-acme/lego/v3/providers/dns/fastdns" + "github.com/go-acme/lego/v3/providers/dns/gandi" + "github.com/go-acme/lego/v3/providers/dns/gandiv5" + "github.com/go-acme/lego/v3/providers/dns/gcloud" + "github.com/go-acme/lego/v3/providers/dns/glesys" + "github.com/go-acme/lego/v3/providers/dns/godaddy" + "github.com/go-acme/lego/v3/providers/dns/hostingde" + "github.com/go-acme/lego/v3/providers/dns/httpreq" + "github.com/go-acme/lego/v3/providers/dns/iij" + "github.com/go-acme/lego/v3/providers/dns/inwx" + "github.com/go-acme/lego/v3/providers/dns/joker" + "github.com/go-acme/lego/v3/providers/dns/lightsail" + "github.com/go-acme/lego/v3/providers/dns/linode" + "github.com/go-acme/lego/v3/providers/dns/linodev4" + "github.com/go-acme/lego/v3/providers/dns/mydnsjp" + "github.com/go-acme/lego/v3/providers/dns/namecheap" + "github.com/go-acme/lego/v3/providers/dns/namedotcom" + "github.com/go-acme/lego/v3/providers/dns/namesilo" + "github.com/go-acme/lego/v3/providers/dns/netcup" + "github.com/go-acme/lego/v3/providers/dns/nifcloud" + "github.com/go-acme/lego/v3/providers/dns/ns1" + "github.com/go-acme/lego/v3/providers/dns/oraclecloud" + "github.com/go-acme/lego/v3/providers/dns/otc" + "github.com/go-acme/lego/v3/providers/dns/ovh" + "github.com/go-acme/lego/v3/providers/dns/pdns" + "github.com/go-acme/lego/v3/providers/dns/rackspace" + "github.com/go-acme/lego/v3/providers/dns/rfc2136" + "github.com/go-acme/lego/v3/providers/dns/route53" + "github.com/go-acme/lego/v3/providers/dns/sakuracloud" + "github.com/go-acme/lego/v3/providers/dns/selectel" + "github.com/go-acme/lego/v3/providers/dns/stackpath" + "github.com/go-acme/lego/v3/providers/dns/transip" + "github.com/go-acme/lego/v3/providers/dns/vegadns" + "github.com/go-acme/lego/v3/providers/dns/versio" + "github.com/go-acme/lego/v3/providers/dns/vscale" + "github.com/go-acme/lego/v3/providers/dns/vultr" + "github.com/go-acme/lego/v3/providers/dns/zoneee" +) + +// NewDNSChallengeProviderByName Factory for DNS providers +func NewDNSChallengeProviderByName(name string) (challenge.Provider, error) { + switch name { + case "acme-dns": + return acmedns.NewDNSProvider() + case "alidns": + return alidns.NewDNSProvider() + case "azure": + return azure.NewDNSProvider() + case "auroradns": + return auroradns.NewDNSProvider() + case "bindman": + return bindman.NewDNSProvider() + case "bluecat": + return bluecat.NewDNSProvider() + case "cloudflare": + return cloudflare.NewDNSProvider() + case "cloudns": + return cloudns.NewDNSProvider() + case "cloudxns": + return cloudxns.NewDNSProvider() + case "conoha": + return conoha.NewDNSProvider() + case "designate": + return designate.NewDNSProvider() + case "digitalocean": + return digitalocean.NewDNSProvider() + case "dnsimple": + return dnsimple.NewDNSProvider() + case "dnsmadeeasy": + return dnsmadeeasy.NewDNSProvider() + case "dnspod": + return dnspod.NewDNSProvider() + case "dode": + return dode.NewDNSProvider() + case "dreamhost": + return dreamhost.NewDNSProvider() + case "duckdns": + return duckdns.NewDNSProvider() + case "dyn": + return dyn.NewDNSProvider() + case "fastdns": + return fastdns.NewDNSProvider() + case "easydns": + return easydns.NewDNSProvider() + case "exec": + return exec.NewDNSProvider() + case "exoscale": + return exoscale.NewDNSProvider() + case "gandi": + return gandi.NewDNSProvider() + case "gandiv5": + return gandiv5.NewDNSProvider() + case "glesys": + return glesys.NewDNSProvider() + case "gcloud": + return gcloud.NewDNSProvider() + case "godaddy": + return godaddy.NewDNSProvider() + case "hostingde": + return hostingde.NewDNSProvider() + case "httpreq": + return httpreq.NewDNSProvider() + case "iij": + return iij.NewDNSProvider() + case "inwx": + return inwx.NewDNSProvider() + case "joker": + return joker.NewDNSProvider() + case "lightsail": + return lightsail.NewDNSProvider() + case "linode": + return linode.NewDNSProvider() + case "linodev4": + return linodev4.NewDNSProvider() + case "manual": + return dns01.NewDNSProviderManual() + case "mydnsjp": + return mydnsjp.NewDNSProvider() + case "namecheap": + return namecheap.NewDNSProvider() + case "namedotcom": + return namedotcom.NewDNSProvider() + case "namesilo": + return namesilo.NewDNSProvider() + case "netcup": + return netcup.NewDNSProvider() + case "nifcloud": + return nifcloud.NewDNSProvider() + case "ns1": + return ns1.NewDNSProvider() + case "oraclecloud": + return oraclecloud.NewDNSProvider() + case "otc": + return otc.NewDNSProvider() + case "ovh": + return ovh.NewDNSProvider() + case "pdns": + return pdns.NewDNSProvider() + case "rackspace": + return rackspace.NewDNSProvider() + case "route53": + return route53.NewDNSProvider() + case "rfc2136": + return rfc2136.NewDNSProvider() + case "sakuracloud": + return sakuracloud.NewDNSProvider() + case "stackpath": + return stackpath.NewDNSProvider() + case "selectel": + return selectel.NewDNSProvider() + case "transip": + return transip.NewDNSProvider() + case "vegadns": + return vegadns.NewDNSProvider() + case "versio": + return versio.NewDNSProvider() + case "vultr": + return vultr.NewDNSProvider() + case "vscale": + return vscale.NewDNSProvider() + case "zoneee": + return zoneee.NewDNSProvider() + default: + return nil, fmt.Errorf("unrecognized DNS provider: %s", name) + } +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dnsimple/dnsimple.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsimple/dnsimple.go new file mode 100644 index 000000000..ef6333d83 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsimple/dnsimple.go @@ -0,0 +1,211 @@ +// Package dnsimple implements a DNS provider for solving the DNS-01 challenge using dnsimple DNS. +package dnsimple + +import ( + "context" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "github.com/dnsimple/dnsimple-go/dnsimple" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "golang.org/x/oauth2" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + AccessToken string + BaseURL string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("DNSIMPLE_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("DNSIMPLE_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("DNSIMPLE_POLLING_INTERVAL", dns01.DefaultPollingInterval), + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *dnsimple.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for dnsimple. +// Credentials must be passed in the environment variables: DNSIMPLE_OAUTH_TOKEN. +// +// See: https://developer.dnsimple.com/v2/#authentication +func NewDNSProvider() (*DNSProvider, error) { + config := NewDefaultConfig() + config.AccessToken = env.GetOrFile("DNSIMPLE_OAUTH_TOKEN") + config.BaseURL = env.GetOrFile("DNSIMPLE_BASE_URL") + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for DNSimple. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("dnsimple: the configuration of the DNS provider is nil") + } + + if config.AccessToken == "" { + return nil, fmt.Errorf("dnsimple: OAuth token is missing") + } + + ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: config.AccessToken}) + client := dnsimple.NewClient(oauth2.NewClient(context.Background(), ts)) + + if config.BaseURL != "" { + client.BaseURL = config.BaseURL + } + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zoneName, err := d.getHostedZone(domain) + if err != nil { + return fmt.Errorf("dnsimple: %v", err) + } + + accountID, err := d.getAccountID() + if err != nil { + return fmt.Errorf("dnsimple: %v", err) + } + + recordAttributes := newTxtRecord(zoneName, fqdn, value, d.config.TTL) + _, err = d.client.Zones.CreateRecord(accountID, zoneName, recordAttributes) + if err != nil { + return fmt.Errorf("dnsimple: API call failed: %v", err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + records, err := d.findTxtRecords(domain, fqdn) + if err != nil { + return fmt.Errorf("dnsimple: %v", err) + } + + accountID, err := d.getAccountID() + if err != nil { + return fmt.Errorf("dnsimple: %v", err) + } + + var lastErr error + for _, rec := range records { + _, err := d.client.Zones.DeleteRecord(accountID, rec.ZoneID, rec.ID) + if err != nil { + lastErr = fmt.Errorf("dnsimple: %v", err) + } + } + + return lastErr +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) getHostedZone(domain string) (string, error) { + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return "", err + } + + accountID, err := d.getAccountID() + if err != nil { + return "", err + } + + zoneName := dns01.UnFqdn(authZone) + + zones, err := d.client.Zones.ListZones(accountID, &dnsimple.ZoneListOptions{NameLike: zoneName}) + if err != nil { + return "", fmt.Errorf("API call failed: %v", err) + } + + var hostedZone dnsimple.Zone + for _, zone := range zones.Data { + if zone.Name == zoneName { + hostedZone = zone + } + } + + if hostedZone.ID == 0 { + return "", fmt.Errorf("zone %s not found in DNSimple for domain %s", authZone, domain) + } + + return hostedZone.Name, nil +} + +func (d *DNSProvider) findTxtRecords(domain, fqdn string) ([]dnsimple.ZoneRecord, error) { + zoneName, err := d.getHostedZone(domain) + if err != nil { + return nil, err + } + + accountID, err := d.getAccountID() + if err != nil { + return nil, err + } + + recordName := extractRecordName(fqdn, zoneName) + + result, err := d.client.Zones.ListRecords(accountID, zoneName, &dnsimple.ZoneRecordListOptions{Name: recordName, Type: "TXT", ListOptions: dnsimple.ListOptions{}}) + if err != nil { + return nil, fmt.Errorf("API call has failed: %v", err) + } + + return result.Data, nil +} + +func newTxtRecord(zoneName, fqdn, value string, ttl int) dnsimple.ZoneRecord { + name := extractRecordName(fqdn, zoneName) + + return dnsimple.ZoneRecord{ + Type: "TXT", + Name: name, + Content: value, + TTL: ttl, + } +} + +func extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} + +func (d *DNSProvider) getAccountID() (string, error) { + whoamiResponse, err := d.client.Identity.Whoami() + if err != nil { + return "", err + } + + if whoamiResponse.Data.Account == nil { + return "", fmt.Errorf("user tokens are not supported, please use an account token") + } + + return strconv.FormatInt(whoamiResponse.Data.Account.ID, 10), nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dnsimple/dnsimple.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsimple/dnsimple.toml new file mode 100644 index 000000000..5a78e76ca --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsimple/dnsimple.toml @@ -0,0 +1,20 @@ +Name = "DNSimple" +Description = '''''' +URL = "https://dnsimple.com/" +Code = "dnsimple" +Since = "v0.3.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + DNSIMPLE_OAUTH_TOKEN = "OAuth token" + DNSIMPLE_BASE_URL = "API endpoint URL" + [Configuration.Additional] + DNSIMPLE_POLLING_INTERVAL = "Time between DNS propagation check" + DNSIMPLE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DNSIMPLE_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://developer.dnsimple.com/v2/" + GoClient = "https://github.com/dnsimple/dnsimple-go" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/dnsmadeeasy.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/dnsmadeeasy.go new file mode 100644 index 000000000..b3968070b --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/dnsmadeeasy.go @@ -0,0 +1,163 @@ +// Package dnsmadeeasy implements a DNS provider for solving the DNS-01 challenge using DNS Made Easy. +package dnsmadeeasy + +import ( + "crypto/tls" + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/internal" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + APIKey string + APISecret string + Sandbox bool + HTTPClient *http.Client + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("DNSMADEEASY_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("DNSMADEEASY_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("DNSMADEEASY_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("DNSMADEEASY_HTTP_TIMEOUT", 10*time.Second), + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses +// DNSMadeEasy's DNS API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + client *internal.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for DNSMadeEasy DNS. +// Credentials must be passed in the environment variables: +// DNSMADEEASY_API_KEY and DNSMADEEASY_API_SECRET. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("DNSMADEEASY_API_KEY", "DNSMADEEASY_API_SECRET") + if err != nil { + return nil, fmt.Errorf("dnsmadeeasy: %v", err) + } + + config := NewDefaultConfig() + config.Sandbox = env.GetOrDefaultBool("DNSMADEEASY_SANDBOX", false) + config.APIKey = values["DNSMADEEASY_API_KEY"] + config.APISecret = values["DNSMADEEASY_API_SECRET"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for DNS Made Easy. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("dnsmadeeasy: the configuration of the DNS provider is nil") + } + + var baseURL string + if config.Sandbox { + baseURL = "https://api.sandbox.dnsmadeeasy.com/V2.0" + } else { + if len(config.BaseURL) > 0 { + baseURL = config.BaseURL + } else { + baseURL = "https://api.dnsmadeeasy.com/V2.0" + } + } + + client, err := internal.NewClient(config.APIKey, config.APISecret) + if err != nil { + return nil, fmt.Errorf("dnsmadeeasy: %v", err) + } + + client.HTTPClient = config.HTTPClient + client.BaseURL = baseURL + + return &DNSProvider{ + client: client, + config: config, + }, nil +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domainName, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domainName, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("dnsmadeeasy: unable to find zone for %s: %v", fqdn, err) + } + + // fetch the domain details + domain, err := d.client.GetDomain(authZone) + if err != nil { + return fmt.Errorf("dnsmadeeasy: unable to get domain for zone %s: %v", authZone, err) + } + + // create the TXT record + name := strings.Replace(fqdn, "."+authZone, "", 1) + record := &internal.Record{Type: "TXT", Name: name, Value: value, TTL: d.config.TTL} + + err = d.client.CreateRecord(domain, record) + if err != nil { + return fmt.Errorf("dnsmadeeasy: unable to create record for %s: %v", name, err) + } + return nil +} + +// CleanUp removes the TXT records matching the specified parameters +func (d *DNSProvider) CleanUp(domainName, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domainName, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("dnsmadeeasy: unable to find zone for %s: %v", fqdn, err) + } + + // fetch the domain details + domain, err := d.client.GetDomain(authZone) + if err != nil { + return fmt.Errorf("dnsmadeeasy: unable to get domain for zone %s: %v", authZone, err) + } + + // find matching records + name := strings.Replace(fqdn, "."+authZone, "", 1) + records, err := d.client.GetRecords(domain, name, "TXT") + if err != nil { + return fmt.Errorf("dnsmadeeasy: unable to get records for domain %s: %v", domain.Name, err) + } + + // delete records + var lastError error + for _, record := range *records { + err = d.client.DeleteRecord(record) + if err != nil { + lastError = fmt.Errorf("dnsmadeeasy: unable to delete record [id=%d, name=%s]: %v", record.ID, record.Name, err) + } + } + + return lastError +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/dnsmadeeasy.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/dnsmadeeasy.toml new file mode 100644 index 000000000..a3e927049 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/dnsmadeeasy.toml @@ -0,0 +1,21 @@ +Name = "DNS Made Easy" +Description = '''''' +URL = "https://dnsmadeeasy.com/" +Code = "dnsmadeeasy" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + DNSMADEEASY_API_KEY = "The API key" + DNSMADEEASY_API_SECRET = "The API Secret key" + [Configuration.Additional] + DNSMADEEASY_SANDBOX = "Activate the sandbox (boolean)" + DNSMADEEASY_POLLING_INTERVAL = "Time between DNS propagation check" + DNSMADEEASY_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DNSMADEEASY_TTL = "The TTL of the TXT record used for the DNS challenge" + DNSMADEEASY_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://api-docs.dnsmadeeasy.com/" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/internal/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/internal/client.go new file mode 100644 index 000000000..748d385d8 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dnsmadeeasy/internal/client.go @@ -0,0 +1,173 @@ +package internal + +import ( + "bytes" + "crypto/hmac" + "crypto/sha1" + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" +) + +// Domain holds the DNSMadeEasy API representation of a Domain +type Domain struct { + ID int `json:"id"` + Name string `json:"name"` +} + +// Record holds the DNSMadeEasy API representation of a Domain Record +type Record struct { + ID int `json:"id"` + Type string `json:"type"` + Name string `json:"name"` + Value string `json:"value"` + TTL int `json:"ttl"` + SourceID int `json:"sourceId"` +} + +type recordsResponse struct { + Records *[]Record `json:"data"` +} + +// Client DNSMadeEasy client +type Client struct { + apiKey string + apiSecret string + BaseURL string + HTTPClient *http.Client +} + +// NewClient creates a DNSMadeEasy client +func NewClient(apiKey string, apiSecret string) (*Client, error) { + if apiKey == "" { + return nil, fmt.Errorf("credentials missing: API key") + } + + if apiSecret == "" { + return nil, fmt.Errorf("credentials missing: API secret") + } + + return &Client{ + apiKey: apiKey, + apiSecret: apiSecret, + HTTPClient: &http.Client{}, + }, nil +} + +// GetDomain gets a domain +func (c *Client) GetDomain(authZone string) (*Domain, error) { + domainName := authZone[0 : len(authZone)-1] + resource := fmt.Sprintf("%s%s", "/dns/managed/name?domainname=", domainName) + + resp, err := c.sendRequest(http.MethodGet, resource, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + domain := &Domain{} + err = json.NewDecoder(resp.Body).Decode(&domain) + if err != nil { + return nil, err + } + + return domain, nil +} + +// GetRecords gets all TXT records +func (c *Client) GetRecords(domain *Domain, recordName, recordType string) (*[]Record, error) { + resource := fmt.Sprintf("%s/%d/%s%s%s%s", "/dns/managed", domain.ID, "records?recordName=", recordName, "&type=", recordType) + + resp, err := c.sendRequest(http.MethodGet, resource, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + records := &recordsResponse{} + err = json.NewDecoder(resp.Body).Decode(&records) + if err != nil { + return nil, err + } + + return records.Records, nil +} + +// CreateRecord creates a TXT records +func (c *Client) CreateRecord(domain *Domain, record *Record) error { + url := fmt.Sprintf("%s/%d/%s", "/dns/managed", domain.ID, "records") + + resp, err := c.sendRequest(http.MethodPost, url, record) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +// DeleteRecord deletes a TXT records +func (c *Client) DeleteRecord(record Record) error { + resource := fmt.Sprintf("%s/%d/%s/%d", "/dns/managed", record.SourceID, "records", record.ID) + + resp, err := c.sendRequest(http.MethodDelete, resource, nil) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +func (c *Client) sendRequest(method, resource string, payload interface{}) (*http.Response, error) { + url := fmt.Sprintf("%s%s", c.BaseURL, resource) + + body, err := json.Marshal(payload) + if err != nil { + return nil, err + } + + timestamp := time.Now().UTC().Format(time.RFC1123) + signature, err := computeHMAC(timestamp, c.apiSecret) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, url, bytes.NewReader(body)) + if err != nil { + return nil, err + } + req.Header.Set("x-dnsme-apiKey", c.apiKey) + req.Header.Set("x-dnsme-requestDate", timestamp) + req.Header.Set("x-dnsme-hmac", signature) + req.Header.Set("accept", "application/json") + req.Header.Set("content-type", "application/json") + + resp, err := c.HTTPClient.Do(req) + if err != nil { + return nil, err + } + + if resp.StatusCode > 299 { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("request failed with HTTP status code %d", resp.StatusCode) + } + return nil, fmt.Errorf("request failed with HTTP status code %d: %s", resp.StatusCode, string(body)) + } + + return resp, nil +} + +func computeHMAC(message string, secret string) (string, error) { + key := []byte(secret) + h := hmac.New(sha1.New, key) + _, err := h.Write([]byte(message)) + if err != nil { + return "", err + } + return hex.EncodeToString(h.Sum(nil)), nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dnspod/dnspod.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dnspod/dnspod.go new file mode 100644 index 000000000..1d4c15783 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dnspod/dnspod.go @@ -0,0 +1,188 @@ +// Package dnspod implements a DNS provider for solving the DNS-01 challenge using dnspod DNS. +package dnspod + +import ( + "errors" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + dnspod "github.com/decker502/dnspod-go" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + LoginToken string + TTL int + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("DNSPOD_TTL", 600), + PropagationTimeout: env.GetOrDefaultSecond("DNSPOD_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("DNSPOD_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("DNSPOD_HTTP_TIMEOUT", 0), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *dnspod.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for dnspod. +// Credentials must be passed in the environment variables: DNSPOD_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("DNSPOD_API_KEY") + if err != nil { + return nil, fmt.Errorf("dnspod: %v", err) + } + + config := NewDefaultConfig() + config.LoginToken = values["DNSPOD_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for dnspod. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("dnspod: the configuration of the DNS provider is nil") + } + + if config.LoginToken == "" { + return nil, fmt.Errorf("dnspod: credentials missing") + } + + params := dnspod.CommonParams{LoginToken: config.LoginToken, Format: "json"} + + client := dnspod.NewClient(params) + client.HttpClient = config.HTTPClient + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + zoneID, zoneName, err := d.getHostedZone(domain) + if err != nil { + return err + } + + recordAttributes := d.newTxtRecord(zoneName, fqdn, value, d.config.TTL) + _, _, err = d.client.Domains.CreateRecord(zoneID, *recordAttributes) + if err != nil { + return fmt.Errorf("API call failed: %v", err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + records, err := d.findTxtRecords(domain, fqdn) + if err != nil { + return err + } + + zoneID, _, err := d.getHostedZone(domain) + if err != nil { + return err + } + + for _, rec := range records { + _, err := d.client.Domains.DeleteRecord(zoneID, rec.ID) + if err != nil { + return err + } + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) getHostedZone(domain string) (string, string, error) { + zones, _, err := d.client.Domains.List() + if err != nil { + return "", "", fmt.Errorf("API call failed: %v", err) + } + + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return "", "", err + } + + var hostedZone dnspod.Domain + for _, zone := range zones { + if zone.Name == dns01.UnFqdn(authZone) { + hostedZone = zone + } + } + + if hostedZone.ID == "" || hostedZone.ID == "0" { + return "", "", fmt.Errorf("zone %s not found in dnspod for domain %s", authZone, domain) + } + + return fmt.Sprintf("%v", hostedZone.ID), hostedZone.Name, nil +} + +func (d *DNSProvider) newTxtRecord(zone, fqdn, value string, ttl int) *dnspod.Record { + name := d.extractRecordName(fqdn, zone) + + return &dnspod.Record{ + Type: "TXT", + Name: name, + Value: value, + Line: "默认", + TTL: strconv.Itoa(ttl), + } +} + +func (d *DNSProvider) findTxtRecords(domain, fqdn string) ([]dnspod.Record, error) { + zoneID, zoneName, err := d.getHostedZone(domain) + if err != nil { + return nil, err + } + + var records []dnspod.Record + result, _, err := d.client.Domains.ListRecords(zoneID, "") + if err != nil { + return records, fmt.Errorf("API call has failed: %v", err) + } + + recordName := d.extractRecordName(fqdn, zoneName) + + for _, record := range result { + if record.Name == recordName { + records = append(records, record) + } + } + + return records, nil +} + +func (d *DNSProvider) extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dnspod/dnspod.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/dnspod/dnspod.toml new file mode 100644 index 000000000..60aaea761 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dnspod/dnspod.toml @@ -0,0 +1,20 @@ +Name = "DNSPod" +Description = '''''' +URL = "http://www.dnspod.com/" +Code = "dnspod" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + DNSPOD_API_KEY = "The user token" + [Configuration.Additional] + DNSPOD_POLLING_INTERVAL = "Time between DNS propagation check" + DNSPOD_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DNSPOD_TTL = "The TTL of the TXT record used for the DNS challenge" + DNSPOD_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.dnspod.com/docs/index.html" + GoClient = "https://github.com/decker502/dnspod-go" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dode/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dode/client.go new file mode 100644 index 000000000..828191233 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dode/client.go @@ -0,0 +1,57 @@ +package dode + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/url" + + "github.com/go-acme/lego/v3/challenge/dns01" +) + +type apiResponse struct { + Domain string + Success bool +} + +// updateTxtRecord Update the domains TXT record +// To update the TXT record we just need to make one simple get request. +func (d *DNSProvider) updateTxtRecord(fqdn, token, txt string, clear bool) error { + u, _ := url.Parse("https://www.do.de/api/letsencrypt") + + query := u.Query() + query.Set("token", token) + query.Set("domain", dns01.UnFqdn(fqdn)) + + // api call differs per set/delete + if clear { + query.Set("action", "delete") + } else { + query.Set("value", txt) + } + + u.RawQuery = query.Encode() + + response, err := d.config.HTTPClient.Get(u.String()) + if err != nil { + return err + } + defer response.Body.Close() + + bodyBytes, err := ioutil.ReadAll(response.Body) + if err != nil { + return err + } + + var r apiResponse + err = json.Unmarshal(bodyBytes, &r) + if err != nil { + return fmt.Errorf("request to change TXT record for do.de returned the following invalid json (%s); used url [%s]", string(bodyBytes), u) + } + + body := string(bodyBytes) + if !r.Success { + return fmt.Errorf("request to change TXT record for do.de returned the following error result (%s); used url [%s]", body, u) + } + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dode/dode.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dode/dode.go new file mode 100644 index 000000000..35814cbb2 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dode/dode.go @@ -0,0 +1,89 @@ +// Package dode implements a DNS provider for solving the DNS-01 challenge using do.de. +package dode + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Token string + PropagationTimeout time.Duration + PollingInterval time.Duration + SequenceInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("DODE_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("DODE_POLLING_INTERVAL", dns01.DefaultPollingInterval), + SequenceInterval: env.GetOrDefaultSecond("DODE_SEQUENCE_INTERVAL", dns01.DefaultPropagationTimeout), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("DODE_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider adds and removes the record for the DNS challenge +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a new DNS provider using +// environment variable DODE_TOKEN for adding and removing the DNS record. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("DODE_TOKEN") + if err != nil { + return nil, fmt.Errorf("do.de: %v", err) + } + + config := NewDefaultConfig() + config.Token = values["DODE_TOKEN"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for do.de. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("do.de: the configuration of the DNS provider is nil") + } + + if config.Token == "" { + return nil, errors.New("do.de: credentials missing") + } + + return &DNSProvider{config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, txtRecord := dns01.GetRecord(domain, keyAuth) + return d.updateTxtRecord(fqdn, d.config.Token, txtRecord, false) +} + +// CleanUp clears TXT record +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + return d.updateTxtRecord(fqdn, d.config.Token, "", true) +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProvider) Sequential() time.Duration { + return d.config.SequenceInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dode/dode.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/dode/dode.toml new file mode 100644 index 000000000..470b73062 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dode/dode.toml @@ -0,0 +1,20 @@ +Name = "Domain Offensive (do.de)" +Description = '''''' +URL = "https://www.do.de/" +Code = "dode" +Since = "v2.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + DODE_TOKEN = "API token" + [Configuration.Additional] + DODE_POLLING_INTERVAL = "Time between DNS propagation check" + DODE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DODE_TTL = "The TTL of the TXT record used for the DNS challenge" + DODE_HTTP_TIMEOUT = "API request timeout" + DODE_SEQUENCE_INTERVAL = "Interval between iteration" + +[Links] + API = "https://www.do.de/wiki/LetsEncrypt_-_Entwickler" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/client.go new file mode 100644 index 000000000..5313385de --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/client.go @@ -0,0 +1,73 @@ +package dreamhost + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/url" + + "github.com/go-acme/lego/v3/log" +) + +const ( + defaultBaseURL = "https://api.dreamhost.com" + + cmdAddRecord = "dns-add_record" + cmdRemoveRecord = "dns-remove_record" +) + +type apiResponse struct { + Data string `json:"data"` + Result string `json:"result"` +} + +func (d *DNSProvider) buildQuery(action, domain, txt string) (*url.URL, error) { + u, err := url.Parse(d.config.BaseURL) + if err != nil { + return nil, err + } + + query := u.Query() + query.Set("key", d.config.APIKey) + query.Set("cmd", action) + query.Set("format", "json") + query.Set("record", domain) + query.Set("type", "TXT") + query.Set("value", txt) + query.Set("comment", url.QueryEscape("Managed By lego")) + u.RawQuery = query.Encode() + + return u, nil +} + +// updateTxtRecord will either add or remove a TXT record. +// action is either cmdAddRecord or cmdRemoveRecord +func (d *DNSProvider) updateTxtRecord(u fmt.Stringer) error { + resp, err := d.config.HTTPClient.Get(u.String()) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return fmt.Errorf("request failed with HTTP status code %d", resp.StatusCode) + } + + raw, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("failed to read body: %v", err) + } + + var response apiResponse + err = json.Unmarshal(raw, &response) + if err != nil { + return fmt.Errorf("unable to decode API server response: %v: %s", err, string(raw)) + } + + if response.Result == "error" { + return fmt.Errorf("add TXT record failed: %s", response.Data) + } + + log.Infof("dreamhost: %s", response.Data) + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/dreamhost.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/dreamhost.go new file mode 100644 index 000000000..1a157b485 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/dreamhost.go @@ -0,0 +1,111 @@ +// Package dreamhost implements a DNS provider for solving the DNS-01 challenge using DreamHost. +// See https://help.dreamhost.com/hc/en-us/articles/217560167-API_overview +// and https://help.dreamhost.com/hc/en-us/articles/217555707-DNS-API-commands for the API spec. +package dreamhost + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + BaseURL: defaultBaseURL, + PropagationTimeout: env.GetOrDefaultSecond("DREAMHOST_PROPAGATION_TIMEOUT", 60*time.Minute), + PollingInterval: env.GetOrDefaultSecond("DREAMHOST_POLLING_INTERVAL", 1*time.Minute), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("DREAMHOST_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider adds and removes the record for the DNS challenge +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a new DNS provider using +// environment variable DREAMHOST_TOKEN for adding and removing the DNS record. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("DREAMHOST_API_KEY") + if err != nil { + return nil, fmt.Errorf("dreamhost: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["DREAMHOST_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for DreamHost. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("dreamhost: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + return nil, errors.New("dreamhost: credentials missing") + } + + if config.BaseURL == "" { + config.BaseURL = defaultBaseURL + } + + return &DNSProvider{config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + record := dns01.UnFqdn(fqdn) + + u, err := d.buildQuery(cmdAddRecord, record, value) + if err != nil { + return fmt.Errorf("dreamhost: %v", err) + } + + err = d.updateTxtRecord(u) + if err != nil { + return fmt.Errorf("dreamhost: %v", err) + } + return nil +} + +// CleanUp clears DreamHost TXT record +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + record := dns01.UnFqdn(fqdn) + + u, err := d.buildQuery(cmdRemoveRecord, record, value) + if err != nil { + return fmt.Errorf("dreamhost: %v", err) + } + + err = d.updateTxtRecord(u) + if err != nil { + return fmt.Errorf("dreamhost: %v", err) + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/dreamhost.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/dreamhost.toml new file mode 100644 index 000000000..4e6eeb160 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dreamhost/dreamhost.toml @@ -0,0 +1,19 @@ +Name = "DreamHost" +Description = '''''' +URL = "https://www.dreamhost.com" +Code = "dreamhost" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + DREAMHOST_API_KEY = "The API key" + [Configuration.Additional] + DREAMHOST_POLLING_INTERVAL = "Time between DNS propagation check" + DREAMHOST_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DREAMHOST_TTL = "The TTL of the TXT record used for the DNS challenge" + DREAMHOST_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://help.dreamhost.com/hc/en-us/articles/217560167-API_overview" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/client.go new file mode 100644 index 000000000..03f12b130 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/client.go @@ -0,0 +1,68 @@ +package duckdns + +import ( + "fmt" + "io/ioutil" + "net/url" + "strconv" + "strings" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/miekg/dns" +) + +// updateTxtRecord Update the domains TXT record +// To update the TXT record we just need to make one simple get request. +// In DuckDNS you only have one TXT record shared with the domain and all sub domains. +func (d *DNSProvider) updateTxtRecord(domain, token, txt string, clear bool) error { + u, _ := url.Parse("https://www.duckdns.org/update") + + mainDomain := getMainDomain(domain) + if len(mainDomain) == 0 { + return fmt.Errorf("unable to find the main domain for: %s", domain) + } + + query := u.Query() + query.Set("domains", mainDomain) + query.Set("token", token) + query.Set("clear", strconv.FormatBool(clear)) + query.Set("txt", txt) + u.RawQuery = query.Encode() + + response, err := d.config.HTTPClient.Get(u.String()) + if err != nil { + return err + } + defer response.Body.Close() + + bodyBytes, err := ioutil.ReadAll(response.Body) + if err != nil { + return err + } + + body := string(bodyBytes) + if body != "OK" { + return fmt.Errorf("request to change TXT record for DuckDNS returned the following result (%s) this does not match expectation (OK) used url [%s]", body, u) + } + return nil +} + +// DuckDNS only lets you write to your subdomain +// so it must be in format subdomain.duckdns.org +// not in format subsubdomain.subdomain.duckdns.org +// so strip off everything that is not top 3 levels +func getMainDomain(domain string) string { + domain = dns01.UnFqdn(domain) + + split := dns.Split(domain) + if strings.HasSuffix(strings.ToLower(domain), "duckdns.org") { + if len(split) < 3 { + return "" + } + + firstSubDomainIndex := split[len(split)-3] + return domain[firstSubDomainIndex:] + } + + return domain[split[len(split)-1]:] +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/duckdns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/duckdns.go new file mode 100644 index 000000000..aec365911 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/duckdns.go @@ -0,0 +1,89 @@ +// Package duckdns implements a DNS provider for solving the DNS-01 challenge using DuckDNS. +// See http://www.duckdns.org/spec.jsp for more info on updating TXT records. +package duckdns + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Token string + PropagationTimeout time.Duration + PollingInterval time.Duration + SequenceInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("DUCKDNS_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("DUCKDNS_POLLING_INTERVAL", dns01.DefaultPollingInterval), + SequenceInterval: env.GetOrDefaultSecond("DUCKDNS_SEQUENCE_INTERVAL", dns01.DefaultPropagationTimeout), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("DUCKDNS_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider adds and removes the record for the DNS challenge +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a new DNS provider using +// environment variable DUCKDNS_TOKEN for adding and removing the DNS record. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("DUCKDNS_TOKEN") + if err != nil { + return nil, fmt.Errorf("duckdns: %v", err) + } + + config := NewDefaultConfig() + config.Token = values["DUCKDNS_TOKEN"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for DuckDNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("duckdns: the configuration of the DNS provider is nil") + } + + if config.Token == "" { + return nil, errors.New("duckdns: credentials missing") + } + + return &DNSProvider{config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + _, txtRecord := dns01.GetRecord(domain, keyAuth) + return d.updateTxtRecord(domain, d.config.Token, txtRecord, false) +} + +// CleanUp clears DuckDNS TXT record +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + return d.updateTxtRecord(domain, d.config.Token, "", true) +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProvider) Sequential() time.Duration { + return d.config.SequenceInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/duckdns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/duckdns.toml new file mode 100644 index 000000000..6aebf8eee --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/duckdns/duckdns.toml @@ -0,0 +1,20 @@ +Name = "Duck DNS" +Description = '''''' +URL = "https://www.duckdns.org/" +Code = "duckdns" +Since = "v0.5.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + DUCKDNS_TOKEN = "Account token" + [Configuration.Additional] + DUCKDNS_POLLING_INTERVAL = "Time between DNS propagation check" + DUCKDNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DUCKDNS_TTL = "The TTL of the TXT record used for the DNS challenge" + DUCKDNS_HTTP_TIMEOUT = "API request timeout" + DUCKDNS_SEQUENCE_INTERVAL = "Interval between iteration" + +[Links] + API = "https://www.duckdns.org/spec.jsp" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/client.go new file mode 100644 index 000000000..f7e6cee84 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/client.go @@ -0,0 +1,146 @@ +package dyn + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" +) + +const defaultBaseURL = "https://api.dynect.net/REST" + +type dynResponse struct { + // One of 'success', 'failure', or 'incomplete' + Status string `json:"status"` + + // The structure containing the actual results of the request + Data json.RawMessage `json:"data"` + + // The ID of the job that was created in response to a request. + JobID int `json:"job_id"` + + // A list of zero or more messages + Messages json.RawMessage `json:"msgs"` +} + +type credentials struct { + Customer string `json:"customer_name"` + User string `json:"user_name"` + Pass string `json:"password"` +} + +type session struct { + Token string `json:"token"` + Version string `json:"version"` +} + +type publish struct { + Publish bool `json:"publish"` + Notes string `json:"notes"` +} + +// Starts a new Dyn API Session. Authenticates using customerName, userName, +// password and receives a token to be used in for subsequent requests. +func (d *DNSProvider) login() error { + payload := &credentials{Customer: d.config.CustomerName, User: d.config.UserName, Pass: d.config.Password} + dynRes, err := d.sendRequest(http.MethodPost, "Session", payload) + if err != nil { + return err + } + + var s session + err = json.Unmarshal(dynRes.Data, &s) + if err != nil { + return err + } + + d.token = s.Token + + return nil +} + +// Destroys Dyn Session +func (d *DNSProvider) logout() error { + if len(d.token) == 0 { + // nothing to do + return nil + } + + url := fmt.Sprintf("%s/Session", defaultBaseURL) + req, err := http.NewRequest(http.MethodDelete, url, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Auth-Token", d.token) + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return err + } + resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("API request failed to delete session with HTTP status code %d", resp.StatusCode) + } + + d.token = "" + + return nil +} + +func (d *DNSProvider) publish(zone, notes string) error { + pub := &publish{Publish: true, Notes: notes} + resource := fmt.Sprintf("Zone/%s/", zone) + + _, err := d.sendRequest(http.MethodPut, resource, pub) + return err +} + +func (d *DNSProvider) sendRequest(method, resource string, payload interface{}) (*dynResponse, error) { + url := fmt.Sprintf("%s/%s", defaultBaseURL, resource) + + body, err := json.Marshal(payload) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, url, bytes.NewReader(body)) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + if len(d.token) > 0 { + req.Header.Set("Auth-Token", d.token) + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode >= 500 { + return nil, fmt.Errorf("API request failed with HTTP status code %d", resp.StatusCode) + } + + var dynRes dynResponse + err = json.NewDecoder(resp.Body).Decode(&dynRes) + if err != nil { + return nil, err + } + + if resp.StatusCode >= 400 { + return nil, fmt.Errorf("API request failed with HTTP status code %d: %s", resp.StatusCode, dynRes.Messages) + } else if resp.StatusCode == 307 { + // TODO add support for HTTP 307 response and long running jobs + return nil, fmt.Errorf("API request returned HTTP 307. This is currently unsupported") + } + + if dynRes.Status == "failure" { + // TODO add better error handling + return nil, fmt.Errorf("API request failed: %s", dynRes.Messages) + } + + return &dynRes, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/dyn.go b/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/dyn.go new file mode 100644 index 000000000..9973cf6a6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/dyn.go @@ -0,0 +1,157 @@ +// Package dyn implements a DNS provider for solving the DNS-01 challenge using Dyn Managed DNS. +package dyn + +import ( + "errors" + "fmt" + "net/http" + "strconv" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + CustomerName string + UserName string + Password string + HTTPClient *http.Client + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("DYN_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("DYN_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("DYN_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("DYN_HTTP_TIMEOUT", 10*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses +// Dyn's Managed DNS API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + token string +} + +// NewDNSProvider returns a DNSProvider instance configured for Dyn DNS. +// Credentials must be passed in the environment variables: +// DYN_CUSTOMER_NAME, DYN_USER_NAME and DYN_PASSWORD. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("DYN_CUSTOMER_NAME", "DYN_USER_NAME", "DYN_PASSWORD") + if err != nil { + return nil, fmt.Errorf("dyn: %v", err) + } + + config := NewDefaultConfig() + config.CustomerName = values["DYN_CUSTOMER_NAME"] + config.UserName = values["DYN_USER_NAME"] + config.Password = values["DYN_PASSWORD"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Dyn DNS +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("dyn: the configuration of the DNS provider is nil") + } + + if config.CustomerName == "" || config.UserName == "" || config.Password == "" { + return nil, fmt.Errorf("dyn: credentials missing") + } + + return &DNSProvider{config: config}, nil +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + + err = d.login() + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + + data := map[string]interface{}{ + "rdata": map[string]string{ + "txtdata": value, + }, + "ttl": strconv.Itoa(d.config.TTL), + } + + resource := fmt.Sprintf("TXTRecord/%s/%s/", authZone, fqdn) + _, err = d.sendRequest(http.MethodPost, resource, data) + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + + err = d.publish(authZone, "Added TXT record for ACME dns-01 challenge using lego client") + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + + return d.logout() +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + + err = d.login() + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + + resource := fmt.Sprintf("TXTRecord/%s/%s/", authZone, fqdn) + url := fmt.Sprintf("%s/%s", defaultBaseURL, resource) + + req, err := http.NewRequest(http.MethodDelete, url, nil) + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Auth-Token", d.token) + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("dyn: API request failed to delete TXT record HTTP status code %d", resp.StatusCode) + } + + err = d.publish(authZone, "Removed TXT record for ACME dns-01 challenge using lego client") + if err != nil { + return fmt.Errorf("dyn: %v", err) + } + + return d.logout() +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/dyn.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/dyn.toml new file mode 100644 index 000000000..b183589ad --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/dyn/dyn.toml @@ -0,0 +1,21 @@ +Name = "Dyn" +Description = '''''' +URL = "https://dyn.com/" +Code = "dyn" +Since = "v0.3.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + DYN_CUSTOMER_NAME = "Customer name" + DYN_USER_NAME = "User name" + DYN_PASSWORD = "Paswword" + [Configuration.Additional] + DYN_POLLING_INTERVAL = "Time between DNS propagation check" + DYN_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + DYN_TTL = "The TTL of the TXT record used for the DNS challenge" + DYN_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://help.dyn.com/rest/" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/client.go new file mode 100644 index 000000000..3d2c565b2 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/client.go @@ -0,0 +1,97 @@ +package easydns + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "path" +) + +const defaultEndpoint = "https://rest.easydns.net" + +type zoneRecord struct { + ID string `json:"id,omitempty"` + Domain string `json:"domain"` + Host string `json:"host"` + TTL string `json:"ttl"` + Prio string `json:"prio"` + Type string `json:"type"` + Rdata string `json:"rdata"` + LastMod string `json:"last_mod,omitempty"` + Revoked int `json:"revoked,omitempty"` + NewHost string `json:"new_host,omitempty"` +} + +type addRecordResponse struct { + Msg string `json:"msg"` + Tm int `json:"tm"` + Data zoneRecord `json:"data"` + Status int `json:"status"` +} + +func (d *DNSProvider) addRecord(domain string, record interface{}) (string, error) { + pathAdd := path.Join("/zones/records/add", domain, "TXT") + + response := &addRecordResponse{} + err := d.doRequest(http.MethodPut, pathAdd, record, response) + if err != nil { + return "", err + } + + recordID := response.Data.ID + + return recordID, nil +} + +func (d *DNSProvider) deleteRecord(domain, recordID string) error { + pathDelete := path.Join("/zones/records", domain, recordID) + + return d.doRequest(http.MethodDelete, pathDelete, nil, nil) +} + +func (d *DNSProvider) doRequest(method, path string, requestMsg, responseMsg interface{}) error { + reqBody := &bytes.Buffer{} + if requestMsg != nil { + err := json.NewEncoder(reqBody).Encode(requestMsg) + if err != nil { + return err + } + } + + endpoint, err := d.config.Endpoint.Parse(path + "?format=json") + if err != nil { + return err + } + + request, err := http.NewRequest(method, endpoint.String(), reqBody) + if err != nil { + return err + } + + request.Header.Set("Content-Type", "application/json") + request.Header.Set("Accept", "application/json") + request.SetBasicAuth(d.config.Token, d.config.Key) + + response, err := d.config.HTTPClient.Do(request) + if err != nil { + return err + } + defer response.Body.Close() + + if response.StatusCode >= http.StatusBadRequest { + body, err := ioutil.ReadAll(response.Body) + if err != nil { + return fmt.Errorf("%d: failed to read response body: %v", response.StatusCode, err) + } + + return fmt.Errorf("%d: request failed: %v", response.StatusCode, string(body)) + } + + if responseMsg != nil { + return json.NewDecoder(response.Body).Decode(responseMsg) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/easydns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/easydns.go new file mode 100644 index 000000000..483be6f58 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/easydns.go @@ -0,0 +1,165 @@ +// Package easydns implements a DNS provider for solving the DNS-01 challenge using EasyDNS API. +package easydns + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + "sync" + "time" + + "github.com/miekg/dns" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Endpoint *url.URL + Token string + Key string + TTL int + HTTPClient *http.Client + PropagationTimeout time.Duration + PollingInterval time.Duration + SequenceInterval time.Duration +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("EASYDNS_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + SequenceInterval: env.GetOrDefaultSecond("EASYDNS_SEQUENCE_INTERVAL", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("EASYDNS_POLLING_INTERVAL", dns01.DefaultPollingInterval), + TTL: env.GetOrDefaultInt("EASYDNS_TTL", dns01.DefaultTTL), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("EASYDNS_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider describes a provider for acme-proxy +type DNSProvider struct { + config *Config + recordIDs map[string]string + recordIDsMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance. +func NewDNSProvider() (*DNSProvider, error) { + config := NewDefaultConfig() + + endpoint, err := url.Parse(env.GetOrDefaultString("EASYDNS_ENDPOINT", defaultEndpoint)) + if err != nil { + return nil, fmt.Errorf("easydns: %v", err) + } + config.Endpoint = endpoint + + values, err := env.Get("EASYDNS_TOKEN", "EASYDNS_KEY") + if err != nil { + return nil, fmt.Errorf("easydns: %v", err) + } + + config.Token = values["EASYDNS_TOKEN"] + config.Key = values["EASYDNS_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider . +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("easydns: the configuration of the DNS provider is nil") + } + + if config.Token == "" { + return nil, errors.New("easydns: the API token is missing") + } + + if config.Key == "" { + return nil, errors.New("easydns: the API key is missing") + } + + return &DNSProvider{config: config, recordIDs: map[string]string{}}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + apiHost, apiDomain := splitFqdn(fqdn) + record := &zoneRecord{ + Domain: apiDomain, + Host: apiHost, + Type: "TXT", + Rdata: value, + TTL: strconv.Itoa(d.config.TTL), + Prio: "0", + } + + recordID, err := d.addRecord(apiDomain, record) + if err != nil { + return fmt.Errorf("easydns: error adding zone record: %v", err) + } + + key := getMapKey(fqdn, value) + + d.recordIDsMu.Lock() + d.recordIDs[key] = recordID + d.recordIDsMu.Unlock() + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, challenge := dns01.GetRecord(domain, keyAuth) + + key := getMapKey(fqdn, challenge) + recordID, exists := d.recordIDs[key] + if !exists { + return nil + } + + _, apiDomain := splitFqdn(fqdn) + err := d.deleteRecord(apiDomain, recordID) + + d.recordIDsMu.Lock() + defer delete(d.recordIDs, key) + d.recordIDsMu.Unlock() + + if err != nil { + return fmt.Errorf("easydns: %v", err) + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProvider) Sequential() time.Duration { + return d.config.SequenceInterval +} + +func splitFqdn(fqdn string) (host, domain string) { + parts := dns.SplitDomainName(fqdn) + length := len(parts) + + host = strings.Join(parts[0:length-2], ".") + domain = strings.Join(parts[length-2:length], ".") + return +} + +func getMapKey(fqdn, value string) string { + return fqdn + "|" + value +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/easydns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/easydns.toml new file mode 100644 index 000000000..01e866e66 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/easydns/easydns.toml @@ -0,0 +1,30 @@ +Name = "EasyDNS" +Description = '''''' +URL = "https://easydns.com/" +Code = "easydns" +Since = "v2.6.0" + +Example = ''' +EASYDNS_TOKEN= \ +EASYDNS_KEY= \ +lego --dns easydns --domains my.domain.com --email my@email.com run +''' + +Additional = ''' +To test with the sandbox environment set ```EASYDNS_ENDPOINT=https://sandbox.rest.easydns.net``` +''' + +[Configuration] + [Configuration.Credentials] + EASYDNS_TOKEN = "API Token" + EASYDNS_KEY = "API Key" + [Configuration.Additional] + EASYDNS_ENDPOINT = "The endpoint URL of the API Server" + EASYDNS_POLLING_INTERVAL = "Time between DNS propagation check" + EASYDNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + EASYDNS_SEQUENCE_INTERVAL = "Time between sequential requests" + EASYDNS_TTL = "The TTL of the TXT record used for the DNS challenge" + EASYDNS_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "http://docs.sandbox.rest.easydns.net" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/exec/exec.go b/vendor/github.com/go-acme/lego/v3/providers/dns/exec/exec.go new file mode 100644 index 000000000..f60964c6d --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/exec/exec.go @@ -0,0 +1,113 @@ +// Package exec implements a DNS provider which runs a program for adding/removing the DNS record. +package exec + +import ( + "errors" + "fmt" + "os" + "os/exec" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config Provider configuration. +type Config struct { + Program string + Mode string + PropagationTimeout time.Duration + PollingInterval time.Duration +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("EXEC_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("EXEC_POLLING_INTERVAL", dns01.DefaultPollingInterval), + } +} + +// DNSProvider adds and removes the record for the DNS challenge by calling a +// program with command-line parameters. +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a new DNS provider which runs the program in the +// environment variable EXEC_PATH for adding and removing the DNS record. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("EXEC_PATH") + if err != nil { + return nil, fmt.Errorf("exec: %v", err) + } + + config := NewDefaultConfig() + config.Program = values["EXEC_PATH"] + config.Mode = os.Getenv("EXEC_MODE") + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig returns a new DNS provider which runs the given configuration +// for adding and removing the DNS record. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("the configuration is nil") + } + + return &DNSProvider{config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + var args []string + if d.config.Mode == "RAW" { + args = []string{"present", "--", domain, token, keyAuth} + } else { + fqdn, value := dns01.GetRecord(domain, keyAuth) + args = []string{"present", fqdn, value} + } + + cmd := exec.Command(d.config.Program, args...) + + output, err := cmd.CombinedOutput() + if len(output) > 0 { + log.Println(string(output)) + } + + return err +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + var args []string + if d.config.Mode == "RAW" { + args = []string{"cleanup", "--", domain, token, keyAuth} + } else { + fqdn, value := dns01.GetRecord(domain, keyAuth) + args = []string{"cleanup", fqdn, value} + } + + cmd := exec.Command(d.config.Program, args...) + + output, err := cmd.CombinedOutput() + if len(output) > 0 { + log.Println(string(output)) + } + + return err +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProvider) Sequential() time.Duration { + return d.config.PropagationTimeout +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/exec/exec.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/exec/exec.toml new file mode 100644 index 000000000..615c55d90 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/exec/exec.toml @@ -0,0 +1,111 @@ +Name = "External program" +Description = "Solving the DNS-01 challenge using an external program." +URL = "/dns/exec" +Code = "exec" +Since = "v0.5.0" + +Example = ''' +EXEC_PATH=/the/path/to/myscript.sh \ +lego --dns exec --domains my.domain.com --email my@email.com run +''' + +Additional = ''' + +## Base Configuration + +| Environment Variable Name | Description | +|---------------------------|---------------------------------------| +| `EXEC_MODE` | `RAW`, none | +| `EXEC_PATH` | The path of the the external program. | + + +## Additional Configuration + +| Environment Variable Name | Description | +|----------------------------|-------------------------------------------| +| `EXEC_POLLING_INTERVAL` | Time between DNS propagation check. | +| `EXEC_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation. | + + +## Description + +The file name of the external program is specified in the environment variable `EXEC_PATH`. + +When it is run by lego, three command-line parameters are passed to it: +The action ("present" or "cleanup"), the fully-qualified domain name and the value for the record. + +For example, requesting a certificate for the domain 'foo.example.com' can be achieved by calling lego as follows: + +```bash +EXEC_PATH=./update-dns.sh \ + lego --dns exec \ + --domains foo.example.com \ + --email invalid@example.com run +``` + +It will then call the program './update-dns.sh' with like this: + +```bash +./update-dns.sh "present" "_acme-challenge.foo.example.com." "MsijOYZxqyjGnFGwhjrhfg-Xgbl5r68WPda0J9EgqqI" +``` + +The program then needs to make sure the record is inserted. +When it returns an error via a non-zero exit code, lego aborts. + +When the record is to be removed again, +the program is called with the first command-line parameter set to `cleanup` instead of `present`. + +If you want to use the raw domain, token, and keyAuth values with your program, you can set `EXEC_MODE=RAW`: + +```bash +EXEC_MODE=RAW \ +EXEC_PATH=./update-dns.sh \ + lego --dns exec \ + --domains foo.example.com \ + --email invalid@example.com run +``` + +It will then call the program `./update-dns.sh` like this: + +```bash +./update-dns.sh "present" "foo.example.com." "--" "some-token" "KxAy-J3NwUmg9ZQuM-gP_Mq1nStaYSaP9tYQs5_-YsE.ksT-qywTd8058G-SHHWA3RAN72Pr0yWtPYmmY5UBpQ8" +``` + +## Commands + +{{% notice note %}} +The `--` is because the token MAY start with a `-`, and the called program may try and interpret a `-` as indicating a flag. +In the case of urfave, which is commonly used, +you can use the `--` delimiter to specify the start of positional arguments, and handle such a string safely. +{{% /notice %}} + +### Present + +| Mode | Command | +|---------|----------------------------------------------------| +| default | `myprogram present -- ` | +| `RAW` | `myprogram present -- ` | + +### Cleanup + +| Mode | Command | +|---------|----------------------------------------------------| +| default | `myprogram cleanup -- ` | +| `RAW` | `myprogram cleanup -- ` | + +### Timeout + +The command have to display propagation timeout and polling interval into Stdout. + +The values must be formatted as JSON, and times are in seconds. +Example: `{"timeout": 30, "interval": 5}` + +If an error occurs or if the command is not provided: +the default display propagation timeout and polling interval are used. + +| Mode | Command | +|---------|----------------------------------------------------| +| default | `myprogram timeout` | +| `RAW` | `myprogram timeout` | + +''' diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/exoscale/exoscale.go b/vendor/github.com/go-acme/lego/v3/providers/dns/exoscale/exoscale.go new file mode 100644 index 000000000..34f44f356 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/exoscale/exoscale.go @@ -0,0 +1,184 @@ +// Package exoscale implements a DNS provider for solving the DNS-01 challenge using exoscale DNS. +package exoscale + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "github.com/exoscale/egoscale" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const defaultBaseURL = "https://api.exoscale.com/dns" + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + APISecret string + Endpoint string + HTTPClient *http.Client + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("EXOSCALE_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("EXOSCALE_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("EXOSCALE_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("EXOSCALE_HTTP_TIMEOUT", 0), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *egoscale.Client +} + +// NewDNSProvider Credentials must be passed in the environment variables: +// EXOSCALE_API_KEY, EXOSCALE_API_SECRET, EXOSCALE_ENDPOINT. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("EXOSCALE_API_KEY", "EXOSCALE_API_SECRET") + if err != nil { + return nil, fmt.Errorf("exoscale: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["EXOSCALE_API_KEY"] + config.APISecret = values["EXOSCALE_API_SECRET"] + config.Endpoint = env.GetOrFile("EXOSCALE_ENDPOINT") + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Exoscale. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("the configuration of the DNS provider is nil") + } + + if config.APIKey == "" || config.APISecret == "" { + return nil, fmt.Errorf("exoscale: credentials missing") + } + + if config.Endpoint == "" { + config.Endpoint = defaultBaseURL + } + + client := egoscale.NewClient(config.Endpoint, config.APIKey, config.APISecret) + client.HTTPClient = config.HTTPClient + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + ctx := context.Background() + fqdn, value := dns01.GetRecord(domain, keyAuth) + zone, recordName, err := d.FindZoneAndRecordName(fqdn, domain) + if err != nil { + return err + } + + recordID, err := d.FindExistingRecordID(zone, recordName) + if err != nil { + return err + } + + if recordID == 0 { + record := egoscale.DNSRecord{ + Name: recordName, + TTL: d.config.TTL, + Content: value, + RecordType: "TXT", + } + + _, err := d.client.CreateRecord(ctx, zone, record) + if err != nil { + return errors.New("Error while creating DNS record: " + err.Error()) + } + } else { + record := egoscale.UpdateDNSRecord{ + ID: recordID, + Name: recordName, + TTL: d.config.TTL, + Content: value, + RecordType: "TXT", + } + + _, err := d.client.UpdateRecord(ctx, zone, record) + if err != nil { + return errors.New("Error while updating DNS record: " + err.Error()) + } + } + + return nil +} + +// CleanUp removes the record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + ctx := context.Background() + fqdn, _ := dns01.GetRecord(domain, keyAuth) + zone, recordName, err := d.FindZoneAndRecordName(fqdn, domain) + if err != nil { + return err + } + + recordID, err := d.FindExistingRecordID(zone, recordName) + if err != nil { + return err + } + + if recordID != 0 { + err = d.client.DeleteRecord(ctx, zone, recordID) + if err != nil { + return errors.New("Error while deleting DNS record: " + err.Error()) + } + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// FindExistingRecordID Query Exoscale to find an existing record for this name. +// Returns nil if no record could be found +func (d *DNSProvider) FindExistingRecordID(zone, recordName string) (int64, error) { + ctx := context.Background() + records, err := d.client.GetRecords(ctx, zone) + if err != nil { + return -1, errors.New("Error while retrievening DNS records: " + err.Error()) + } + for _, record := range records { + if record.Name == recordName { + return record.ID, nil + } + } + return 0, nil +} + +// FindZoneAndRecordName Extract DNS zone and DNS entry name +func (d *DNSProvider) FindZoneAndRecordName(fqdn, domain string) (string, string, error) { + zone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return "", "", err + } + zone = dns01.UnFqdn(zone) + name := dns01.UnFqdn(fqdn) + name = name[:len(name)-len("."+zone)] + + return zone, name, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/exoscale/exoscale.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/exoscale/exoscale.toml new file mode 100644 index 000000000..038944608 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/exoscale/exoscale.toml @@ -0,0 +1,22 @@ +Name = "Exoscale" +Description = '''''' +URL = "https://www.exoscale.com/" +Code = "exoscale" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + EXOSCALE_API_KEY = "API key" + EXOSCALE_API_SECRET = "API secret" + EXOSCALE_ENDPOINT = "API endpoint URL" + [Configuration.Additional] + EXOSCALE_POLLING_INTERVAL = "Time between DNS propagation check" + EXOSCALE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + EXOSCALE_TTL = "The TTL of the TXT record used for the DNS challenge" + EXOSCALE_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://community.exoscale.com/documentation/dns/api/" + GoClient = "https://github.com/exoscale/egoscale" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/fastdns/fastdns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/fastdns/fastdns.go new file mode 100644 index 000000000..8dd31b2bc --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/fastdns/fastdns.go @@ -0,0 +1,158 @@ +// Package fastdns implements a DNS provider for solving the DNS-01 challenge using FastDNS. +package fastdns + +import ( + "errors" + "fmt" + "reflect" + "time" + + configdns "github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1" + "github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + edgegrid.Config + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("AKAMAI_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("AKAMAI_POLLING_INTERVAL", dns01.DefaultPollingInterval), + TTL: env.GetOrDefaultInt("AKAMAI_TTL", dns01.DefaultTTL), + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config +} + +// NewDNSProvider uses the supplied environment variables to return a DNSProvider instance: +// AKAMAI_HOST, AKAMAI_CLIENT_TOKEN, AKAMAI_CLIENT_SECRET, AKAMAI_ACCESS_TOKEN +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("AKAMAI_HOST", "AKAMAI_CLIENT_TOKEN", "AKAMAI_CLIENT_SECRET", "AKAMAI_ACCESS_TOKEN") + if err != nil { + return nil, fmt.Errorf("fastdns: %v", err) + } + + config := NewDefaultConfig() + config.Config = edgegrid.Config{ + Host: values["AKAMAI_HOST"], + ClientToken: values["AKAMAI_CLIENT_TOKEN"], + ClientSecret: values["AKAMAI_CLIENT_SECRET"], + AccessToken: values["AKAMAI_ACCESS_TOKEN"], + MaxBody: 131072, + } + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for FastDNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("fastdns: the configuration of the DNS provider is nil") + } + + if config.ClientToken == "" || config.ClientSecret == "" || config.AccessToken == "" || config.Host == "" { + return nil, fmt.Errorf("fastdns: credentials are missing") + } + + return &DNSProvider{config: config}, nil +} + +// Present creates a TXT record to fullfil the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + zoneName, recordName, err := d.findZoneAndRecordName(fqdn, domain) + if err != nil { + return fmt.Errorf("fastdns: %v", err) + } + + configdns.Init(d.config.Config) + + zone, err := configdns.GetZone(zoneName) + if err != nil { + return fmt.Errorf("fastdns: %v", err) + } + + record := configdns.NewTxtRecord() + _ = record.SetField("name", recordName) + _ = record.SetField("ttl", d.config.TTL) + _ = record.SetField("target", value) + _ = record.SetField("active", true) + + for _, r := range zone.Zone.Txt { + if r != nil && reflect.DeepEqual(r.ToMap(), record.ToMap()) { + return nil + } + } + + return d.createRecord(zone, record) +} + +// CleanUp removes the record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + zoneName, recordName, err := d.findZoneAndRecordName(fqdn, domain) + if err != nil { + return fmt.Errorf("fastdns: %v", err) + } + + configdns.Init(d.config.Config) + + zone, err := configdns.GetZone(zoneName) + if err != nil { + return fmt.Errorf("fastdns: %v", err) + } + + var removed bool + for _, r := range zone.Zone.Txt { + if r != nil && r.Name == recordName { + if zone.RemoveRecord(r) != nil { + return fmt.Errorf("fastdns: %v", err) + } + removed = true + } + } + + if removed { + return zone.Save() + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) findZoneAndRecordName(fqdn, domain string) (string, string, error) { + zone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return "", "", err + } + zone = dns01.UnFqdn(zone) + name := dns01.UnFqdn(fqdn) + name = name[:len(name)-len("."+zone)] + + return zone, name, nil +} + +func (d *DNSProvider) createRecord(zone *configdns.Zone, record *configdns.TxtRecord) error { + err := zone.AddRecord(record) + if err != nil { + return err + } + + return zone.Save() +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/fastdns/fastdns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/fastdns/fastdns.toml new file mode 100644 index 000000000..5dbae3ba6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/fastdns/fastdns.toml @@ -0,0 +1,24 @@ +Name = "FastDNS" +Description = '''''' +URL = "https://www.akamai.com/us/en/products/security/fast-dns.jsp" +Code = "fastdns" +Since = "v0.5.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + AKAMAI_HOST = "API host" + AKAMAI_CLIENT_TOKEN = "Client token" + AKAMAI_CLIENT_SECRET = "Client secret" + AKAMAI_ACCESS_TOKEN = "Access token" + [Configuration.Additional] + AKAMAI_POLLING_INTERVAL = "Time between DNS propagation check" + AKAMAI_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + AKAMAI_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://developer.akamai.com/api/web_performance/fast_dns_record_management/v1.html" + GoClient = "https://github.com/akamai/AkamaiOPEN-edgegrid-golang" + + diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/client.go new file mode 100644 index 000000000..901a78947 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/client.go @@ -0,0 +1,316 @@ +package gandi + +import ( + "bytes" + "encoding/xml" + "fmt" + "io" + "io/ioutil" +) + +// types for XML-RPC method calls and parameters + +type param interface { + param() +} + +type paramString struct { + XMLName xml.Name `xml:"param"` + Value string `xml:"value>string"` +} + +type paramInt struct { + XMLName xml.Name `xml:"param"` + Value int `xml:"value>int"` +} + +type structMember interface { + structMember() +} +type structMemberString struct { + Name string `xml:"name"` + Value string `xml:"value>string"` +} +type structMemberInt struct { + Name string `xml:"name"` + Value int `xml:"value>int"` +} +type paramStruct struct { + XMLName xml.Name `xml:"param"` + StructMembers []structMember `xml:"value>struct>member"` +} + +func (p paramString) param() {} +func (p paramInt) param() {} +func (m structMemberString) structMember() {} +func (m structMemberInt) structMember() {} +func (p paramStruct) param() {} + +type methodCall struct { + XMLName xml.Name `xml:"methodCall"` + MethodName string `xml:"methodName"` + Params []param `xml:"params"` +} + +// types for XML-RPC responses + +type response interface { + faultCode() int + faultString() string +} + +type responseFault struct { + FaultCode int `xml:"fault>value>struct>member>value>int"` + FaultString string `xml:"fault>value>struct>member>value>string"` +} + +func (r responseFault) faultCode() int { return r.FaultCode } +func (r responseFault) faultString() string { return r.FaultString } + +type responseStruct struct { + responseFault + StructMembers []struct { + Name string `xml:"name"` + ValueInt int `xml:"value>int"` + } `xml:"params>param>value>struct>member"` +} + +type responseInt struct { + responseFault + Value int `xml:"params>param>value>int"` +} + +type responseBool struct { + responseFault + Value bool `xml:"params>param>value>boolean"` +} + +type rpcError struct { + faultCode int + faultString string +} + +func (e rpcError) Error() string { + return fmt.Sprintf("Gandi DNS: RPC Error: (%d) %s", e.faultCode, e.faultString) +} + +// rpcCall makes an XML-RPC call to Gandi's RPC endpoint by +// marshaling the data given in the call argument to XML and sending +// that via HTTP Post to Gandi. +// The response is then unmarshalled into the resp argument. +func (d *DNSProvider) rpcCall(call *methodCall, resp response) error { + // marshal + b, err := xml.MarshalIndent(call, "", " ") + if err != nil { + return fmt.Errorf("marshal error: %v", err) + } + + // post + b = append([]byte(``+"\n"), b...) + respBody, err := d.httpPost(d.config.BaseURL, "text/xml", bytes.NewReader(b)) + if err != nil { + return err + } + + // unmarshal + err = xml.Unmarshal(respBody, resp) + if err != nil { + return fmt.Errorf("unmarshal error: %v", err) + } + if resp.faultCode() != 0 { + return rpcError{ + faultCode: resp.faultCode(), faultString: resp.faultString()} + } + return nil +} + +// functions to perform API actions + +func (d *DNSProvider) getZoneID(domain string) (int, error) { + resp := &responseStruct{} + err := d.rpcCall(&methodCall{ + MethodName: "domain.info", + Params: []param{ + paramString{Value: d.config.APIKey}, + paramString{Value: domain}, + }, + }, resp) + if err != nil { + return 0, err + } + + var zoneID int + for _, member := range resp.StructMembers { + if member.Name == "zone_id" { + zoneID = member.ValueInt + } + } + + if zoneID == 0 { + return 0, fmt.Errorf("could not determine zone_id for %s", domain) + } + return zoneID, nil +} + +func (d *DNSProvider) cloneZone(zoneID int, name string) (int, error) { + resp := &responseStruct{} + err := d.rpcCall(&methodCall{ + MethodName: "domain.zone.clone", + Params: []param{ + paramString{Value: d.config.APIKey}, + paramInt{Value: zoneID}, + paramInt{Value: 0}, + paramStruct{ + StructMembers: []structMember{ + structMemberString{ + Name: "name", + Value: name, + }}, + }, + }, + }, resp) + if err != nil { + return 0, err + } + + var newZoneID int + for _, member := range resp.StructMembers { + if member.Name == "id" { + newZoneID = member.ValueInt + } + } + + if newZoneID == 0 { + return 0, fmt.Errorf("could not determine cloned zone_id") + } + return newZoneID, nil +} + +func (d *DNSProvider) newZoneVersion(zoneID int) (int, error) { + resp := &responseInt{} + err := d.rpcCall(&methodCall{ + MethodName: "domain.zone.version.new", + Params: []param{ + paramString{Value: d.config.APIKey}, + paramInt{Value: zoneID}, + }, + }, resp) + if err != nil { + return 0, err + } + + if resp.Value == 0 { + return 0, fmt.Errorf("could not create new zone version") + } + return resp.Value, nil +} + +func (d *DNSProvider) addTXTRecord(zoneID int, version int, name string, value string, ttl int) error { + resp := &responseStruct{} + err := d.rpcCall(&methodCall{ + MethodName: "domain.zone.record.add", + Params: []param{ + paramString{Value: d.config.APIKey}, + paramInt{Value: zoneID}, + paramInt{Value: version}, + paramStruct{ + StructMembers: []structMember{ + structMemberString{ + Name: "type", + Value: "TXT", + }, structMemberString{ + Name: "name", + Value: name, + }, structMemberString{ + Name: "value", + Value: value, + }, structMemberInt{ + Name: "ttl", + Value: ttl, + }}, + }, + }, + }, resp) + return err +} + +func (d *DNSProvider) setZoneVersion(zoneID int, version int) error { + resp := &responseBool{} + err := d.rpcCall(&methodCall{ + MethodName: "domain.zone.version.set", + Params: []param{ + paramString{Value: d.config.APIKey}, + paramInt{Value: zoneID}, + paramInt{Value: version}, + }, + }, resp) + if err != nil { + return err + } + + if !resp.Value { + return fmt.Errorf("could not set zone version") + } + return nil +} + +func (d *DNSProvider) setZone(domain string, zoneID int) error { + resp := &responseStruct{} + err := d.rpcCall(&methodCall{ + MethodName: "domain.zone.set", + Params: []param{ + paramString{Value: d.config.APIKey}, + paramString{Value: domain}, + paramInt{Value: zoneID}, + }, + }, resp) + if err != nil { + return err + } + + var respZoneID int + for _, member := range resp.StructMembers { + if member.Name == "zone_id" { + respZoneID = member.ValueInt + } + } + + if respZoneID != zoneID { + return fmt.Errorf("could not set new zone_id for %s", domain) + } + return nil +} + +func (d *DNSProvider) deleteZone(zoneID int) error { + resp := &responseBool{} + err := d.rpcCall(&methodCall{ + MethodName: "domain.zone.delete", + Params: []param{ + paramString{Value: d.config.APIKey}, + paramInt{Value: zoneID}, + }, + }, resp) + if err != nil { + return err + } + + if !resp.Value { + return fmt.Errorf("could not delete zone_id") + } + return nil +} + +func (d *DNSProvider) httpPost(url string, bodyType string, body io.Reader) ([]byte, error) { + resp, err := d.config.HTTPClient.Post(url, bodyType, body) + if err != nil { + return nil, fmt.Errorf("HTTP Post Error: %v", err) + } + defer resp.Body.Close() + + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("HTTP Post Error: %v", err) + } + + return b, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/gandi.go b/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/gandi.go new file mode 100644 index 000000000..589ab55df --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/gandi.go @@ -0,0 +1,214 @@ +// Package gandi implements a DNS provider for solving the DNS-01 challenge using Gandi DNS. +package gandi + +import ( + "errors" + "fmt" + "net/http" + "strings" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Gandi API reference: http://doc.rpc.gandi.net/index.html +// Gandi API domain examples: http://doc.rpc.gandi.net/domain/faq.html + +const ( + // defaultBaseURL Gandi XML-RPC endpoint used by Present and CleanUp + defaultBaseURL = "https://rpc.gandi.net/xmlrpc/" + minTTL = 300 +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("GANDI_TTL", minTTL), + PropagationTimeout: env.GetOrDefaultSecond("GANDI_PROPAGATION_TIMEOUT", 40*time.Minute), + PollingInterval: env.GetOrDefaultSecond("GANDI_POLLING_INTERVAL", 60*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("GANDI_HTTP_TIMEOUT", 60*time.Second), + }, + } +} + +// inProgressInfo contains information about an in-progress challenge +type inProgressInfo struct { + zoneID int // zoneID of gandi zone to restore in CleanUp + newZoneID int // zoneID of temporary gandi zone containing TXT record + authZone string // the domain name registered at gandi with trailing "." +} + +// DNSProvider is an implementation of the +// acme.ChallengeProviderTimeout interface that uses Gandi's XML-RPC +// API to manage TXT records for a domain. +type DNSProvider struct { + inProgressFQDNs map[string]inProgressInfo + inProgressAuthZones map[string]struct{} + inProgressMu sync.Mutex + config *Config + // findZoneByFqdn determines the DNS zone of an fqdn. It is overridden during tests. + findZoneByFqdn func(fqdn string) (string, error) +} + +// NewDNSProvider returns a DNSProvider instance configured for Gandi. +// Credentials must be passed in the environment variable: GANDI_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("GANDI_API_KEY") + if err != nil { + return nil, fmt.Errorf("gandi: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["GANDI_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Gandi. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("gandi: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + return nil, fmt.Errorf("gandi: no API Key given") + } + + if config.BaseURL == "" { + config.BaseURL = defaultBaseURL + } + + return &DNSProvider{ + config: config, + inProgressFQDNs: make(map[string]inProgressInfo), + inProgressAuthZones: make(map[string]struct{}), + findZoneByFqdn: dns01.FindZoneByFqdn, + }, nil +} + +// Present creates a TXT record using the specified parameters. It +// does this by creating and activating a new temporary Gandi DNS +// zone. This new zone contains the TXT record. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + if d.config.TTL < minTTL { + d.config.TTL = minTTL // 300 is gandi minimum value for ttl + } + + // find authZone and Gandi zone_id for fqdn + authZone, err := d.findZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("gandi: findZoneByFqdn failure: %v", err) + } + + zoneID, err := d.getZoneID(authZone) + if err != nil { + return fmt.Errorf("gandi: %v", err) + } + + // determine name of TXT record + if !strings.HasSuffix( + strings.ToLower(fqdn), strings.ToLower("."+authZone)) { + return fmt.Errorf("gandi: unexpected authZone %s for fqdn %s", authZone, fqdn) + } + name := fqdn[:len(fqdn)-len("."+authZone)] + + // acquire lock and check there is not a challenge already in + // progress for this value of authZone + d.inProgressMu.Lock() + defer d.inProgressMu.Unlock() + + if _, ok := d.inProgressAuthZones[authZone]; ok { + return fmt.Errorf("gandi: challenge already in progress for authZone %s", authZone) + } + + // perform API actions to create and activate new gandi zone + // containing the required TXT record + newZoneName := fmt.Sprintf("%s [ACME Challenge %s]", dns01.UnFqdn(authZone), time.Now().Format(time.RFC822Z)) + + newZoneID, err := d.cloneZone(zoneID, newZoneName) + if err != nil { + return err + } + + newZoneVersion, err := d.newZoneVersion(newZoneID) + if err != nil { + return fmt.Errorf("gandi: %v", err) + } + + err = d.addTXTRecord(newZoneID, newZoneVersion, name, value, d.config.TTL) + if err != nil { + return fmt.Errorf("gandi: %v", err) + } + + err = d.setZoneVersion(newZoneID, newZoneVersion) + if err != nil { + return fmt.Errorf("gandi: %v", err) + } + + err = d.setZone(authZone, newZoneID) + if err != nil { + return fmt.Errorf("gandi: %v", err) + } + + // save data necessary for CleanUp + d.inProgressFQDNs[fqdn] = inProgressInfo{ + zoneID: zoneID, + newZoneID: newZoneID, + authZone: authZone, + } + d.inProgressAuthZones[authZone] = struct{}{} + + return nil +} + +// CleanUp removes the TXT record matching the specified +// parameters. It does this by restoring the old Gandi DNS zone and +// removing the temporary one created by Present. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + // acquire lock and retrieve zoneID, newZoneID and authZone + d.inProgressMu.Lock() + defer d.inProgressMu.Unlock() + + if _, ok := d.inProgressFQDNs[fqdn]; !ok { + // if there is no cleanup information then just return + return nil + } + + zoneID := d.inProgressFQDNs[fqdn].zoneID + newZoneID := d.inProgressFQDNs[fqdn].newZoneID + authZone := d.inProgressFQDNs[fqdn].authZone + delete(d.inProgressFQDNs, fqdn) + delete(d.inProgressAuthZones, authZone) + + // perform API actions to restore old gandi zone for authZone + err := d.setZone(authZone, zoneID) + if err != nil { + return fmt.Errorf("gandi: %v", err) + } + + return d.deleteZone(newZoneID) +} + +// Timeout returns the values (40*time.Minute, 60*time.Second) which +// are used by the acme package as timeout and check interval values +// when checking for DNS record propagation with Gandi. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/gandi.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/gandi.toml new file mode 100644 index 000000000..ec866b823 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/gandi/gandi.toml @@ -0,0 +1,19 @@ +Name = "Gandi" +Description = """""" +URL = "https://www.gandi.net" +Code = "gandi" +Since = "v0.3.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + GANDI_API_KEY = "API key" + [Configuration.Additional] + GANDI_POLLING_INTERVAL = "Time between DNS propagation check" + GANDI_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + GANDI_TTL = "The TTL of the TXT record used for the DNS challenge" + GANDI_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "http://doc.rpc.gandi.net/index.html" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/client.go new file mode 100644 index 000000000..40e7bcab1 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/client.go @@ -0,0 +1,199 @@ +package gandiv5 + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/go-acme/lego/v3/log" +) + +const apiKeyHeader = "X-Api-Key" + +// types for JSON responses with only a message +type apiResponse struct { + Message string `json:"message"` + UUID string `json:"uuid,omitempty"` +} + +// Record TXT record representation +type Record struct { + RRSetTTL int `json:"rrset_ttl"` + RRSetValues []string `json:"rrset_values"` + RRSetName string `json:"rrset_name,omitempty"` + RRSetType string `json:"rrset_type,omitempty"` +} + +func (d *DNSProvider) addTXTRecord(domain string, name string, value string, ttl int) error { + // Get exiting values for the TXT records + // Needed to create challenges for both wildcard and base name domains + txtRecord, err := d.getTXTRecord(domain, name) + if err != nil { + return err + } + + values := []string{value} + if len(txtRecord.RRSetValues) > 0 { + values = append(values, txtRecord.RRSetValues...) + } + + target := fmt.Sprintf("domains/%s/records/%s/TXT", domain, name) + + newRecord := &Record{RRSetTTL: ttl, RRSetValues: values} + req, err := d.newRequest(http.MethodPut, target, newRecord) + if err != nil { + return err + } + + message := apiResponse{} + err = d.do(req, &message) + if err != nil { + return fmt.Errorf("unable to create TXT record for domain %s and name %s: %v", domain, name, err) + } + + if len(message.Message) > 0 { + log.Infof("API response: %s", message.Message) + } + + return nil +} + +func (d *DNSProvider) getTXTRecord(domain, name string) (*Record, error) { + target := fmt.Sprintf("domains/%s/records/%s/TXT", domain, name) + + // Get exiting values for the TXT records + // Needed to create challenges for both wildcard and base name domains + req, err := d.newRequest(http.MethodGet, target, nil) + if err != nil { + return nil, err + } + + txtRecord := &Record{} + err = d.do(req, txtRecord) + if err != nil { + return nil, fmt.Errorf("unable to get TXT records for domain %s and name %s: %v", domain, name, err) + } + + return txtRecord, nil +} + +func (d *DNSProvider) deleteTXTRecord(domain string, name string) error { + target := fmt.Sprintf("domains/%s/records/%s/TXT", domain, name) + + req, err := d.newRequest(http.MethodDelete, target, nil) + if err != nil { + return err + } + + message := apiResponse{} + err = d.do(req, &message) + if err != nil { + return fmt.Errorf("unable to delete TXT record for domain %s and name %s: %v", domain, name, err) + } + + if len(message.Message) > 0 { + log.Infof("API response: %s", message.Message) + } + + return nil +} + +func (d *DNSProvider) newRequest(method, resource string, body interface{}) (*http.Request, error) { + u := fmt.Sprintf("%s/%s", d.config.BaseURL, resource) + + if body == nil { + req, err := http.NewRequest(method, u, nil) + if err != nil { + return nil, err + } + + return req, nil + } + + reqBody, err := json.Marshal(body) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, u, bytes.NewBuffer(reqBody)) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + + return req, nil +} + +func (d *DNSProvider) do(req *http.Request, v interface{}) error { + if len(d.config.APIKey) > 0 { + req.Header.Set(apiKeyHeader, d.config.APIKey) + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return err + } + + err = checkResponse(resp) + if err != nil { + return err + } + + if v == nil { + return nil + } + + raw, err := readBody(resp) + if err != nil { + return fmt.Errorf("failed to read body: %v", err) + } + + if len(raw) > 0 { + err = json.Unmarshal(raw, v) + if err != nil { + return fmt.Errorf("unmarshaling error: %v: %s", err, string(raw)) + } + } + + return nil +} + +func checkResponse(resp *http.Response) error { + if resp.StatusCode == 404 && resp.Request.Method == http.MethodGet { + return nil + } + + if resp.StatusCode >= 400 { + data, err := readBody(resp) + if err != nil { + return fmt.Errorf("%d [%s] request failed: %v", resp.StatusCode, http.StatusText(resp.StatusCode), err) + } + + message := &apiResponse{} + err = json.Unmarshal(data, message) + if err != nil { + return fmt.Errorf("%d [%s] request failed: %v: %s", resp.StatusCode, http.StatusText(resp.StatusCode), err, data) + } + return fmt.Errorf("%d [%s] request failed: %s", resp.StatusCode, http.StatusText(resp.StatusCode), message.Message) + } + + return nil +} + +func readBody(resp *http.Response) ([]byte, error) { + if resp.Body == nil { + return nil, fmt.Errorf("response body is nil") + } + + defer resp.Body.Close() + + rawBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return rawBody, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/gandiv5.go b/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/gandiv5.go new file mode 100644 index 000000000..dcb577f6e --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/gandiv5.go @@ -0,0 +1,167 @@ +// Package gandiv5 implements a DNS provider for solving the DNS-01 challenge using Gandi LiveDNS api. +package gandiv5 + +import ( + "errors" + "fmt" + "net/http" + "strings" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Gandi API reference: http://doc.livedns.gandi.net/ + +const ( + // defaultBaseURL endpoint is the Gandi API endpoint used by Present and CleanUp. + defaultBaseURL = "https://dns.api.gandi.net/api/v5" + minTTL = 300 +) + +// inProgressInfo contains information about an in-progress challenge +type inProgressInfo struct { + fieldName string + authZone string +} + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("GANDIV5_TTL", minTTL), + PropagationTimeout: env.GetOrDefaultSecond("GANDIV5_PROPAGATION_TIMEOUT", 20*time.Minute), + PollingInterval: env.GetOrDefaultSecond("GANDIV5_POLLING_INTERVAL", 20*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("GANDIV5_HTTP_TIMEOUT", 10*time.Second), + }, + } +} + +// DNSProvider is an implementation of the +// acme.ChallengeProviderTimeout interface that uses Gandi's LiveDNS +// API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + inProgressFQDNs map[string]inProgressInfo + inProgressMu sync.Mutex + // findZoneByFqdn determines the DNS zone of an fqdn. It is overridden during tests. + findZoneByFqdn func(fqdn string) (string, error) +} + +// NewDNSProvider returns a DNSProvider instance configured for Gandi. +// Credentials must be passed in the environment variable: GANDIV5_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("GANDIV5_API_KEY") + if err != nil { + return nil, fmt.Errorf("gandi: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["GANDIV5_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Gandi. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("gandiv5: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + return nil, fmt.Errorf("gandiv5: no API Key given") + } + + if config.BaseURL == "" { + config.BaseURL = defaultBaseURL + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("gandiv5: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + return &DNSProvider{ + config: config, + inProgressFQDNs: make(map[string]inProgressInfo), + findZoneByFqdn: dns01.FindZoneByFqdn, + }, nil +} + +// Present creates a TXT record using the specified parameters. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + // find authZone + authZone, err := d.findZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("gandiv5: findZoneByFqdn failure: %v", err) + } + + // determine name of TXT record + if !strings.HasSuffix( + strings.ToLower(fqdn), strings.ToLower("."+authZone)) { + return fmt.Errorf("gandiv5: unexpected authZone %s for fqdn %s", authZone, fqdn) + } + name := fqdn[:len(fqdn)-len("."+authZone)] + + // acquire lock and check there is not a challenge already in + // progress for this value of authZone + d.inProgressMu.Lock() + defer d.inProgressMu.Unlock() + + // add TXT record into authZone + err = d.addTXTRecord(dns01.UnFqdn(authZone), name, value, d.config.TTL) + if err != nil { + return err + } + + // save data necessary for CleanUp + d.inProgressFQDNs[fqdn] = inProgressInfo{ + authZone: authZone, + fieldName: name, + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + // acquire lock and retrieve authZone + d.inProgressMu.Lock() + defer d.inProgressMu.Unlock() + if _, ok := d.inProgressFQDNs[fqdn]; !ok { + // if there is no cleanup information then just return + return nil + } + + fieldName := d.inProgressFQDNs[fqdn].fieldName + authZone := d.inProgressFQDNs[fqdn].authZone + delete(d.inProgressFQDNs, fqdn) + + // delete TXT record from authZone + err := d.deleteTXTRecord(dns01.UnFqdn(authZone), fieldName) + if err != nil { + return fmt.Errorf("gandiv5: %v", err) + } + return nil +} + +// Timeout returns the values (20*time.Minute, 20*time.Second) which +// are used by the acme package as timeout and check interval values +// when checking for DNS record propagation with Gandi. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/gandiv5.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/gandiv5.toml new file mode 100644 index 000000000..bd2ffd924 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/gandiv5/gandiv5.toml @@ -0,0 +1,19 @@ +Name = "Gandi Live DNS (v5)" +Description = '''''' +URL = "https://www.gandi.net" +Code = "gandiv5" +Since = "v0.5.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + GANDIV5_API_KEY = "API key" + [Configuration.Additional] + GANDIV5_POLLING_INTERVAL = "Time between DNS propagation check" + GANDIV5_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + GANDIV5_TTL = "The TTL of the TXT record used for the DNS challenge" + GANDIV5_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "http://doc.livedns.gandi.net" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/gcloud/gcloud.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/gcloud/gcloud.toml new file mode 100644 index 000000000..e5b75807f --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/gcloud/gcloud.toml @@ -0,0 +1,22 @@ +Name = "Google Cloud" +Description = '''''' +URL = "https://cloud.google.com" +Code = "gcloud" +Since = "v0.3.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + GCE_PROJECT = "Project name" + 'Application Default Credentials' = "[Documentation](https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application)" + GCE_SERVICE_ACCOUNT_FILE = "Account file path" + GCE_SERVICE_ACCOUNT = "Account" + [Configuration.Additional] + GCE_POLLING_INTERVAL = "Time between DNS propagation check" + GCE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + GCE_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://community.exoscale.com/documentation/dns/api/" + GoClient = "https://github.com/googleapis/google-api-go-client" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/gcloud/googlecloud.go b/vendor/github.com/go-acme/lego/v3/providers/dns/gcloud/googlecloud.go new file mode 100644 index 000000000..bf46dd202 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/gcloud/googlecloud.go @@ -0,0 +1,337 @@ +// Package gcloud implements a DNS provider for solving the DNS-01 challenge using Google Cloud DNS. +package gcloud + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/go-acme/lego/v3/platform/wait" + "golang.org/x/net/context" + "golang.org/x/oauth2/google" + "google.golang.org/api/dns/v1" + "google.golang.org/api/googleapi" + "google.golang.org/api/option" +) + +const ( + changeStatusDone = "done" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Debug bool + Project string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + Debug: env.GetOrDefaultBool("GCE_DEBUG", false), + TTL: env.GetOrDefaultInt("GCE_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("GCE_PROPAGATION_TIMEOUT", 180*time.Second), + PollingInterval: env.GetOrDefaultSecond("GCE_POLLING_INTERVAL", 5*time.Second), + } +} + +// DNSProvider is an implementation of the DNSProvider interface. +type DNSProvider struct { + config *Config + client *dns.Service +} + +// NewDNSProvider returns a DNSProvider instance configured for Google Cloud DNS. +// Project name must be passed in the environment variable: GCE_PROJECT. +// A Service Account can be passed in the environment variable: GCE_SERVICE_ACCOUNT +// or by specifying the keyfile location: GCE_SERVICE_ACCOUNT_FILE +func NewDNSProvider() (*DNSProvider, error) { + // Use a service account file if specified via environment variable. + if saKey := env.GetOrFile("GCE_SERVICE_ACCOUNT"); len(saKey) > 0 { + return NewDNSProviderServiceAccountKey([]byte(saKey)) + } + + // Use default credentials. + project := env.GetOrDefaultString("GCE_PROJECT", "") + return NewDNSProviderCredentials(project) +} + +// NewDNSProviderCredentials uses the supplied credentials +// to return a DNSProvider instance configured for Google Cloud DNS. +func NewDNSProviderCredentials(project string) (*DNSProvider, error) { + if project == "" { + return nil, fmt.Errorf("googlecloud: project name missing") + } + + client, err := google.DefaultClient(context.Background(), dns.NdevClouddnsReadwriteScope) + if err != nil { + return nil, fmt.Errorf("googlecloud: unable to get Google Cloud client: %v", err) + } + + config := NewDefaultConfig() + config.Project = project + config.HTTPClient = client + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderServiceAccountKey uses the supplied service account JSON +// to return a DNSProvider instance configured for Google Cloud DNS. +func NewDNSProviderServiceAccountKey(saKey []byte) (*DNSProvider, error) { + if len(saKey) == 0 { + return nil, fmt.Errorf("googlecloud: Service Account is missing") + } + + // If GCE_PROJECT is non-empty it overrides the project in the service + // account file. + project := env.GetOrDefaultString("GCE_PROJECT", "") + if project == "" { + // read project id from service account file + var datJSON struct { + ProjectID string `json:"project_id"` + } + err := json.Unmarshal(saKey, &datJSON) + if err != nil || datJSON.ProjectID == "" { + return nil, fmt.Errorf("googlecloud: project ID not found in Google Cloud Service Account file") + } + project = datJSON.ProjectID + } + + conf, err := google.JWTConfigFromJSON(saKey, dns.NdevClouddnsReadwriteScope) + if err != nil { + return nil, fmt.Errorf("googlecloud: unable to acquire config: %v", err) + } + client := conf.Client(context.Background()) + + config := NewDefaultConfig() + config.Project = project + config.HTTPClient = client + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderServiceAccount uses the supplied service account JSON file +// to return a DNSProvider instance configured for Google Cloud DNS. +func NewDNSProviderServiceAccount(saFile string) (*DNSProvider, error) { + if saFile == "" { + return nil, fmt.Errorf("googlecloud: Service Account file missing") + } + + saKey, err := ioutil.ReadFile(saFile) + if err != nil { + return nil, fmt.Errorf("googlecloud: unable to read Service Account file: %v", err) + } + + return NewDNSProviderServiceAccountKey(saKey) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Google Cloud DNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("googlecloud: the configuration of the DNS provider is nil") + } + if config.HTTPClient == nil { + return nil, fmt.Errorf("googlecloud: unable to create Google Cloud DNS service: client is nil") + } + + svc, err := dns.NewService(context.Background(), option.WithHTTPClient(config.HTTPClient)) + if err != nil { + return nil, fmt.Errorf("googlecloud: unable to create Google Cloud DNS service: %v", err) + } + + return &DNSProvider{config: config, client: svc}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZone(fqdn) + if err != nil { + return fmt.Errorf("googlecloud: %v", err) + } + + // Look for existing records. + existingRrSet, err := d.findTxtRecords(zone, fqdn) + if err != nil { + return fmt.Errorf("googlecloud: %v", err) + } + + for _, rrSet := range existingRrSet { + var rrd []string + for _, rr := range rrSet.Rrdatas { + data := mustUnquote(rr) + rrd = append(rrd, data) + + if data == value { + log.Printf("skip: the record already exists: %s", value) + return nil + } + } + rrSet.Rrdatas = rrd + } + + // Attempt to delete the existing records before adding the new one. + if len(existingRrSet) > 0 { + if err = d.applyChanges(zone, &dns.Change{Deletions: existingRrSet}); err != nil { + return fmt.Errorf("googlecloud: %v", err) + } + } + + rec := &dns.ResourceRecordSet{ + Name: fqdn, + Rrdatas: []string{value}, + Ttl: int64(d.config.TTL), + Type: "TXT", + } + + // Append existing TXT record data to the new TXT record data + for _, rrSet := range existingRrSet { + for _, rr := range rrSet.Rrdatas { + if rr != value { + rec.Rrdatas = append(rec.Rrdatas, rr) + } + } + } + + change := &dns.Change{ + Additions: []*dns.ResourceRecordSet{rec}, + } + + if err = d.applyChanges(zone, change); err != nil { + return fmt.Errorf("googlecloud: %v", err) + } + + return nil +} + +func (d *DNSProvider) applyChanges(zone string, change *dns.Change) error { + if d.config.Debug { + data, _ := json.Marshal(change) + log.Printf("change (Create): %s", string(data)) + } + + chg, err := d.client.Changes.Create(d.config.Project, zone, change).Do() + if err != nil { + if v, ok := err.(*googleapi.Error); ok { + if v.Code == http.StatusNotFound { + return nil + } + } + + data, _ := json.Marshal(change) + return fmt.Errorf("failed to perform changes [zone %s, change %s]: %v", zone, string(data), err) + } + + if chg.Status == changeStatusDone { + return nil + } + + chgID := chg.Id + + // wait for change to be acknowledged + return wait.For("apply change", 30*time.Second, 3*time.Second, func() (bool, error) { + if d.config.Debug { + data, _ := json.Marshal(change) + log.Printf("change (Get): %s", string(data)) + } + + chg, err = d.client.Changes.Get(d.config.Project, zone, chgID).Do() + if err != nil { + data, _ := json.Marshal(change) + return false, fmt.Errorf("failed to get changes [zone %s, change %s]: %v", zone, string(data), err) + } + + if chg.Status == changeStatusDone { + return true, nil + } + + return false, fmt.Errorf("status: %s", chg.Status) + }) +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZone(fqdn) + if err != nil { + return fmt.Errorf("googlecloud: %v", err) + } + + records, err := d.findTxtRecords(zone, fqdn) + if err != nil { + return fmt.Errorf("googlecloud: %v", err) + } + + if len(records) == 0 { + return nil + } + + _, err = d.client.Changes.Create(d.config.Project, zone, &dns.Change{Deletions: records}).Do() + if err != nil { + return fmt.Errorf("googlecloud: %v", err) + } + return nil +} + +// Timeout customizes the timeout values used by the ACME package for checking +// DNS record validity. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// getHostedZone returns the managed-zone +func (d *DNSProvider) getHostedZone(domain string) (string, error) { + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return "", err + } + + zones, err := d.client.ManagedZones. + List(d.config.Project). + DnsName(authZone). + Do() + if err != nil { + return "", fmt.Errorf("API call failed: %v", err) + } + + if len(zones.ManagedZones) == 0 { + return "", fmt.Errorf("no matching domain found for domain %s", authZone) + } + + for _, z := range zones.ManagedZones { + if z.Visibility == "public" || z.Visibility == "" { + return z.Name, nil + } + } + + return "", fmt.Errorf("no public zone found for domain %s", authZone) +} + +func (d *DNSProvider) findTxtRecords(zone, fqdn string) ([]*dns.ResourceRecordSet, error) { + recs, err := d.client.ResourceRecordSets.List(d.config.Project, zone).Name(fqdn).Type("TXT").Do() + if err != nil { + return nil, err + } + + return recs.Rrsets, nil +} + +func mustUnquote(raw string) string { + clean, err := strconv.Unquote(raw) + if err != nil { + return raw + } + return clean +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/client.go new file mode 100644 index 000000000..a44d3c455 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/client.go @@ -0,0 +1,91 @@ +package glesys + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + + "github.com/go-acme/lego/v3/log" +) + +// types for JSON method calls, parameters, and responses + +type addRecordRequest struct { + DomainName string `json:"domainname"` + Host string `json:"host"` + Type string `json:"type"` + Data string `json:"data"` + TTL int `json:"ttl,omitempty"` +} + +type deleteRecordRequest struct { + RecordID int `json:"recordid"` +} + +type responseStruct struct { + Response struct { + Status struct { + Code int `json:"code"` + } `json:"status"` + Record deleteRecordRequest `json:"record"` + } `json:"response"` +} + +func (d *DNSProvider) addTXTRecord(fqdn string, domain string, name string, value string, ttl int) (int, error) { + response, err := d.sendRequest(http.MethodPost, "addrecord", addRecordRequest{ + DomainName: domain, + Host: name, + Type: "TXT", + Data: value, + TTL: ttl, + }) + + if response != nil && response.Response.Status.Code == http.StatusOK { + log.Infof("[%s]: Successfully created record id %d", fqdn, response.Response.Record.RecordID) + return response.Response.Record.RecordID, nil + } + return 0, err +} + +func (d *DNSProvider) deleteTXTRecord(fqdn string, recordid int) error { + response, err := d.sendRequest(http.MethodPost, "deleterecord", deleteRecordRequest{ + RecordID: recordid, + }) + if response != nil && response.Response.Status.Code == 200 { + log.Infof("[%s]: Successfully deleted record id %d", fqdn, recordid) + } + return err +} + +func (d *DNSProvider) sendRequest(method string, resource string, payload interface{}) (*responseStruct, error) { + url := fmt.Sprintf("%s/%s", defaultBaseURL, resource) + + body, err := json.Marshal(payload) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, url, bytes.NewReader(body)) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + req.SetBasicAuth(d.config.APIUser, d.config.APIKey) + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode >= 400 { + return nil, fmt.Errorf("request failed with HTTP status code %d", resp.StatusCode) + } + + var response responseStruct + err = json.NewDecoder(resp.Body).Decode(&response) + + return &response, err +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/glesys.go b/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/glesys.go new file mode 100644 index 000000000..02c23cc03 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/glesys.go @@ -0,0 +1,146 @@ +// Package glesys implements a DNS provider for solving the DNS-01 challenge using GleSYS api. +package glesys + +import ( + "errors" + "fmt" + "net/http" + "strings" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const ( + // defaultBaseURL is the GleSYS API endpoint used by Present and CleanUp. + defaultBaseURL = "https://api.glesys.com/domain" + minTTL = 60 +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIUser string + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("GLESYS_TTL", minTTL), + PropagationTimeout: env.GetOrDefaultSecond("GLESYS_PROPAGATION_TIMEOUT", 20*time.Minute), + PollingInterval: env.GetOrDefaultSecond("GLESYS_POLLING_INTERVAL", 20*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("GLESYS_HTTP_TIMEOUT", 10*time.Second), + }, + } +} + +// DNSProvider is an implementation of the +// acme.ChallengeProviderTimeout interface that uses GleSYS +// API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + activeRecords map[string]int + inProgressMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance configured for GleSYS. +// Credentials must be passed in the environment variables: +// GLESYS_API_USER and GLESYS_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("GLESYS_API_USER", "GLESYS_API_KEY") + if err != nil { + return nil, fmt.Errorf("glesys: %v", err) + } + + config := NewDefaultConfig() + config.APIUser = values["GLESYS_API_USER"] + config.APIKey = values["GLESYS_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for GleSYS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("glesys: the configuration of the DNS provider is nil") + } + + if config.APIUser == "" || config.APIKey == "" { + return nil, fmt.Errorf("glesys: incomplete credentials provided") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("glesys: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + return &DNSProvider{ + config: config, + activeRecords: make(map[string]int), + }, nil +} + +// Present creates a TXT record using the specified parameters. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + // find authZone + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("glesys: findZoneByFqdn failure: %v", err) + } + + // determine name of TXT record + if !strings.HasSuffix( + strings.ToLower(fqdn), strings.ToLower("."+authZone)) { + return fmt.Errorf("glesys: unexpected authZone %s for fqdn %s", authZone, fqdn) + } + name := fqdn[:len(fqdn)-len("."+authZone)] + + // acquire lock and check there is not a challenge already in + // progress for this value of authZone + d.inProgressMu.Lock() + defer d.inProgressMu.Unlock() + + // add TXT record into authZone + recordID, err := d.addTXTRecord(domain, dns01.UnFqdn(authZone), name, value, d.config.TTL) + if err != nil { + return err + } + + // save data necessary for CleanUp + d.activeRecords[fqdn] = recordID + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + // acquire lock and retrieve authZone + d.inProgressMu.Lock() + defer d.inProgressMu.Unlock() + if _, ok := d.activeRecords[fqdn]; !ok { + // if there is no cleanup information then just return + return nil + } + + recordID := d.activeRecords[fqdn] + delete(d.activeRecords, fqdn) + + // delete TXT record from authZone + return d.deleteTXTRecord(domain, recordID) +} + +// Timeout returns the values (20*time.Minute, 20*time.Second) which +// are used by the acme package as timeout and check interval values +// when checking for DNS record propagation with GleSYS. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/glesys.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/glesys.toml new file mode 100644 index 000000000..c65c32f43 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/glesys/glesys.toml @@ -0,0 +1,20 @@ +Name = "Glesys" +Description = '''''' +URL = "https://glesys.com/" +Code = "glesys" +Since = "v0.5.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + GLESYS_API_USER = "API user" + GLESYS_API_KEY = "API key" + [Configuration.Additional] + GLESYS_POLLING_INTERVAL = "Time between DNS propagation check" + GLESYS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + GLESYS_TTL = "The TTL of the TXT record used for the DNS challenge" + GLESYS_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://github.com/GleSYS/API/wiki/API-Documentation" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/client.go new file mode 100644 index 000000000..212b8e69c --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/client.go @@ -0,0 +1,53 @@ +package godaddy + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" +) + +// DNSRecord a DNS record +type DNSRecord struct { + Type string `json:"type"` + Name string `json:"name"` + Data string `json:"data"` + Priority int `json:"priority,omitempty"` + TTL int `json:"ttl,omitempty"` +} + +func (d *DNSProvider) updateRecords(records []DNSRecord, domainZone string, recordName string) error { + body, err := json.Marshal(records) + if err != nil { + return err + } + + var resp *http.Response + resp, err = d.makeRequest(http.MethodPut, fmt.Sprintf("/v1/domains/%s/records/TXT/%s", domainZone, recordName), bytes.NewReader(body)) + if err != nil { + return err + } + + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + bodyBytes, _ := ioutil.ReadAll(resp.Body) + return fmt.Errorf("could not create record %v; Status: %v; Body: %s", string(body), resp.StatusCode, string(bodyBytes)) + } + return nil +} + +func (d *DNSProvider) makeRequest(method, uri string, body io.Reader) (*http.Response, error) { + req, err := http.NewRequest(method, fmt.Sprintf("%s%s", defaultBaseURL, uri), body) + if err != nil { + return nil, err + } + + req.Header.Set("Accept", "application/json") + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", fmt.Sprintf("sso-key %s:%s", d.config.APIKey, d.config.APISecret)) + + return d.config.HTTPClient.Do(req) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/godaddy.go b/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/godaddy.go new file mode 100644 index 000000000..e14888a1a --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/godaddy.go @@ -0,0 +1,151 @@ +// Package godaddy implements a DNS provider for solving the DNS-01 challenge using godaddy DNS. +package godaddy + +import ( + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const ( + // defaultBaseURL represents the API endpoint to call. + defaultBaseURL = "https://api.godaddy.com" + minTTL = 600 +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + APISecret string + PropagationTimeout time.Duration + PollingInterval time.Duration + SequenceInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("GODADDY_TTL", minTTL), + PropagationTimeout: env.GetOrDefaultSecond("GODADDY_PROPAGATION_TIMEOUT", 120*time.Second), + PollingInterval: env.GetOrDefaultSecond("GODADDY_POLLING_INTERVAL", 2*time.Second), + SequenceInterval: env.GetOrDefaultSecond("GODADDY_SEQUENCE_INTERVAL", dns01.DefaultPropagationTimeout), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("GODADDY_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for godaddy. +// Credentials must be passed in the environment variables: +// GODADDY_API_KEY and GODADDY_API_SECRET. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("GODADDY_API_KEY", "GODADDY_API_SECRET") + if err != nil { + return nil, fmt.Errorf("godaddy: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["GODADDY_API_KEY"] + config.APISecret = values["GODADDY_API_SECRET"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for godaddy. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("godaddy: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" || config.APISecret == "" { + return nil, fmt.Errorf("godaddy: credentials missing") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("godaddy: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS +// propagation. Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + domainZone, err := d.getZone(fqdn) + if err != nil { + return err + } + + recordName := d.extractRecordName(fqdn, domainZone) + rec := []DNSRecord{ + { + Type: "TXT", + Name: recordName, + Data: value, + TTL: d.config.TTL, + }, + } + + return d.updateRecords(rec, domainZone, recordName) +} + +// CleanUp sets null value in the TXT DNS record as GoDaddy has no proper DELETE record method +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + domainZone, err := d.getZone(fqdn) + if err != nil { + return err + } + + recordName := d.extractRecordName(fqdn, domainZone) + rec := []DNSRecord{ + { + Type: "TXT", + Name: recordName, + Data: "null", + }, + } + + return d.updateRecords(rec, domainZone, recordName) +} + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProvider) Sequential() time.Duration { + return d.config.SequenceInterval +} + +func (d *DNSProvider) extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} + +func (d *DNSProvider) getZone(fqdn string) (string, error) { + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return "", err + } + + return dns01.UnFqdn(authZone), nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/godaddy.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/godaddy.toml new file mode 100644 index 000000000..eb4acb6e8 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/godaddy/godaddy.toml @@ -0,0 +1,19 @@ +Name = "Go Daddy" +Description = '''''' +URL = "https://godaddy.com" +Code = "godaddy" +Since = "v0.5.0" + +[Configuration] + [Configuration.Credentials] + GODADDY_API_KEY = "API key" + GODADDY_API_SECRET = "API secret" + [Configuration.Additional] + GODADDY_POLLING_INTERVAL = "Time between DNS propagation check" + GODADDY_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + GODADDY_TTL = "The TTL of the TXT record used for the DNS challenge" + GODADDY_HTTP_TIMEOUT = "API request timeout" + GODADDY_SEQUENCE_INTERVAL = "Interval between iteration" + +[Links] + API = "https://developer.godaddy.com/doc/endpoint/domains" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/client.go new file mode 100644 index 000000000..912b40ea5 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/client.go @@ -0,0 +1,127 @@ +package hostingde + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "time" + + "github.com/cenkalti/backoff/v3" +) + +const defaultBaseURL = "https://secure.hosting.de/api/dns/v1/json" + +// https://www.hosting.de/api/?json#list-zoneconfigs +func (d *DNSProvider) listZoneConfigs(findRequest ZoneConfigsFindRequest) (*ZoneConfigsFindResponse, error) { + uri := defaultBaseURL + "/zoneConfigsFind" + + findResponse := &ZoneConfigsFindResponse{} + + rawResp, err := d.post(uri, findRequest, findResponse) + if err != nil { + return nil, err + } + + if len(findResponse.Response.Data) == 0 { + return nil, fmt.Errorf("%v: %s", err, toUnreadableBodyMessage(uri, rawResp)) + } + + if findResponse.Status != "success" && findResponse.Status != "pending" { + return findResponse, errors.New(toUnreadableBodyMessage(uri, rawResp)) + } + + return findResponse, nil +} + +// https://www.hosting.de/api/?json#updating-zones +func (d *DNSProvider) updateZone(updateRequest ZoneUpdateRequest) (*ZoneUpdateResponse, error) { + uri := defaultBaseURL + "/zoneUpdate" + + // but we'll need the ID later to delete the record + updateResponse := &ZoneUpdateResponse{} + + rawResp, err := d.post(uri, updateRequest, updateResponse) + if err != nil { + return nil, err + } + + if updateResponse.Status != "success" && updateResponse.Status != "pending" { + return nil, errors.New(toUnreadableBodyMessage(uri, rawResp)) + } + + return updateResponse, nil +} + +func (d *DNSProvider) getZone(findRequest ZoneConfigsFindRequest) (*ZoneConfig, error) { + ctx, cancel := context.WithCancel(context.Background()) + + var zoneConfig *ZoneConfig + + operation := func() error { + findResponse, err := d.listZoneConfigs(findRequest) + if err != nil { + cancel() + return err + } + + if findResponse.Response.Data[0].Status != "active" { + return fmt.Errorf("unexpected status: %q", findResponse.Response.Data[0].Status) + } + + zoneConfig = &findResponse.Response.Data[0] + + return nil + } + + bo := backoff.NewExponentialBackOff() + bo.InitialInterval = 3 * time.Second + bo.MaxInterval = 10 * bo.InitialInterval + bo.MaxElapsedTime = 100 * bo.InitialInterval + + // retry in case the zone was edited recently and is not yet active + err := backoff.Retry(operation, backoff.WithContext(bo, ctx)) + if err != nil { + return nil, err + } + + return zoneConfig, nil +} + +func (d *DNSProvider) post(uri string, request interface{}, response interface{}) ([]byte, error) { + body, err := json.Marshal(request) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, uri, bytes.NewReader(body)) + if err != nil { + return nil, err + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return nil, fmt.Errorf("error querying API: %v", err) + } + + defer resp.Body.Close() + + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, errors.New(toUnreadableBodyMessage(uri, content)) + } + + err = json.Unmarshal(content, response) + if err != nil { + return nil, fmt.Errorf("%v: %s", err, toUnreadableBodyMessage(uri, content)) + } + + return content, nil +} + +func toUnreadableBodyMessage(uri string, rawBody []byte) string { + return fmt.Sprintf("the request %s sent a response with a body which is an invalid format: %q", uri, string(rawBody)) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/hostingde.go b/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/hostingde.go new file mode 100644 index 000000000..554fdcb60 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/hostingde.go @@ -0,0 +1,183 @@ +// Package hostingde implements a DNS provider for solving the DNS-01 challenge using hosting.de. +package hostingde + +import ( + "errors" + "fmt" + "net/http" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + ZoneName string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("HOSTINGDE_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("HOSTINGDE_PROPAGATION_TIMEOUT", 2*time.Minute), + PollingInterval: env.GetOrDefaultSecond("HOSTINGDE_POLLING_INTERVAL", 2*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("HOSTINGDE_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config + recordIDs map[string]string + recordIDsMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance configured for hosting.de. +// Credentials must be passed in the environment variables: +// HOSTINGDE_ZONE_NAME and HOSTINGDE_API_KEY +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("HOSTINGDE_API_KEY", "HOSTINGDE_ZONE_NAME") + if err != nil { + return nil, fmt.Errorf("hostingde: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["HOSTINGDE_API_KEY"] + config.ZoneName = values["HOSTINGDE_ZONE_NAME"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for hosting.de. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("hostingde: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + return nil, errors.New("hostingde: API key missing") + } + + if config.ZoneName == "" { + return nil, errors.New("hostingde: Zone Name missing") + } + + return &DNSProvider{ + config: config, + recordIDs: make(map[string]string), + }, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + // get the ZoneConfig for that domain + zonesFind := ZoneConfigsFindRequest{ + Filter: Filter{ + Field: "zoneName", + Value: d.config.ZoneName, + }, + Limit: 1, + Page: 1, + } + zonesFind.AuthToken = d.config.APIKey + + zoneConfig, err := d.getZone(zonesFind) + if err != nil { + return fmt.Errorf("hostingde: %v", err) + } + zoneConfig.Name = d.config.ZoneName + + rec := []DNSRecord{{ + Type: "TXT", + Name: dns01.UnFqdn(fqdn), + Content: value, + TTL: d.config.TTL, + }} + + req := ZoneUpdateRequest{ + ZoneConfig: *zoneConfig, + RecordsToAdd: rec, + } + req.AuthToken = d.config.APIKey + + resp, err := d.updateZone(req) + if err != nil { + return fmt.Errorf("hostingde: %v", err) + } + + for _, record := range resp.Response.Records { + if record.Name == dns01.UnFqdn(fqdn) && record.Content == fmt.Sprintf(`"%s"`, value) { + d.recordIDsMu.Lock() + d.recordIDs[fqdn] = record.ID + d.recordIDsMu.Unlock() + } + } + + if d.recordIDs[fqdn] == "" { + return fmt.Errorf("hostingde: error getting ID of just created record, for domain %s", domain) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + rec := []DNSRecord{{ + Type: "TXT", + Name: dns01.UnFqdn(fqdn), + Content: `"` + value + `"`, + }} + + // get the ZoneConfig for that domain + zonesFind := ZoneConfigsFindRequest{ + Filter: Filter{ + Field: "zoneName", + Value: d.config.ZoneName, + }, + Limit: 1, + Page: 1, + } + zonesFind.AuthToken = d.config.APIKey + + zoneConfig, err := d.getZone(zonesFind) + if err != nil { + return fmt.Errorf("hostingde: %v", err) + } + zoneConfig.Name = d.config.ZoneName + + req := ZoneUpdateRequest{ + ZoneConfig: *zoneConfig, + RecordsToDelete: rec, + } + req.AuthToken = d.config.APIKey + + // Delete record ID from map + d.recordIDsMu.Lock() + delete(d.recordIDs, fqdn) + d.recordIDsMu.Unlock() + + _, err = d.updateZone(req) + if err != nil { + return fmt.Errorf("hostingde: %v", err) + } + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/hostingde.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/hostingde.toml new file mode 100644 index 000000000..f19c4941c --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/hostingde.toml @@ -0,0 +1,20 @@ +Name = "Hosting.de" +Description = '''''' +URL = "https://www.hosting.de/" +Code = "hostingde" +Since = "v1.1.0" + +[Configuration] + [Configuration.Credentials] + HOSTINGDE_API_KEY = "API key" + HOSTINGDE_ZONE_NAME = "Zone name in ACE format" + [Configuration.Additional] + HOSTINGDE_POLLING_INTERVAL = "Time between DNS propagation check" + HOSTINGDE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + HOSTINGDE_TTL = "The TTL of the TXT record used for the DNS challenge" + HOSTINGDE_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.hosting.de/api/#dns" + + diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/model.go b/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/model.go new file mode 100644 index 000000000..9c67784b6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/hostingde/model.go @@ -0,0 +1,139 @@ +package hostingde + +import "encoding/json" + +// APIError represents an error in an API response. +// https://www.hosting.de/api/?json#warnings-and-errors +type APIError struct { + Code int `json:"code"` + ContextObject string `json:"contextObject"` + ContextPath string `json:"contextPath"` + Details []string `json:"details"` + Text string `json:"text"` + Value string `json:"value"` +} + +// Filter is used to filter FindRequests to the API. +// https://www.hosting.de/api/?json#filter-object +type Filter struct { + Field string `json:"field"` + Value string `json:"value"` +} + +// Sort is used to sort FindRequests from the API. +// https://www.hosting.de/api/?json#filtering-and-sorting +type Sort struct { + Field string `json:"zoneName"` + Order string `json:"order"` +} + +// Metadata represents the metadata in an API response. +// https://www.hosting.de/api/?json#metadata-object +type Metadata struct { + ClientTransactionID string `json:"clientTransactionId"` + ServerTransactionID string `json:"serverTransactionId"` +} + +// ZoneConfig The ZoneConfig object defines a zone. +// https://www.hosting.de/api/?json#the-zoneconfig-object +type ZoneConfig struct { + ID string `json:"id"` + AccountID string `json:"accountId"` + Status string `json:"status"` + Name string `json:"name"` + NameUnicode string `json:"nameUnicode"` + MasterIP string `json:"masterIp"` + Type string `json:"type"` + EMailAddress string `json:"emailAddress"` + ZoneTransferWhitelist []string `json:"zoneTransferWhitelist"` + LastChangeDate string `json:"lastChangeDate"` + DNSServerGroupID string `json:"dnsServerGroupId"` + DNSSecMode string `json:"dnsSecMode"` + SOAValues *SOAValues `json:"soaValues,omitempty"` + TemplateValues json.RawMessage `json:"templateValues,omitempty"` +} + +// SOAValues The SOA values object contains the time (seconds) used in a zone’s SOA record. +// https://www.hosting.de/api/?json#the-soa-values-object +type SOAValues struct { + Refresh int `json:"refresh"` + Retry int `json:"retry"` + Expire int `json:"expire"` + TTL int `json:"ttl"` + NegativeTTL int `json:"negativeTtl"` +} + +// DNSRecord The DNS Record object is part of a zone. It is used to manage DNS resource records. +// https://www.hosting.de/api/?json#the-record-object +type DNSRecord struct { + ID string `json:"id,omitempty"` + ZoneID string `json:"zoneId,omitempty"` + RecordTemplateID string `json:"recordTemplateId,omitempty"` + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + Content string `json:"content,omitempty"` + TTL int `json:"ttl,omitempty"` + Priority int `json:"priority,omitempty"` + LastChangeDate string `json:"lastChangeDate,omitempty"` +} + +// Zone The Zone Object. +// https://www.hosting.de/api/?json#the-zone-object +type Zone struct { + Records []DNSRecord `json:"records"` + ZoneConfig ZoneConfig `json:"zoneConfig"` +} + +// ZoneUpdateRequest represents a API ZoneUpdate request. +// https://www.hosting.de/api/?json#updating-zones +type ZoneUpdateRequest struct { + BaseRequest + ZoneConfig `json:"zoneConfig"` + RecordsToAdd []DNSRecord `json:"recordsToAdd"` + RecordsToDelete []DNSRecord `json:"recordsToDelete"` +} + +// ZoneUpdateResponse represents a response from the API. +// https://www.hosting.de/api/?json#updating-zones +type ZoneUpdateResponse struct { + BaseResponse + Response Zone `json:"response"` +} + +// ZoneConfigsFindRequest represents a API ZonesFind request. +// https://www.hosting.de/api/?json#list-zoneconfigs +type ZoneConfigsFindRequest struct { + BaseRequest + Filter Filter `json:"filter"` + Limit int `json:"limit"` + Page int `json:"page"` + Sort *Sort `json:"sort,omitempty"` +} + +// ZoneConfigsFindResponse represents the API response for ZoneConfigsFind. +// https://www.hosting.de/api/?json#list-zoneconfigs +type ZoneConfigsFindResponse struct { + BaseResponse + Response struct { + Limit int `json:"limit"` + Page int `json:"page"` + TotalEntries int `json:"totalEntries"` + TotalPages int `json:"totalPages"` + Type string `json:"type"` + Data []ZoneConfig `json:"data"` + } `json:"response"` +} + +// BaseResponse Common response struct. +// https://www.hosting.de/api/?json#responses +type BaseResponse struct { + Errors []APIError `json:"errors"` + Metadata Metadata `json:"metadata"` + Warnings []string `json:"warnings"` + Status string `json:"status"` +} + +// BaseRequest Common request struct. +type BaseRequest struct { + AuthToken string `json:"authToken"` +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/httpreq/httpreq.go b/vendor/github.com/go-acme/lego/v3/providers/dns/httpreq/httpreq.go new file mode 100644 index 000000000..336342563 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/httpreq/httpreq.go @@ -0,0 +1,195 @@ +// Package httpreq implements a DNS provider for solving the DNS-01 challenge through a HTTP server. +package httpreq + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "path" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +type message struct { + FQDN string `json:"fqdn"` + Value string `json:"value"` +} + +type messageRaw struct { + Domain string `json:"domain"` + Token string `json:"token"` + KeyAuth string `json:"keyAuth"` +} + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Endpoint *url.URL + Mode string + Username string + Password string + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("HTTPREQ_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("HTTPREQ_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("HTTPREQ_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider describes a provider for acme-proxy +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("HTTPREQ_ENDPOINT") + if err != nil { + return nil, fmt.Errorf("httpreq: %v", err) + } + + endpoint, err := url.Parse(values["HTTPREQ_ENDPOINT"]) + if err != nil { + return nil, fmt.Errorf("httpreq: %v", err) + } + + config := NewDefaultConfig() + config.Mode = os.Getenv("HTTPREQ_MODE") + config.Username = os.Getenv("HTTPREQ_USERNAME") + config.Password = os.Getenv("HTTPREQ_PASSWORD") + config.Endpoint = endpoint + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider . +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("httpreq: the configuration of the DNS provider is nil") + } + + if config.Endpoint == nil { + return nil, errors.New("httpreq: the endpoint is missing") + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + if d.config.Mode == "RAW" { + msg := &messageRaw{ + Domain: domain, + Token: token, + KeyAuth: keyAuth, + } + + err := d.doPost("/present", msg) + if err != nil { + return fmt.Errorf("httpreq: %v", err) + } + return nil + } + + fqdn, value := dns01.GetRecord(domain, keyAuth) + msg := &message{ + FQDN: fqdn, + Value: value, + } + + err := d.doPost("/present", msg) + if err != nil { + return fmt.Errorf("httpreq: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + if d.config.Mode == "RAW" { + msg := &messageRaw{ + Domain: domain, + Token: token, + KeyAuth: keyAuth, + } + + err := d.doPost("/cleanup", msg) + if err != nil { + return fmt.Errorf("httpreq: %v", err) + } + return nil + } + + fqdn, value := dns01.GetRecord(domain, keyAuth) + msg := &message{ + FQDN: fqdn, + Value: value, + } + + err := d.doPost("/cleanup", msg) + if err != nil { + return fmt.Errorf("httpreq: %v", err) + } + return nil +} + +func (d *DNSProvider) doPost(uri string, msg interface{}) error { + reqBody := &bytes.Buffer{} + err := json.NewEncoder(reqBody).Encode(msg) + if err != nil { + return err + } + + newURI := path.Join(d.config.Endpoint.EscapedPath(), uri) + endpoint, err := d.config.Endpoint.Parse(newURI) + if err != nil { + return err + } + + req, err := http.NewRequest(http.MethodPost, endpoint.String(), reqBody) + if err != nil { + return err + } + + req.Header.Set("Content-Type", "application/json") + + if len(d.config.Username) > 0 && len(d.config.Password) > 0 { + req.SetBasicAuth(d.config.Username, d.config.Password) + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode >= http.StatusBadRequest { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("%d: failed to read response body: %v", resp.StatusCode, err) + } + + return fmt.Errorf("%d: request failed: %v", resp.StatusCode, string(body)) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/httpreq/httpreq.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/httpreq/httpreq.toml new file mode 100644 index 000000000..64750678e --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/httpreq/httpreq.toml @@ -0,0 +1,61 @@ +Name = "HTTP request" +Description = '''''' +URL = "/dns/httpreq/" +Code = "httpreq" +Since = "v2.0.0" + +Example = ''' +HTTPREQ_ENDPOINT=http://my.server.com:9090 \ +lego --dns httpreq --domains my.domain.com --email my@email.com run +''' + +Additional = ''' +## Description + +The server must provide: + +- `POST` `/present` +- `POST` `/cleanup` + +The URL of the server must be define by `HTTPREQ_ENDPOINT`. + +### Mode + +There are 2 modes (`HTTPREQ_MODE`): + +- default mode: +```json +{ + "fqdn": "_acme-challenge.domain.", + "value": "LHDhK3oGRvkiefQnx7OOczTY5Tic_xZ6HcMOc_gmtoM" +} +``` + +- `RAW` +```json +{ + "domain": "domain", + "token": "token", + "keyAuth": "key" +} +``` + +### Authentication + +Basic authentication (optional) can be set with some environment variables: + +- `HTTPREQ_USERNAME` and `HTTPREQ_PASSWORD` +- both values must be set, otherwise basic authentication is not defined. + +''' + +[Configuration] + [Configuration.Credentials] + HTTPREQ_MODE = "`RAW`, none" + HTTPREQ_ENDPOINT = "The URL of the server" + [Configuration.Additional] + HTTPREQ_USERNAME = "Basic authentication username" + HTTPREQ_PASSWORD = "Basic authentication password" + HTTPREQ_POLLING_INTERVAL = "Time between DNS propagation check" + HTTPREQ_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + HTTPREQ_HTTP_TIMEOUT = "API request timeout" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/iij/iij.go b/vendor/github.com/go-acme/lego/v3/providers/dns/iij/iij.go new file mode 100644 index 000000000..49a168716 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/iij/iij.go @@ -0,0 +1,239 @@ +// Package iij implements a DNS provider for solving the DNS-01 challenge using IIJ DNS. +package iij + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/iij/doapi" + "github.com/iij/doapi/protocol" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + AccessKey string + SecretKey string + DoServiceCode string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("IIJ_TTL", 300), + PropagationTimeout: env.GetOrDefaultSecond("IIJ_PROPAGATION_TIMEOUT", 2*time.Minute), + PollingInterval: env.GetOrDefaultSecond("IIJ_POLLING_INTERVAL", 4*time.Second), + } +} + +// DNSProvider implements the acme.ChallengeProvider interface +type DNSProvider struct { + api *doapi.API + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for IIJ DO +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("IIJ_API_ACCESS_KEY", "IIJ_API_SECRET_KEY", "IIJ_DO_SERVICE_CODE") + if err != nil { + return nil, fmt.Errorf("iij: %v", err) + } + + config := NewDefaultConfig() + config.AccessKey = values["IIJ_API_ACCESS_KEY"] + config.SecretKey = values["IIJ_API_SECRET_KEY"] + config.DoServiceCode = values["IIJ_DO_SERVICE_CODE"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig takes a given config +// and returns a custom configured DNSProvider instance +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config.SecretKey == "" || config.AccessKey == "" || config.DoServiceCode == "" { + return nil, fmt.Errorf("iij: credentials missing") + } + + return &DNSProvider{ + api: doapi.NewAPI(config.AccessKey, config.SecretKey), + config: config, + }, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + _, value := dns01.GetRecord(domain, keyAuth) + + err := d.addTxtRecord(domain, value) + if err != nil { + return fmt.Errorf("iij: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + _, value := dns01.GetRecord(domain, keyAuth) + + err := d.deleteTxtRecord(domain, value) + if err != nil { + return fmt.Errorf("iij: %v", err) + } + return nil +} + +func (d *DNSProvider) addTxtRecord(domain, value string) error { + zones, err := d.listZones() + if err != nil { + return err + } + + owner, zone, err := splitDomain(domain, zones) + if err != nil { + return err + } + + request := protocol.RecordAdd{ + DoServiceCode: d.config.DoServiceCode, + ZoneName: zone, + Owner: owner, + TTL: strconv.Itoa(d.config.TTL), + RecordType: "TXT", + RData: value, + } + + response := &protocol.RecordAddResponse{} + + if err := doapi.Call(*d.api, request, response); err != nil { + return err + } + + return d.commit() +} + +func (d *DNSProvider) deleteTxtRecord(domain, value string) error { + zones, err := d.listZones() + if err != nil { + return err + } + + owner, zone, err := splitDomain(domain, zones) + if err != nil { + return err + } + + id, err := d.findTxtRecord(owner, zone, value) + if err != nil { + return err + } + + request := protocol.RecordDelete{ + DoServiceCode: d.config.DoServiceCode, + ZoneName: zone, + RecordID: id, + } + + response := &protocol.RecordDeleteResponse{} + + if err := doapi.Call(*d.api, request, response); err != nil { + return err + } + + return d.commit() +} + +func (d *DNSProvider) commit() error { + request := protocol.Commit{ + DoServiceCode: d.config.DoServiceCode, + } + + response := &protocol.CommitResponse{} + + return doapi.Call(*d.api, request, response) +} + +func (d *DNSProvider) findTxtRecord(owner, zone, value string) (string, error) { + request := protocol.RecordListGet{ + DoServiceCode: d.config.DoServiceCode, + ZoneName: zone, + } + + response := &protocol.RecordListGetResponse{} + + if err := doapi.Call(*d.api, request, response); err != nil { + return "", err + } + + var id string + + for _, record := range response.RecordList { + if record.Owner == owner && record.RecordType == "TXT" && record.RData == "\""+value+"\"" { + id = record.Id + } + } + + if id == "" { + return "", fmt.Errorf("%s record in %s not found", owner, zone) + } + + return id, nil +} + +func (d *DNSProvider) listZones() ([]string, error) { + request := protocol.ZoneListGet{ + DoServiceCode: d.config.DoServiceCode, + } + + response := &protocol.ZoneListGetResponse{} + + if err := doapi.Call(*d.api, request, response); err != nil { + return nil, err + } + + return response.ZoneList, nil +} + +func splitDomain(domain string, zones []string) (string, string, error) { + parts := strings.Split(strings.Trim(domain, "."), ".") + + var owner string + var zone string + + for i := 0; i < len(parts)-1; i++ { + zone = strings.Join(parts[i:], ".") + if zoneContains(zone, zones) { + baseOwner := strings.Join(parts[0:i], ".") + if len(baseOwner) > 0 { + baseOwner = "." + baseOwner + } + owner = "_acme-challenge" + baseOwner + break + } + } + + if len(owner) == 0 { + return "", "", fmt.Errorf("%s not found", domain) + } + + return owner, zone, nil +} + +func zoneContains(zone string, zones []string) bool { + for _, z := range zones { + if zone == z { + return true + } + } + return false +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/iij/iij.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/iij/iij.toml new file mode 100644 index 000000000..5232af0e1 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/iij/iij.toml @@ -0,0 +1,21 @@ +Name = "Internet Initiative Japan" +Description = '''''' +URL = "https://www.iij.ad.jp/en/" +Code = "iij" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + IIJ_API_ACCESS_KEY = "API access key" + IIJ_API_SECRET_KEY = "API secret key" + IIJ_DO_SERVICE_CODE = "DO service code" + [Configuration.Additional] + IIJ_POLLING_INTERVAL = "Time between DNS propagation check" + IIJ_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + IIJ_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "http://manual.iij.jp/p2/pubapi/http://manual.iij.jp/p2/pubapi/" + GoClient = "https://github.com/iij/doapi" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/inwx/inwx.go b/vendor/github.com/go-acme/lego/v3/providers/dns/inwx/inwx.go new file mode 100644 index 000000000..2ca70d070 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/inwx/inwx.go @@ -0,0 +1,166 @@ +// Package inwx implements a DNS provider for solving the DNS-01 challenge using inwx dom robot +package inwx + +import ( + "errors" + "fmt" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/nrdcg/goinwx" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Username string + Password string + Sandbox bool + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("INWX_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("INWX_POLLING_INTERVAL", dns01.DefaultPollingInterval), + TTL: env.GetOrDefaultInt("INWX_TTL", 300), + Sandbox: env.GetOrDefaultBool("INWX_SANDBOX", false), + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config + client *goinwx.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for Dyn DNS. +// Credentials must be passed in the environment variables: +// INWX_USERNAME and INWX_PASSWORD. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("INWX_USERNAME", "INWX_PASSWORD") + if err != nil { + return nil, fmt.Errorf("inwx: %v", err) + } + + config := NewDefaultConfig() + config.Username = values["INWX_USERNAME"] + config.Password = values["INWX_PASSWORD"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Dyn DNS +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("inwx: the configuration of the DNS provider is nil") + } + + if config.Username == "" || config.Password == "" { + return nil, fmt.Errorf("inwx: credentials missing") + } + + if config.Sandbox { + log.Infof("inwx: sandbox mode is enabled") + } + + client := goinwx.NewClient(config.Username, config.Password, &goinwx.ClientOptions{Sandbox: config.Sandbox}) + + return &DNSProvider{config: config, client: client}, nil +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("inwx: %v", err) + } + + err = d.client.Account.Login() + if err != nil { + return fmt.Errorf("inwx: %v", err) + } + + defer func() { + errL := d.client.Account.Logout() + if errL != nil { + log.Infof("inwx: failed to logout: %v", errL) + } + }() + + var request = &goinwx.NameserverRecordRequest{ + Domain: dns01.UnFqdn(authZone), + Name: dns01.UnFqdn(fqdn), + Type: "TXT", + Content: value, + TTL: d.config.TTL, + } + + _, err = d.client.Nameservers.CreateRecord(request) + if err != nil { + switch er := err.(type) { + case *goinwx.ErrorResponse: + if er.Message == "Object exists" { + return nil + } + return fmt.Errorf("inwx: %v", err) + default: + return fmt.Errorf("inwx: %v", err) + } + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("inwx: %v", err) + } + + err = d.client.Account.Login() + if err != nil { + return fmt.Errorf("inwx: %v", err) + } + + defer func() { + errL := d.client.Account.Logout() + if errL != nil { + log.Infof("inwx: failed to logout: %v", errL) + } + }() + + response, err := d.client.Nameservers.Info(&goinwx.NameserverInfoRequest{ + Domain: dns01.UnFqdn(authZone), + Name: dns01.UnFqdn(fqdn), + Type: "TXT", + }) + if err != nil { + return fmt.Errorf("inwx: %v", err) + } + + var lastErr error + for _, record := range response.Records { + err = d.client.Nameservers.DeleteRecord(record.ID) + if err != nil { + lastErr = fmt.Errorf("inwx: %v", err) + } + } + + return lastErr +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/inwx/inwx.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/inwx/inwx.toml new file mode 100644 index 000000000..31434800c --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/inwx/inwx.toml @@ -0,0 +1,21 @@ +Name = "INWX" +Description = '''''' +URL = "https://www.inwx.de/en" +Code = "inwx" +Since = "v2.0.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + INWX_USERNAME = "Username" + INWX_PASSWORD = "Password" + [Configuration.Additional] + INWX_POLLING_INTERVAL = "Time between DNS propagation check" + INWX_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + INWX_TTL = "The TTL of the TXT record used for the DNS challenge" + INWX_SANDBOX = "Activate the sandbox (boolean)" + +[Links] + API = "https://www.inwx.de/en/help/apidoc" + GoClient = "https://github.com/nrdcg/goinwx" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/joker/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/joker/client.go new file mode 100644 index 000000000..2466181f3 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/joker/client.go @@ -0,0 +1,210 @@ +package joker + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" +) + +const defaultBaseURL = "https://dmapi.joker.com/request/" + +// Joker DMAPI Response +type response struct { + Headers url.Values + Body string + StatusCode int + StatusText string + AuthSid string +} + +// parseResponse parses HTTP response body +func parseResponse(message string) *response { + r := &response{Headers: url.Values{}, StatusCode: -1} + + parts := strings.SplitN(message, "\n\n", 2) + + for _, line := range strings.Split(parts[0], "\n") { + if strings.TrimSpace(line) == "" { + continue + } + + kv := strings.SplitN(line, ":", 2) + + val := "" + if len(kv) == 2 { + val = strings.TrimSpace(kv[1]) + } + + r.Headers.Add(kv[0], val) + + switch kv[0] { + case "Status-Code": + i, err := strconv.Atoi(val) + if err == nil { + r.StatusCode = i + } + case "Status-Text": + r.StatusText = val + case "Auth-Sid": + r.AuthSid = val + } + } + + if len(parts) > 1 { + r.Body = parts[1] + } + + return r +} + +// login performs a login to Joker's DMAPI +func (d *DNSProvider) login() (*response, error) { + if d.config.AuthSid != "" { + // already logged in + return nil, nil + } + + var values url.Values + switch { + case d.config.Username != "" && d.config.Password != "": + values = url.Values{ + "username": {d.config.Username}, + "password": {d.config.Password}, + } + case d.config.APIKey != "": + values = url.Values{"api-key": {d.config.APIKey}} + default: + return nil, fmt.Errorf("no username and password or api-key") + } + + response, err := d.postRequest("login", values) + if err != nil { + return response, err + } + + if response == nil { + return nil, fmt.Errorf("login returned nil response") + } + + if response.AuthSid == "" { + return response, fmt.Errorf("login did not return valid Auth-Sid") + } + + d.config.AuthSid = response.AuthSid + + return response, nil +} + +// logout closes authenticated session with Joker's DMAPI +func (d *DNSProvider) logout() (*response, error) { + if d.config.AuthSid == "" { + return nil, fmt.Errorf("already logged out") + } + + response, err := d.postRequest("logout", url.Values{}) + if err == nil { + d.config.AuthSid = "" + } + return response, err +} + +// getZone returns content of DNS zone for domain +func (d *DNSProvider) getZone(domain string) (*response, error) { + if d.config.AuthSid == "" { + return nil, fmt.Errorf("must be logged in to get zone") + } + + return d.postRequest("dns-zone-get", url.Values{"domain": {dns01.UnFqdn(domain)}}) +} + +// putZone uploads DNS zone to Joker DMAPI +func (d *DNSProvider) putZone(domain, zone string) (*response, error) { + if d.config.AuthSid == "" { + return nil, fmt.Errorf("must be logged in to put zone") + } + + return d.postRequest("dns-zone-put", url.Values{"domain": {dns01.UnFqdn(domain)}, "zone": {strings.TrimSpace(zone)}}) +} + +// postRequest performs actual HTTP request +func (d *DNSProvider) postRequest(cmd string, data url.Values) (*response, error) { + uri := d.config.BaseURL + cmd + + if d.config.AuthSid != "" { + data.Set("auth-sid", d.config.AuthSid) + } + + if d.config.Debug { + log.Infof("postRequest:\n\tURL: %q\n\tData: %v", uri, data) + } + + resp, err := d.config.HTTPClient.PostForm(uri, data) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("HTTP error %d [%s]: %v", resp.StatusCode, http.StatusText(resp.StatusCode), string(body)) + } + + return parseResponse(string(body)), nil +} + +// Temporary workaround, until it get fixed on API side +func fixTxtLines(line string) string { + fields := strings.Fields(line) + + if len(fields) < 6 || fields[1] != "TXT" { + return line + } + + if fields[3][0] == '"' && fields[4] == `"` { + fields[3] = strings.TrimSpace(fields[3]) + `"` + fields = append(fields[:4], fields[5:]...) + } + + return strings.Join(fields, " ") +} + +// removeTxtEntryFromZone clean-ups all TXT records with given name +func removeTxtEntryFromZone(zone, relative string) (string, bool) { + prefix := fmt.Sprintf("%s TXT 0 ", relative) + + modified := false + var zoneEntries []string + for _, line := range strings.Split(zone, "\n") { + if strings.HasPrefix(line, prefix) { + modified = true + continue + } + zoneEntries = append(zoneEntries, line) + } + + return strings.TrimSpace(strings.Join(zoneEntries, "\n")), modified +} + +// addTxtEntryToZone returns DNS zone with added TXT record +func addTxtEntryToZone(zone, relative, value string, ttl int) string { + var zoneEntries []string + + for _, line := range strings.Split(zone, "\n") { + zoneEntries = append(zoneEntries, fixTxtLines(line)) + } + + newZoneEntry := fmt.Sprintf("%s TXT 0 %q %d", relative, value, ttl) + zoneEntries = append(zoneEntries, newZoneEntry) + + return strings.TrimSpace(strings.Join(zoneEntries, "\n")) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/joker/joker.go b/vendor/github.com/go-acme/lego/v3/providers/dns/joker/joker.go new file mode 100644 index 000000000..90b8e10f9 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/joker/joker.go @@ -0,0 +1,184 @@ +// Package joker implements a DNS provider for solving the DNS-01 challenge using joker.com DMAPI. +package joker + +import ( + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider. +type Config struct { + Debug bool + BaseURL string + APIKey string + Username string + Password string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client + AuthSid string +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + BaseURL: defaultBaseURL, + Debug: env.GetOrDefaultBool("JOKER_DEBUG", false), + TTL: env.GetOrDefaultInt("JOKER_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("JOKER_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("JOKER_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("JOKER_HTTP_TIMEOUT", 60*time.Second), + }, + } +} + +// DNSProvider is an implementation of the ChallengeProviderTimeout interface +// that uses Joker's DMAPI to manage TXT records for a domain. +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for Joker DMAPI. +// Credentials must be passed in the environment variable JOKER_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("JOKER_API_KEY") + if err != nil { + var errU error + values, errU = env.Get("JOKER_USERNAME", "JOKER_PASSWORD") + if errU != nil { + return nil, fmt.Errorf("joker: %v or %v", errU, err) + } + } + + config := NewDefaultConfig() + config.APIKey = values["JOKER_API_KEY"] + config.Username = values["JOKER_USERNAME"] + config.Password = values["JOKER_PASSWORD"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Joker DMAPI. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("joker: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + if config.Username == "" || config.Password == "" { + return nil, fmt.Errorf("joker: credentials missing") + } + } + + if !strings.HasSuffix(config.BaseURL, "/") { + config.BaseURL += "/" + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present installs a TXT record for the DNS challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("joker: %v", err) + } + + relative := getRelative(fqdn, zone) + + if d.config.Debug { + log.Infof("[%s] joker: adding TXT record %q to zone %q with value %q", domain, relative, zone, value) + } + + response, err := d.login() + if err != nil { + return formatResponseError(response, err) + } + + response, err = d.getZone(zone) + if err != nil || response.StatusCode != 0 { + return formatResponseError(response, err) + } + + dnsZone := addTxtEntryToZone(response.Body, relative, value, d.config.TTL) + + response, err = d.putZone(zone, dnsZone) + if err != nil || response.StatusCode != 0 { + return formatResponseError(response, err) + } + + return nil +} + +// CleanUp removes a TXT record used for a previous DNS challenge. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("joker: %v", err) + } + + relative := getRelative(fqdn, zone) + + if d.config.Debug { + log.Infof("[%s] joker: removing entry %q from zone %q", domain, relative, zone) + } + + response, err := d.login() + if err != nil { + return formatResponseError(response, err) + } + + defer func() { + // Try to logout in case of errors + _, _ = d.logout() + }() + + response, err = d.getZone(zone) + if err != nil || response.StatusCode != 0 { + return formatResponseError(response, err) + } + + dnsZone, modified := removeTxtEntryFromZone(response.Body, relative) + if modified { + response, err = d.putZone(zone, dnsZone) + if err != nil || response.StatusCode != 0 { + return formatResponseError(response, err) + } + } + + response, err = d.logout() + if err != nil { + return formatResponseError(response, err) + } + return nil +} + +func getRelative(fqdn, zone string) string { + return dns01.UnFqdn(strings.TrimSuffix(fqdn, dns01.ToFqdn(zone))) +} + +// formatResponseError formats error with optional details from DMAPI response +func formatResponseError(response *response, err error) error { + if response != nil { + return fmt.Errorf("joker: DMAPI error: %v Response: %v", err, response.Headers) + } + return fmt.Errorf("joker: DMAPI error: %v", err) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/joker/joker.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/joker/joker.toml new file mode 100644 index 000000000..53a2b8111 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/joker/joker.toml @@ -0,0 +1,28 @@ +Name = "Joker" +Description = '''''' +URL = "https://joker.com" +Code = "joker" +Since = "v2.6.0" + +Example = ''' +JOKER_USERNAME= \ +JOKER_PASSWORD= \ +lego --dns joker --domains my.domain.com --email my@email.com run +# or +JOKER_API_KEY= \ +lego --dns joker --domains my.domain.com --email my@email.com run +''' + +[Configuration] + [Configuration.Credentials] + JOKER_API_KEY = "API key" + JOKER_USERNAME = "Joker.com username (email address)" + JOKER_PASSWORD = "Joker.com password" + [Configuration.Additional] + JOKER_POLLING_INTERVAL = "Time between DNS propagation check" + JOKER_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + JOKER_TTL = "The TTL of the TXT record used for the DNS challenge" + JOKER_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://joker.com/faq/category/39/22-dmapi.html" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/lightsail/lightsail.go b/vendor/github.com/go-acme/lego/v3/providers/dns/lightsail/lightsail.go new file mode 100644 index 000000000..4aa98a619 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/lightsail/lightsail.go @@ -0,0 +1,153 @@ +// Package lightsail implements a DNS provider for solving the DNS-01 challenge using AWS Lightsail DNS. +package lightsail + +import ( + "errors" + "fmt" + "math/rand" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/lightsail" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const ( + maxRetries = 5 +) + +// customRetryer implements the client.Retryer interface by composing the DefaultRetryer. +// It controls the logic for retrying recoverable request errors (e.g. when rate limits are exceeded). +type customRetryer struct { + client.DefaultRetryer +} + +// RetryRules overwrites the DefaultRetryer's method. +// It uses a basic exponential backoff algorithm that returns an initial +// delay of ~400ms with an upper limit of ~30 seconds which should prevent +// causing a high number of consecutive throttling errors. +// For reference: Route 53 enforces an account-wide(!) 5req/s query limit. +func (c customRetryer) RetryRules(r *request.Request) time.Duration { + retryCount := r.RetryCount + if retryCount > 7 { + retryCount = 7 + } + + delay := (1 << uint(retryCount)) * (rand.Intn(50) + 200) + return time.Duration(delay) * time.Millisecond +} + +// Config is used to configure the creation of the DNSProvider +type Config struct { + DNSZone string + Region string + PropagationTimeout time.Duration + PollingInterval time.Duration +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + DNSZone: env.GetOrFile("DNS_ZONE"), + PropagationTimeout: env.GetOrDefaultSecond("LIGHTSAIL_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("LIGHTSAIL_POLLING_INTERVAL", dns01.DefaultPollingInterval), + Region: env.GetOrDefaultString("LIGHTSAIL_REGION", "us-east-1"), + } +} + +// DNSProvider implements the acme.ChallengeProvider interface +type DNSProvider struct { + client *lightsail.Lightsail + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for the AWS Lightsail service. +// +// AWS Credentials are automatically detected in the following locations +// and prioritized in the following order: +// 1. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, +// [AWS_SESSION_TOKEN], [DNS_ZONE], [LIGHTSAIL_REGION] +// 2. Shared credentials file (defaults to ~/.aws/credentials) +// 3. Amazon EC2 IAM role +// +// public hosted zone via the FQDN. +// +// See also: https://github.com/aws/aws-sdk-go/wiki/configuring-sdk +func NewDNSProvider() (*DNSProvider, error) { + return NewDNSProviderConfig(NewDefaultConfig()) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for AWS Lightsail. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("lightsail: the configuration of the DNS provider is nil") + } + + retryer := customRetryer{} + retryer.NumMaxRetries = maxRetries + + conf := aws.NewConfig().WithRegion(config.Region) + sess, err := session.NewSession(request.WithRetryer(conf, retryer)) + if err != nil { + return nil, err + } + + return &DNSProvider{ + config: config, + client: lightsail.New(sess), + }, nil +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + err := d.newTxtRecord(fqdn, `"`+value+`"`) + if err != nil { + return fmt.Errorf("lightsail: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + params := &lightsail.DeleteDomainEntryInput{ + DomainName: aws.String(d.config.DNSZone), + DomainEntry: &lightsail.DomainEntry{ + Name: aws.String(fqdn), + Type: aws.String("TXT"), + Target: aws.String(`"` + value + `"`), + }, + } + + _, err := d.client.DeleteDomainEntry(params) + if err != nil { + return fmt.Errorf("lightsail: %v", err) + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) newTxtRecord(fqdn string, value string) error { + params := &lightsail.CreateDomainEntryInput{ + DomainName: aws.String(d.config.DNSZone), + DomainEntry: &lightsail.DomainEntry{ + Name: aws.String(fqdn), + Target: aws.String(value), + Type: aws.String("TXT"), + }, + } + _, err := d.client.CreateDomainEntry(params) + return err +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/lightsail/lightsail.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/lightsail/lightsail.toml new file mode 100644 index 000000000..a94851ace --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/lightsail/lightsail.toml @@ -0,0 +1,19 @@ +Name = "Amazon Lightsail" +Description = '''''' +URL = "https://aws.amazon.com/lightsail/" +Code = "lightsail" +Since = "v0.5.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + AWS_ACCESS_KEY_ID = "Access key ID" + AWS_SECRET_ACCESS_KEY = "Secret access key" + DNS_ZONE = "DNS zone" + [Configuration.Additional] + LIGHTSAIL_POLLING_INTERVAL = "Time between DNS propagation check" + LIGHTSAIL_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + +[Links] + GoClient = "https://github.com/aws/aws-sdk-go/aws" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/linode/linode.go b/vendor/github.com/go-acme/lego/v3/providers/dns/linode/linode.go new file mode 100644 index 000000000..d42879c62 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/linode/linode.go @@ -0,0 +1,164 @@ +// Package linode implements a DNS provider for solving the DNS-01 challenge using Linode DNS. +package linode + +import ( + "errors" + "fmt" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/timewasted/linode/dns" +) + +const ( + minTTL = 300 + dnsUpdateFreqMins = 15 + dnsUpdateFudgeSecs = 120 +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PollingInterval: env.GetOrDefaultSecond("LINODE_POLLING_INTERVAL", 15*time.Second), + TTL: env.GetOrDefaultInt("LINODE_TTL", minTTL), + } +} + +type hostedZoneInfo struct { + domainID int + resourceName string +} + +// DNSProvider implements the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *dns.DNS +} + +// NewDNSProvider returns a DNSProvider instance configured for Linode. +// Credentials must be passed in the environment variable: LINODE_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("LINODE_API_KEY") + if err != nil { + return nil, fmt.Errorf("linode: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["LINODE_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Linode. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("linode: the configuration of the DNS provider is nil") + } + + if len(config.APIKey) == 0 { + return nil, errors.New("linode: credentials missing") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("linode: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + return &DNSProvider{ + config: config, + client: dns.New(config.APIKey), + }, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS +// propagation. Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + // Since Linode only updates their zone files every X minutes, we need + // to figure out how many minutes we have to wait until we hit the next + // interval of X. We then wait another couple of minutes, just to be + // safe. Hopefully at some point during all of this, the record will + // have propagated throughout Linode's network. + minsRemaining := dnsUpdateFreqMins - (time.Now().Minute() % dnsUpdateFreqMins) + + timeout = (time.Duration(minsRemaining) * time.Minute) + + (minTTL * time.Second) + + (dnsUpdateFudgeSecs * time.Second) + interval = d.config.PollingInterval + return +} + +// Present creates a TXT record using the specified parameters. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + zone, err := d.getHostedZoneInfo(fqdn) + if err != nil { + return err + } + + if _, err = d.client.CreateDomainResourceTXT(zone.domainID, dns01.UnFqdn(fqdn), value, d.config.TTL); err != nil { + return err + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + zone, err := d.getHostedZoneInfo(fqdn) + if err != nil { + return err + } + + // Get all TXT records for the specified domain. + resources, err := d.client.GetResourcesByType(zone.domainID, "TXT") + if err != nil { + return err + } + + // Remove the specified resource, if it exists. + for _, resource := range resources { + if resource.Name == zone.resourceName && resource.Target == value { + resp, err := d.client.DeleteDomainResource(resource.DomainID, resource.ResourceID) + if err != nil { + return err + } + + if resp.ResourceID != resource.ResourceID { + return errors.New("error deleting resource: resource IDs do not match") + } + break + } + } + + return nil +} + +func (d *DNSProvider) getHostedZoneInfo(fqdn string) (*hostedZoneInfo, error) { + // Lookup the zone that handles the specified FQDN. + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return nil, err + } + + resourceName := strings.TrimSuffix(fqdn, "."+authZone) + + // Query the authority zone. + domain, err := d.client.GetDomain(dns01.UnFqdn(authZone)) + if err != nil { + return nil, err + } + + return &hostedZoneInfo{ + domainID: domain.DomainID, + resourceName: resourceName, + }, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/linode/linode.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/linode/linode.toml new file mode 100644 index 000000000..0e912f041 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/linode/linode.toml @@ -0,0 +1,19 @@ +Name = "Linode (deprecated)" +Description = '''''' +URL = "https://www.linode.com/" +Code = "linode" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + LINODE_API_KEY = "API key" + [Configuration.Additional] + LINODE_POLLING_INTERVAL = "Time between DNS propagation check" + LINODE_TTL = "The TTL of the TXT record used for the DNS challenge" + LINODE_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.linode.com/api/dns" + GoClient = "https://github.com/timewasted/linode" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/linodev4/linodev4.go b/vendor/github.com/go-acme/lego/v3/providers/dns/linodev4/linodev4.go new file mode 100644 index 000000000..a71686755 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/linodev4/linodev4.go @@ -0,0 +1,190 @@ +// Package linodev4 implements a DNS provider for solving the DNS-01 challenge using Linode DNS and Linode's APIv4 +package linodev4 + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/linode/linodego" + "golang.org/x/oauth2" +) + +const ( + minTTL = 300 + dnsUpdateFreqMins = 15 + dnsUpdateFudgeSecs = 120 +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Token string + PollingInterval time.Duration + TTL int + HTTPTimeout time.Duration +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PollingInterval: env.GetOrDefaultSecond("LINODE_POLLING_INTERVAL", 15*time.Second), + TTL: env.GetOrDefaultInt("LINODE_TTL", minTTL), + HTTPTimeout: env.GetOrDefaultSecond("LINODE_HTTP_TIMEOUT", 0), + } +} + +type hostedZoneInfo struct { + domainID int + resourceName string +} + +// DNSProvider implements the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *linodego.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for Linode. +// Credentials must be passed in the environment variable: LINODE_TOKEN. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("LINODE_TOKEN") + if err != nil { + return nil, fmt.Errorf("linodev4: %v", err) + } + + config := NewDefaultConfig() + config.Token = values["LINODE_TOKEN"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Linode. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("linodev4: the configuration of the DNS provider is nil") + } + + if len(config.Token) == 0 { + return nil, errors.New("linodev4: Linode Access Token missing") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("linodev4: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: config.Token}) + oauth2Client := &http.Client{ + Timeout: config.HTTPTimeout, + Transport: &oauth2.Transport{ + Source: tokenSource, + }, + } + + client := linodego.NewClient(oauth2Client) + client.SetUserAgent(fmt.Sprintf("lego-dns linodego/%s", linodego.Version)) + + return &DNSProvider{ + config: config, + client: &client, + }, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS +// propagation. Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + // Since Linode only updates their zone files every X minutes, we need + // to figure out how many minutes we have to wait until we hit the next + // interval of X. We then wait another couple of minutes, just to be + // safe. Hopefully at some point during all of this, the record will + // have propagated throughout Linode's network. + minsRemaining := dnsUpdateFreqMins - (time.Now().Minute() % dnsUpdateFreqMins) + + timeout = (time.Duration(minsRemaining) * time.Minute) + + (minTTL * time.Second) + + (dnsUpdateFudgeSecs * time.Second) + interval = d.config.PollingInterval + return +} + +// Present creates a TXT record using the specified parameters. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + zone, err := d.getHostedZoneInfo(fqdn) + if err != nil { + return err + } + + createOpts := linodego.DomainRecordCreateOptions{ + Name: dns01.UnFqdn(fqdn), + Target: value, + TTLSec: d.config.TTL, + Type: linodego.RecordTypeTXT, + } + + _, err = d.client.CreateDomainRecord(context.Background(), zone.domainID, createOpts) + return err +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZoneInfo(fqdn) + if err != nil { + return err + } + + // Get all TXT records for the specified domain. + listOpts := linodego.NewListOptions(0, "{\"type\":\"TXT\"}") + resources, err := d.client.ListDomainRecords(context.Background(), zone.domainID, listOpts) + if err != nil { + return err + } + + // Remove the specified resource, if it exists. + for _, resource := range resources { + if (resource.Name == strings.TrimSuffix(fqdn, ".") || resource.Name == zone.resourceName) && + resource.Target == value { + if err := d.client.DeleteDomainRecord(context.Background(), zone.domainID, resource.ID); err != nil { + return err + } + } + } + + return nil +} + +func (d *DNSProvider) getHostedZoneInfo(fqdn string) (*hostedZoneInfo, error) { + // Lookup the zone that handles the specified FQDN. + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return nil, err + } + + // Query the authority zone. + data, err := json.Marshal(map[string]string{"domain": dns01.UnFqdn(authZone)}) + if err != nil { + return nil, err + } + + listOpts := linodego.NewListOptions(0, string(data)) + domains, err := d.client.ListDomains(context.Background(), listOpts) + if err != nil { + return nil, err + } + + if len(domains) == 0 { + return nil, fmt.Errorf("domain not found") + } + + return &hostedZoneInfo{ + domainID: domains[0].ID, + resourceName: strings.TrimSuffix(fqdn, "."+authZone), + }, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/linodev4/linodev4.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/linodev4/linodev4.toml new file mode 100644 index 000000000..6111c3e40 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/linodev4/linodev4.toml @@ -0,0 +1,19 @@ +Name = "Linode (v4)" +Description = '''''' +URL = "https://www.linode.com/" +Code = "linodev4" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + LINODE_TOKEN = "API token" + [Configuration.Additional] + LINODE_POLLING_INTERVAL = "Time between DNS propagation check" + LINODE_TTL = "The TTL of the TXT record used for the DNS challenge" + LINODE_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://developers.linode.com/api/v4" + GoClient = "https://github.com/linode/linodego" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/client.go new file mode 100644 index 000000000..d8fc5841e --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/client.go @@ -0,0 +1,52 @@ +package mydnsjp + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +func (d *DNSProvider) doRequest(domain, value string, cmd string) error { + req, err := d.buildRequest(domain, value, cmd) + if err != nil { + return err + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return fmt.Errorf("error querying API: %v", err) + } + + defer resp.Body.Close() + + if resp.StatusCode >= 400 { + var content []byte + content, err = ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + return fmt.Errorf("request %s failed [status code %d]: %s", req.URL, resp.StatusCode, string(content)) + } + + return nil +} + +func (d *DNSProvider) buildRequest(domain, value string, cmd string) (*http.Request, error) { + params := url.Values{} + params.Set("CERTBOT_DOMAIN", domain) + params.Set("CERTBOT_VALIDATION", value) + params.Set("EDIT_CMD", cmd) + + req, err := http.NewRequest(http.MethodPost, defaultBaseURL, strings.NewReader(params.Encode())) + if err != nil { + return nil, fmt.Errorf("invalid request: %v", err) + } + + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.SetBasicAuth(d.config.MasterID, d.config.Password) + + return req, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/mydnsjp.go b/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/mydnsjp.go new file mode 100644 index 000000000..0a19b7754 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/mydnsjp.go @@ -0,0 +1,93 @@ +// Package mydnsjp implements a DNS provider for solving the DNS-01 challenge using MyDNS.jp. +package mydnsjp + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const defaultBaseURL = "https://www.mydns.jp/directedit.html" + +// Config is used to configure the creation of the DNSProvider +type Config struct { + MasterID string + Password string + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("MYDNSJP_PROPAGATION_TIMEOUT", 2*time.Minute), + PollingInterval: env.GetOrDefaultSecond("MYDNSJP_POLLING_INTERVAL", 2*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("MYDNSJP_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for MyDNS.jp. +// Credentials must be passed in the environment variables: MYDNSJP_MASTER_ID and MYDNSJP_PASSWORD. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("MYDNSJP_MASTER_ID", "MYDNSJP_PASSWORD") + if err != nil { + return nil, fmt.Errorf("mydnsjp: %v", err) + } + + config := NewDefaultConfig() + config.MasterID = values["MYDNSJP_MASTER_ID"] + config.Password = values["MYDNSJP_PASSWORD"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for MyDNS.jp. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("mydnsjp: the configuration of the DNS provider is nil") + } + + if config.MasterID == "" || config.Password == "" { + return nil, errors.New("mydnsjp: some credentials information are missing") + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + _, value := dns01.GetRecord(domain, keyAuth) + err := d.doRequest(domain, value, "REGIST") + if err != nil { + return fmt.Errorf("mydnsjp: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + _, value := dns01.GetRecord(domain, keyAuth) + err := d.doRequest(domain, value, "DELETE") + if err != nil { + return fmt.Errorf("mydnsjp: %v", err) + } + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/mydnsjp.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/mydnsjp.toml new file mode 100644 index 000000000..37b6bb854 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/mydnsjp/mydnsjp.toml @@ -0,0 +1,20 @@ +Name = "MyDNS.jp" +Description = '''''' +URL = "https://www.mydns.jp" +Code = "mydnsjp" +Since = "v1.2.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + MYDNSJP_MASTER_ID = "Master ID" + MYDNSJP_PASSWORD = "Password" + [Configuration.Additional] + MYDNSJP_POLLING_INTERVAL = "Time between DNS propagation check" + MYDNSJP_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + MYDNSJP_TTL = "The TTL of the TXT record used for the DNS challenge" + MYDNSJP_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.mydns.jp/?MENU=030" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/client.go new file mode 100644 index 000000000..85bec85f8 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/client.go @@ -0,0 +1,225 @@ +package namecheap + +import ( + "encoding/xml" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +// Record describes a DNS record returned by the Namecheap DNS gethosts API. +// Namecheap uses the term "host" to refer to all DNS records that include +// a host field (A, AAAA, CNAME, NS, TXT, URL). +type Record struct { + Type string `xml:",attr"` + Name string `xml:",attr"` + Address string `xml:",attr"` + MXPref string `xml:",attr"` + TTL string `xml:",attr"` +} + +// apiError describes an error record in a namecheap API response. +type apiError struct { + Number int `xml:",attr"` + Description string `xml:",innerxml"` +} + +type setHostsResponse struct { + XMLName xml.Name `xml:"ApiResponse"` + Status string `xml:"Status,attr"` + Errors []apiError `xml:"Errors>Error"` + Result struct { + IsSuccess string `xml:",attr"` + } `xml:"CommandResponse>DomainDNSSetHostsResult"` +} + +type getHostsResponse struct { + XMLName xml.Name `xml:"ApiResponse"` + Status string `xml:"Status,attr"` + Errors []apiError `xml:"Errors>Error"` + Hosts []Record `xml:"CommandResponse>DomainDNSGetHostsResult>host"` +} + +type getTldsResponse struct { + XMLName xml.Name `xml:"ApiResponse"` + Errors []apiError `xml:"Errors>Error"` + Result []struct { + Name string `xml:",attr"` + } `xml:"CommandResponse>Tlds>Tld"` +} + +// getTLDs requests the list of available TLDs. +// https://www.namecheap.com/support/api/methods/domains/get-tld-list.aspx +func (d *DNSProvider) getTLDs() (map[string]string, error) { + request, err := d.newRequestGet("namecheap.domains.getTldList") + if err != nil { + return nil, err + } + + var gtr getTldsResponse + err = d.do(request, >r) + if err != nil { + return nil, err + } + + if len(gtr.Errors) > 0 { + return nil, fmt.Errorf("%s [%d]", gtr.Errors[0].Description, gtr.Errors[0].Number) + } + + tlds := make(map[string]string) + for _, t := range gtr.Result { + tlds[t.Name] = t.Name + } + return tlds, nil +} + +// getHosts reads the full list of DNS host records. +// https://www.namecheap.com/support/api/methods/domains-dns/get-hosts.aspx +func (d *DNSProvider) getHosts(sld, tld string) ([]Record, error) { + request, err := d.newRequestGet("namecheap.domains.dns.getHosts", + addParam("SLD", sld), + addParam("TLD", tld), + ) + if err != nil { + return nil, err + } + + var ghr getHostsResponse + err = d.do(request, &ghr) + if err != nil { + return nil, err + } + + if len(ghr.Errors) > 0 { + return nil, fmt.Errorf("%s [%d]", ghr.Errors[0].Description, ghr.Errors[0].Number) + } + + return ghr.Hosts, nil +} + +// setHosts writes the full list of DNS host records . +// https://www.namecheap.com/support/api/methods/domains-dns/set-hosts.aspx +func (d *DNSProvider) setHosts(sld, tld string, hosts []Record) error { + req, err := d.newRequestPost("namecheap.domains.dns.setHosts", + addParam("SLD", sld), + addParam("TLD", tld), + func(values url.Values) { + for i, h := range hosts { + ind := fmt.Sprintf("%d", i+1) + values.Add("HostName"+ind, h.Name) + values.Add("RecordType"+ind, h.Type) + values.Add("Address"+ind, h.Address) + values.Add("MXPref"+ind, h.MXPref) + values.Add("TTL"+ind, h.TTL) + } + }, + ) + if err != nil { + return err + } + + var shr setHostsResponse + err = d.do(req, &shr) + if err != nil { + return err + } + + if len(shr.Errors) > 0 { + return fmt.Errorf("%s [%d]", shr.Errors[0].Description, shr.Errors[0].Number) + } + if shr.Result.IsSuccess != "true" { + return fmt.Errorf("setHosts failed") + } + + return nil +} + +func (d *DNSProvider) do(req *http.Request, out interface{}) error { + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode >= 400 { + var body []byte + body, err = readBody(resp) + if err != nil { + return fmt.Errorf("HTTP error %d [%s]: %v", resp.StatusCode, http.StatusText(resp.StatusCode), err) + } + return fmt.Errorf("HTTP error %d [%s]: %s", resp.StatusCode, http.StatusText(resp.StatusCode), string(body)) + } + + body, err := readBody(resp) + if err != nil { + return err + } + + if err := xml.Unmarshal(body, out); err != nil { + return err + } + + return nil +} + +func (d *DNSProvider) newRequestGet(cmd string, params ...func(url.Values)) (*http.Request, error) { + query := d.makeQuery(cmd, params...) + + reqURL, err := url.Parse(d.config.BaseURL) + if err != nil { + return nil, err + } + + reqURL.RawQuery = query.Encode() + + return http.NewRequest(http.MethodGet, reqURL.String(), nil) +} + +func (d *DNSProvider) newRequestPost(cmd string, params ...func(url.Values)) (*http.Request, error) { + query := d.makeQuery(cmd, params...) + + req, err := http.NewRequest(http.MethodPost, d.config.BaseURL, strings.NewReader(query.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + return req, nil +} + +func (d *DNSProvider) makeQuery(cmd string, params ...func(url.Values)) url.Values { + queryParams := make(url.Values) + queryParams.Set("ApiUser", d.config.APIUser) + queryParams.Set("ApiKey", d.config.APIKey) + queryParams.Set("UserName", d.config.APIUser) + queryParams.Set("Command", cmd) + queryParams.Set("ClientIp", d.config.ClientIP) + + for _, param := range params { + param(queryParams) + } + + return queryParams +} + +func addParam(key, value string) func(url.Values) { + return func(values url.Values) { + values.Set(key, value) + } +} + +func readBody(resp *http.Response) ([]byte, error) { + if resp.Body == nil { + return nil, fmt.Errorf("response body is nil") + } + + defer resp.Body.Close() + + rawBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return rawBody, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/namecheap.go b/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/namecheap.go new file mode 100644 index 000000000..bc1f9d9ff --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/namecheap.go @@ -0,0 +1,260 @@ +// Package namecheap implements a DNS provider for solving the DNS-01 challenge using namecheap DNS. +package namecheap + +import ( + "errors" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Notes about namecheap's tool API: +// 1. Using the API requires registration. Once registered, use your account +// name and API key to access the API. +// 2. There is no API to add or modify a single DNS record. Instead you must +// read the entire list of records, make modifications, and then write the +// entire updated list of records. (Yuck.) +// 3. Namecheap's DNS updates can be slow to propagate. I've seen them take +// as long as an hour. +// 4. Namecheap requires you to whitelist the IP address from which you call +// its APIs. It also requires all API calls to include the whitelisted IP +// address as a form or query string value. This code uses a namecheap +// service to query the client's IP address. + +const ( + defaultBaseURL = "https://api.namecheap.com/xml.response" + getIPURL = "https://dynamicdns.park-your-domain.com/getip" +) + +// A challenge represents all the data needed to specify a dns-01 challenge +// to lets-encrypt. +type challenge struct { + domain string + key string + keyFqdn string + keyValue string + tld string + sld string + host string +} + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Debug bool + BaseURL string + APIUser string + APIKey string + ClientIP string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + BaseURL: defaultBaseURL, + Debug: env.GetOrDefaultBool("NAMECHEAP_DEBUG", false), + TTL: env.GetOrDefaultInt("NAMECHEAP_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("NAMECHEAP_PROPAGATION_TIMEOUT", 60*time.Minute), + PollingInterval: env.GetOrDefaultSecond("NAMECHEAP_POLLING_INTERVAL", 15*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("NAMECHEAP_HTTP_TIMEOUT", 60*time.Second), + }, + } +} + +// DNSProvider is an implementation of the ChallengeProviderTimeout interface +// that uses Namecheap's tool API to manage TXT records for a domain. +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for namecheap. +// Credentials must be passed in the environment variables: +// NAMECHEAP_API_USER and NAMECHEAP_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("NAMECHEAP_API_USER", "NAMECHEAP_API_KEY") + if err != nil { + return nil, fmt.Errorf("namecheap: %v", err) + } + + config := NewDefaultConfig() + config.APIUser = values["NAMECHEAP_API_USER"] + config.APIKey = values["NAMECHEAP_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for namecheap. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("namecheap: the configuration of the DNS provider is nil") + } + + if config.APIUser == "" || config.APIKey == "" { + return nil, fmt.Errorf("namecheap: credentials missing") + } + + if len(config.ClientIP) == 0 { + clientIP, err := getClientIP(config.HTTPClient, config.Debug) + if err != nil { + return nil, fmt.Errorf("namecheap: %v", err) + } + config.ClientIP = clientIP + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Namecheap can sometimes take a long time to complete an update, so wait up to 60 minutes for the update to propagate. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present installs a TXT record for the DNS challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + tlds, err := d.getTLDs() + if err != nil { + return fmt.Errorf("namecheap: %v", err) + } + + ch, err := newChallenge(domain, keyAuth, tlds) + if err != nil { + return fmt.Errorf("namecheap: %v", err) + } + + records, err := d.getHosts(ch.sld, ch.tld) + if err != nil { + return fmt.Errorf("namecheap: %v", err) + } + + record := Record{ + Name: ch.key, + Type: "TXT", + Address: ch.keyValue, + MXPref: "10", + TTL: strconv.Itoa(d.config.TTL), + } + + records = append(records, record) + + if d.config.Debug { + for _, h := range records { + log.Printf("%-5.5s %-30.30s %-6s %-70.70s", h.Type, h.Name, h.TTL, h.Address) + } + } + + err = d.setHosts(ch.sld, ch.tld, records) + if err != nil { + return fmt.Errorf("namecheap: %v", err) + } + return nil +} + +// CleanUp removes a TXT record used for a previous DNS challenge. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + tlds, err := d.getTLDs() + if err != nil { + return fmt.Errorf("namecheap: %v", err) + } + + ch, err := newChallenge(domain, keyAuth, tlds) + if err != nil { + return fmt.Errorf("namecheap: %v", err) + } + + records, err := d.getHosts(ch.sld, ch.tld) + if err != nil { + return fmt.Errorf("namecheap: %v", err) + } + + // Find the challenge TXT record and remove it if found. + var found bool + var newRecords []Record + for _, h := range records { + if h.Name == ch.key && h.Type == "TXT" { + found = true + } else { + newRecords = append(newRecords, h) + } + } + + if !found { + return nil + } + + err = d.setHosts(ch.sld, ch.tld, newRecords) + if err != nil { + return fmt.Errorf("namecheap: %v", err) + } + return nil +} + +// getClientIP returns the client's public IP address. +// It uses namecheap's IP discovery service to perform the lookup. +func getClientIP(client *http.Client, debug bool) (addr string, err error) { + resp, err := client.Get(getIPURL) + if err != nil { + return "", err + } + defer resp.Body.Close() + + clientIP, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + if debug { + log.Println("Client IP:", string(clientIP)) + } + return string(clientIP), nil +} + +// newChallenge builds a challenge record from a domain name, a challenge +// authentication key, and a map of available TLDs. +func newChallenge(domain, keyAuth string, tlds map[string]string) (*challenge, error) { + domain = dns01.UnFqdn(domain) + parts := strings.Split(domain, ".") + + // Find the longest matching TLD. + longest := -1 + for i := len(parts); i > 0; i-- { + t := strings.Join(parts[i-1:], ".") + if _, found := tlds[t]; found { + longest = i - 1 + } + } + if longest < 1 { + return nil, fmt.Errorf("invalid domain name %q", domain) + } + + tld := strings.Join(parts[longest:], ".") + sld := parts[longest-1] + + var host string + if longest >= 1 { + host = strings.Join(parts[:longest-1], ".") + } + + fqdn, value := dns01.GetRecord(domain, keyAuth) + + return &challenge{ + domain: domain, + key: "_acme-challenge." + host, + keyFqdn: fqdn, + keyValue: value, + tld: tld, + sld: sld, + host: host, + }, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/namecheap.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/namecheap.toml new file mode 100644 index 000000000..bb4fa8b91 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/namecheap/namecheap.toml @@ -0,0 +1,20 @@ +Name = "Namecheap" +Description = '''''' +URL = "https://www.namecheap.com" +Code = "namecheap" +Since = "v0.3.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + NAMECHEAP_API_USER = "API user" + NAMECHEAP_API_KEY = "API key" + [Configuration.Additional] + NAMECHEAP_POLLING_INTERVAL = "Time between DNS propagation check" + NAMECHEAP_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + NAMECHEAP_TTL = "The TTL of the TXT record used for the DNS challenge" + NAMECHEAP_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.namecheap.com/support/api/methods.aspx" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/namedotcom/namedotcom.go b/vendor/github.com/go-acme/lego/v3/providers/dns/namedotcom/namedotcom.go new file mode 100644 index 000000000..df172f5e8 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/namedotcom/namedotcom.go @@ -0,0 +1,170 @@ +// Package namedotcom implements a DNS provider for solving the DNS-01 challenge using Name.com's DNS service. +package namedotcom + +import ( + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/namedotcom/go/namecom" +) + +// according to https://www.name.com/api-docs/DNS#CreateRecord +const minTTL = 300 + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Username string + APIToken string + Server string + TTL int + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("NAMECOM_TTL", minTTL), + PropagationTimeout: env.GetOrDefaultSecond("NAMECOM_PROPAGATION_TIMEOUT", 15*time.Minute), + PollingInterval: env.GetOrDefaultSecond("NAMECOM_POLLING_INTERVAL", 20*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("NAMECOM_HTTP_TIMEOUT", 10*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + client *namecom.NameCom + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for namedotcom. +// Credentials must be passed in the environment variables: +// NAMECOM_USERNAME and NAMECOM_API_TOKEN +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("NAMECOM_USERNAME", "NAMECOM_API_TOKEN") + if err != nil { + return nil, fmt.Errorf("namedotcom: %v", err) + } + + config := NewDefaultConfig() + config.Username = values["NAMECOM_USERNAME"] + config.APIToken = values["NAMECOM_API_TOKEN"] + config.Server = env.GetOrFile("NAMECOM_SERVER") + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for namedotcom. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("namedotcom: the configuration of the DNS provider is nil") + } + + if config.Username == "" { + return nil, fmt.Errorf("namedotcom: username is required") + } + + if config.APIToken == "" { + return nil, fmt.Errorf("namedotcom: API token is required") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("namedotcom: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + client := namecom.New(config.Username, config.APIToken) + client.Client = config.HTTPClient + + if config.Server != "" { + client.Server = config.Server + } + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + request := &namecom.Record{ + DomainName: domain, + Host: d.extractRecordName(fqdn, domain), + Type: "TXT", + TTL: uint32(d.config.TTL), + Answer: value, + } + + _, err := d.client.CreateRecord(request) + if err != nil { + return fmt.Errorf("namedotcom: API call failed: %v", err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + records, err := d.getRecords(domain) + if err != nil { + return fmt.Errorf("namedotcom: %v", err) + } + + for _, rec := range records { + if rec.Fqdn == fqdn && rec.Type == "TXT" { + request := &namecom.DeleteRecordRequest{ + DomainName: domain, + ID: rec.ID, + } + _, err := d.client.DeleteRecord(request) + if err != nil { + return fmt.Errorf("namedotcom: %v", err) + } + } + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) getRecords(domain string) ([]*namecom.Record, error) { + request := &namecom.ListRecordsRequest{ + DomainName: domain, + Page: 1, + } + + var records []*namecom.Record + for request.Page > 0 { + response, err := d.client.ListRecords(request) + if err != nil { + return nil, err + } + + records = append(records, response.Records...) + request.Page = response.NextPage + } + + return records, nil +} + +func (d *DNSProvider) extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/namedotcom/namedotcom.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/namedotcom/namedotcom.toml new file mode 100644 index 000000000..cd1beaae0 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/namedotcom/namedotcom.toml @@ -0,0 +1,22 @@ +Name = "Name.com" +Description = '''''' +URL = "https://www.name.com" +Code = "namedotcom" +Since = "v0.5.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + NAMECOM_USERNAME = "Username" + NAMECOM_API_TOKEN = "API token" + [Configuration.Additional] + NAMECOM_POLLING_INTERVAL = "Time between DNS propagation check" + NAMECOM_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + NAMECOM_TTL = "The TTL of the TXT record used for the DNS challenge" + NAMECOM_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.name.com/api-docs/DNS" + GoClient = "https://github.com/namedotcom/go" + diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/namesilo/namesilo.go b/vendor/github.com/go-acme/lego/v3/providers/dns/namesilo/namesilo.go new file mode 100644 index 000000000..6a121bdd9 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/namesilo/namesilo.go @@ -0,0 +1,142 @@ +// Package namesilo implements a DNS provider for solving the DNS-01 challenge using namesilo DNS. +package namesilo + +import ( + "errors" + "fmt" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/nrdcg/namesilo" +) + +const ( + defaultTTL = 3600 + maxTTL = 2592000 +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + PropagationTimeout: env.GetOrDefaultSecond("NAMESILO_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("NAMESILO_POLLING_INTERVAL", dns01.DefaultPollingInterval), + TTL: env.GetOrDefaultInt("NAMESILO_TTL", defaultTTL), + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + client *namesilo.Client + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for namesilo. +// API_KEY must be passed in the environment variables: NAMESILO_API_KEY. +// +// See: https://www.namesilo.com/api_reference.php +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("NAMESILO_API_KEY") + if err != nil { + return nil, fmt.Errorf("namesilo: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["NAMESILO_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for DNSimple. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("namesilo: the configuration of the DNS provider is nil") + } + + if config.TTL < defaultTTL || config.TTL > maxTTL { + return nil, fmt.Errorf("namesilo: TTL should be in [%d, %d]", defaultTTL, maxTTL) + } + + transport, err := namesilo.NewTokenTransport(config.APIKey) + if err != nil { + return nil, fmt.Errorf("namesilo: %v", err) + } + + return &DNSProvider{client: namesilo.NewClient(transport.Client()), config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zoneName, err := getZoneNameByDomain(domain) + if err != nil { + return fmt.Errorf("namesilo: %v", err) + } + + _, err = d.client.DnsAddRecord(&namesilo.DnsAddRecordParams{ + Domain: zoneName, + Type: "TXT", + Host: getRecordName(fqdn, zoneName), + Value: value, + TTL: d.config.TTL, + }) + if err != nil { + return fmt.Errorf("namesilo: failed to add record %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zoneName, err := getZoneNameByDomain(domain) + if err != nil { + return fmt.Errorf("namesilo: %v", err) + } + + resp, err := d.client.DnsListRecords(&namesilo.DnsListRecordsParams{Domain: zoneName}) + if err != nil { + return fmt.Errorf("namesilo: %v", err) + } + + var lastErr error + name := getRecordName(fqdn, zoneName) + for _, r := range resp.Reply.ResourceRecord { + if r.Type == "TXT" && r.Host == name { + _, err := d.client.DnsDeleteRecord(&namesilo.DnsDeleteRecordParams{Domain: zoneName, ID: r.RecordID}) + if err != nil { + lastErr = fmt.Errorf("namesilo: %v", err) + } + } + } + return lastErr +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func getZoneNameByDomain(domain string) (string, error) { + zone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return "", fmt.Errorf("failed to find zone for domain: %s, %v", domain, err) + } + return dns01.UnFqdn(zone), nil +} + +func getRecordName(domain, zone string) string { + return strings.TrimSuffix(dns01.ToFqdn(domain), "."+dns01.ToFqdn(zone)) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/namesilo/namesilo.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/namesilo/namesilo.toml new file mode 100644 index 000000000..89a455c4f --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/namesilo/namesilo.toml @@ -0,0 +1,22 @@ +Name = "Namesilo" +Description = '''''' +URL = "https://www.namesilo.com/" +Code = "namesilo" +Since = "v2.7.0" + +Example = ''' +NAMESILO_API_KEY=b9841238feb177a84330febba8a83208921177bffe733 \ +lego --dns namesilo --domains my.domain.com --email my@email.com run +''' + +[Configuration] + [Configuration.Credentials] + NAMESILO_API_KEY = "Client ID" + [Configuration.Additional] + NAMESILO_POLLING_INTERVAL = "Time between DNS propagation check" + NAMESILO_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation, it is better to set larger than 15m" + NAMESILO_TTL = "The TTL of the TXT record used for the DNS challenge, should be in [3600, 2592000]" + +[Links] + API = "https://www.namesilo.com/api_reference.php" + GoClient = "https://github.com/nrdcg/namesilo" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/internal/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/internal/client.go new file mode 100644 index 000000000..733bfd0be --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/internal/client.go @@ -0,0 +1,327 @@ +package internal + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" +) + +// defaultBaseURL for reaching the jSON-based API-Endpoint of netcup +const defaultBaseURL = "https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON" + +// success response status +const success = "success" + +// Request wrapper as specified in netcup wiki +// needed for every request to netcup API around *Msg +// https://www.netcup-wiki.de/wiki/CCP_API#Anmerkungen_zu_JSON-Requests +type Request struct { + Action string `json:"action"` + Param interface{} `json:"param"` +} + +// LoginRequest as specified in netcup WSDL +// https://ccp.netcup.net/run/webservice/servers/endpoint.php#login +type LoginRequest struct { + CustomerNumber string `json:"customernumber"` + APIKey string `json:"apikey"` + APIPassword string `json:"apipassword"` + ClientRequestID string `json:"clientrequestid,omitempty"` +} + +// LogoutRequest as specified in netcup WSDL +// https://ccp.netcup.net/run/webservice/servers/endpoint.php#logout +type LogoutRequest struct { + CustomerNumber string `json:"customernumber"` + APIKey string `json:"apikey"` + APISessionID string `json:"apisessionid"` + ClientRequestID string `json:"clientrequestid,omitempty"` +} + +// UpdateDNSRecordsRequest as specified in netcup WSDL +// https://ccp.netcup.net/run/webservice/servers/endpoint.php#updateDnsRecords +type UpdateDNSRecordsRequest struct { + DomainName string `json:"domainname"` + CustomerNumber string `json:"customernumber"` + APIKey string `json:"apikey"` + APISessionID string `json:"apisessionid"` + ClientRequestID string `json:"clientrequestid,omitempty"` + DNSRecordSet DNSRecordSet `json:"dnsrecordset"` +} + +// DNSRecordSet as specified in netcup WSDL +// needed in UpdateDNSRecordsRequest +// https://ccp.netcup.net/run/webservice/servers/endpoint.php#Dnsrecordset +type DNSRecordSet struct { + DNSRecords []DNSRecord `json:"dnsrecords"` +} + +// InfoDNSRecordsRequest as specified in netcup WSDL +// https://ccp.netcup.net/run/webservice/servers/endpoint.php#infoDnsRecords +type InfoDNSRecordsRequest struct { + DomainName string `json:"domainname"` + CustomerNumber string `json:"customernumber"` + APIKey string `json:"apikey"` + APISessionID string `json:"apisessionid"` + ClientRequestID string `json:"clientrequestid,omitempty"` +} + +// DNSRecord as specified in netcup WSDL +// https://ccp.netcup.net/run/webservice/servers/endpoint.php#Dnsrecord +type DNSRecord struct { + ID int `json:"id,string,omitempty"` + Hostname string `json:"hostname"` + RecordType string `json:"type"` + Priority string `json:"priority,omitempty"` + Destination string `json:"destination"` + DeleteRecord bool `json:"deleterecord,omitempty"` + State string `json:"state,omitempty"` + TTL int `json:"ttl,omitempty"` +} + +// ResponseMsg as specified in netcup WSDL +// https://ccp.netcup.net/run/webservice/servers/endpoint.php#Responsemessage +type ResponseMsg struct { + ServerRequestID string `json:"serverrequestid"` + ClientRequestID string `json:"clientrequestid,omitempty"` + Action string `json:"action"` + Status string `json:"status"` + StatusCode int `json:"statuscode"` + ShortMessage string `json:"shortmessage"` + LongMessage string `json:"longmessage"` + ResponseData json.RawMessage `json:"responsedata,omitempty"` +} + +func (r *ResponseMsg) Error() string { + return fmt.Sprintf("an error occurred during the action %s: [Status=%s, StatusCode=%d, ShortMessage=%s, LongMessage=%s]", + r.Action, r.Status, r.StatusCode, r.ShortMessage, r.LongMessage) +} + +// LoginResponse response to login action. +type LoginResponse struct { + APISessionID string `json:"apisessionid"` +} + +// InfoDNSRecordsResponse response to infoDnsRecords action. +type InfoDNSRecordsResponse struct { + APISessionID string `json:"apisessionid"` + DNSRecords []DNSRecord `json:"dnsrecords,omitempty"` +} + +// Client netcup DNS client +type Client struct { + customerNumber string + apiKey string + apiPassword string + HTTPClient *http.Client + BaseURL string +} + +// NewClient creates a netcup DNS client +func NewClient(customerNumber string, apiKey string, apiPassword string) (*Client, error) { + if customerNumber == "" || apiKey == "" || apiPassword == "" { + return nil, fmt.Errorf("credentials missing") + } + + return &Client{ + customerNumber: customerNumber, + apiKey: apiKey, + apiPassword: apiPassword, + BaseURL: defaultBaseURL, + HTTPClient: &http.Client{ + Timeout: 10 * time.Second, + }, + }, nil +} + +// Login performs the login as specified by the netcup WSDL +// returns sessionID needed to perform remaining actions +// https://ccp.netcup.net/run/webservice/servers/endpoint.php +func (c *Client) Login() (string, error) { + payload := &Request{ + Action: "login", + Param: &LoginRequest{ + CustomerNumber: c.customerNumber, + APIKey: c.apiKey, + APIPassword: c.apiPassword, + ClientRequestID: "", + }, + } + + var responseData LoginResponse + err := c.doRequest(payload, &responseData) + if err != nil { + return "", fmt.Errorf("loging error: %v", err) + } + + return responseData.APISessionID, nil +} + +// Logout performs the logout with the supplied sessionID as specified by the netcup WSDL +// https://ccp.netcup.net/run/webservice/servers/endpoint.php +func (c *Client) Logout(sessionID string) error { + payload := &Request{ + Action: "logout", + Param: &LogoutRequest{ + CustomerNumber: c.customerNumber, + APIKey: c.apiKey, + APISessionID: sessionID, + ClientRequestID: "", + }, + } + + err := c.doRequest(payload, nil) + if err != nil { + return fmt.Errorf("logout error: %v", err) + } + + return nil +} + +// UpdateDNSRecord performs an update of the DNSRecords as specified by the netcup WSDL +// https://ccp.netcup.net/run/webservice/servers/endpoint.php +func (c *Client) UpdateDNSRecord(sessionID, domainName string, records []DNSRecord) error { + payload := &Request{ + Action: "updateDnsRecords", + Param: UpdateDNSRecordsRequest{ + DomainName: domainName, + CustomerNumber: c.customerNumber, + APIKey: c.apiKey, + APISessionID: sessionID, + ClientRequestID: "", + DNSRecordSet: DNSRecordSet{DNSRecords: records}, + }, + } + + err := c.doRequest(payload, nil) + if err != nil { + return fmt.Errorf("error when sending the request: %v", err) + } + + return nil +} + +// GetDNSRecords retrieves all dns records of an DNS-Zone as specified by the netcup WSDL +// returns an array of DNSRecords +// https://ccp.netcup.net/run/webservice/servers/endpoint.php +func (c *Client) GetDNSRecords(hostname, apiSessionID string) ([]DNSRecord, error) { + payload := &Request{ + Action: "infoDnsRecords", + Param: InfoDNSRecordsRequest{ + DomainName: hostname, + CustomerNumber: c.customerNumber, + APIKey: c.apiKey, + APISessionID: apiSessionID, + ClientRequestID: "", + }, + } + + var responseData InfoDNSRecordsResponse + err := c.doRequest(payload, &responseData) + if err != nil { + return nil, fmt.Errorf("error when sending the request: %v", err) + } + + return responseData.DNSRecords, nil + +} + +// doRequest marshals given body to JSON, send the request to netcup API +// and returns body of response +func (c *Client) doRequest(payload interface{}, responseData interface{}) error { + body, err := json.Marshal(payload) + if err != nil { + return err + } + + req, err := http.NewRequest(http.MethodPost, c.BaseURL, bytes.NewReader(body)) + if err != nil { + return err + } + + req.Close = true + req.Header.Set("content-type", "application/json") + + resp, err := c.HTTPClient.Do(req) + if err != nil { + return err + } + + if err = checkResponse(resp); err != nil { + return err + } + + respMsg, err := decodeResponseMsg(resp) + if err != nil { + return err + } + + if respMsg.Status != success { + return respMsg + } + + if responseData != nil { + err = json.Unmarshal(respMsg.ResponseData, responseData) + if err != nil { + return fmt.Errorf("%v: unmarshaling %T error: %v: %s", + respMsg, responseData, err, string(respMsg.ResponseData)) + } + } + + return nil +} + +func checkResponse(resp *http.Response) error { + if resp.StatusCode > 299 { + if resp.Body == nil { + return fmt.Errorf("response body is nil, status code=%d", resp.StatusCode) + } + + defer resp.Body.Close() + + raw, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("unable to read body: status code=%d, error=%v", resp.StatusCode, err) + } + + return fmt.Errorf("status code=%d: %s", resp.StatusCode, string(raw)) + } + + return nil +} + +func decodeResponseMsg(resp *http.Response) (*ResponseMsg, error) { + if resp.Body == nil { + return nil, fmt.Errorf("response body is nil, status code=%d", resp.StatusCode) + } + + defer resp.Body.Close() + + raw, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("unable to read body: status code=%d, error=%v", resp.StatusCode, err) + } + + var respMsg ResponseMsg + err = json.Unmarshal(raw, &respMsg) + if err != nil { + return nil, fmt.Errorf("unmarshaling %T error [status code=%d]: %v: %s", respMsg, resp.StatusCode, err, string(raw)) + } + + return &respMsg, nil +} + +// GetDNSRecordIdx searches a given array of DNSRecords for a given DNSRecord +// equivalence is determined by Destination and RecortType attributes +// returns index of given DNSRecord in given array of DNSRecords +func GetDNSRecordIdx(records []DNSRecord, record DNSRecord) (int, error) { + for index, element := range records { + if record.Destination == element.Destination && record.RecordType == element.RecordType { + return index, nil + } + } + return -1, fmt.Errorf("no DNS Record found") +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/netcup.go b/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/netcup.go new file mode 100644 index 000000000..e0b46f899 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/netcup.go @@ -0,0 +1,182 @@ +// Package netcup implements a DNS Provider for solving the DNS-01 challenge using the netcup DNS API. +package netcup + +import ( + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/go-acme/lego/v3/providers/dns/netcup/internal" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Key string + Password string + Customer string + TTL int + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("NETCUP_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("NETCUP_PROPAGATION_TIMEOUT", 120*time.Second), + PollingInterval: env.GetOrDefaultSecond("NETCUP_POLLING_INTERVAL", 5*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("NETCUP_HTTP_TIMEOUT", 10*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + client *internal.Client + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for netcup. +// Credentials must be passed in the environment variables: +// NETCUP_CUSTOMER_NUMBER, NETCUP_API_KEY, NETCUP_API_PASSWORD +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("NETCUP_CUSTOMER_NUMBER", "NETCUP_API_KEY", "NETCUP_API_PASSWORD") + if err != nil { + return nil, fmt.Errorf("netcup: %v", err) + } + + config := NewDefaultConfig() + config.Customer = values["NETCUP_CUSTOMER_NUMBER"] + config.Key = values["NETCUP_API_KEY"] + config.Password = values["NETCUP_API_PASSWORD"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for netcup. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("netcup: the configuration of the DNS provider is nil") + } + + client, err := internal.NewClient(config.Customer, config.Key, config.Password) + if err != nil { + return nil, fmt.Errorf("netcup: %v", err) + } + + client.HTTPClient = config.HTTPClient + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domainName, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domainName, keyAuth) + + zone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("netcup: failed to find DNSZone, %v", err) + } + + sessionID, err := d.client.Login() + if err != nil { + return fmt.Errorf("netcup: %v", err) + } + + defer func() { + err = d.client.Logout(sessionID) + if err != nil { + log.Print("netcup: %v", err) + } + }() + + hostname := strings.Replace(fqdn, "."+zone, "", 1) + record := internal.DNSRecord{ + Hostname: hostname, + RecordType: "TXT", + Destination: value, + TTL: d.config.TTL, + } + + zone = dns01.UnFqdn(zone) + + records, err := d.client.GetDNSRecords(zone, sessionID) + if err != nil { + // skip no existing records + log.Infof("no existing records, error ignored: %v", err) + } + + records = append(records, record) + + err = d.client.UpdateDNSRecord(sessionID, zone, records) + if err != nil { + return fmt.Errorf("netcup: failed to add TXT-Record: %v", err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domainName, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domainName, keyAuth) + + zone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("netcup: failed to find DNSZone, %v", err) + } + + sessionID, err := d.client.Login() + if err != nil { + return fmt.Errorf("netcup: %v", err) + } + + defer func() { + err = d.client.Logout(sessionID) + if err != nil { + log.Print("netcup: %v", err) + } + }() + + hostname := strings.Replace(fqdn, "."+zone, "", 1) + + zone = dns01.UnFqdn(zone) + + records, err := d.client.GetDNSRecords(zone, sessionID) + if err != nil { + return fmt.Errorf("netcup: %v", err) + } + + record := internal.DNSRecord{ + Hostname: hostname, + RecordType: "TXT", + Destination: value, + } + + idx, err := internal.GetDNSRecordIdx(records, record) + if err != nil { + return fmt.Errorf("netcup: %v", err) + } + + records[idx].DeleteRecord = true + + err = d.client.UpdateDNSRecord(sessionID, zone, []internal.DNSRecord{records[idx]}) + if err != nil { + return fmt.Errorf("netcup: %v", err) + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/netcup.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/netcup.toml new file mode 100644 index 000000000..992e868a0 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/netcup/netcup.toml @@ -0,0 +1,21 @@ +Name = "Netcup" +Description = '''''' +URL = "https://www.netcup.eu/" +Code = "netcup" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + NETCUP_CUSTOMER_NUMBER = "Customer number" + NETCUP_API_KEY = "API key" + NETCUP_API_PASSWORD = "API password" + [Configuration.Additional] + NETCUP_POLLING_INTERVAL = "Time between DNS propagation check" + NETCUP_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + NETCUP_TTL = "The TTL of the TXT record used for the DNS challenge" + NETCUP_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.netcup-wiki.de/wiki/DNS_API" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/internal/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/internal/client.go new file mode 100644 index 000000000..a2eb8a763 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/internal/client.go @@ -0,0 +1,234 @@ +package internal + +import ( + "bytes" + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "encoding/xml" + "errors" + "fmt" + "net/http" + "time" +) + +const ( + defaultBaseURL = "https://dns.api.nifcloud.com" + apiVersion = "2012-12-12N2013-12-16" + // XMLNs XML NS of Route53 + XMLNs = "https://route53.amazonaws.com/doc/2012-12-12/" +) + +// ChangeResourceRecordSetsRequest is a complex type that contains change information for the resource record set. +type ChangeResourceRecordSetsRequest struct { + XMLNs string `xml:"xmlns,attr"` + ChangeBatch ChangeBatch `xml:"ChangeBatch"` +} + +// ChangeResourceRecordSetsResponse is a complex type containing the response for the request. +type ChangeResourceRecordSetsResponse struct { + ChangeInfo ChangeInfo `xml:"ChangeInfo"` +} + +// GetChangeResponse is a complex type that contains the ChangeInfo element. +type GetChangeResponse struct { + ChangeInfo ChangeInfo `xml:"ChangeInfo"` +} + +// ErrorResponse is the information for any errors. +type ErrorResponse struct { + Error struct { + Type string `xml:"Type"` + Message string `xml:"Message"` + Code string `xml:"Code"` + } `xml:"Error"` + RequestID string `xml:"RequestId"` +} + +// ChangeBatch is the information for a change request. +type ChangeBatch struct { + Changes Changes `xml:"Changes"` + Comment string `xml:"Comment"` +} + +// Changes is array of Change. +type Changes struct { + Change []Change `xml:"Change"` +} + +// Change is the information for each resource record set that you want to change. +type Change struct { + Action string `xml:"Action"` + ResourceRecordSet ResourceRecordSet `xml:"ResourceRecordSet"` +} + +// ResourceRecordSet is the information about the resource record set to create or delete. +type ResourceRecordSet struct { + Name string `xml:"Name"` + Type string `xml:"Type"` + TTL int `xml:"TTL"` + ResourceRecords ResourceRecords `xml:"ResourceRecords"` +} + +// ResourceRecords is array of ResourceRecord. +type ResourceRecords struct { + ResourceRecord []ResourceRecord `xml:"ResourceRecord"` +} + +// ResourceRecord is the information specific to the resource record. +type ResourceRecord struct { + Value string `xml:"Value"` +} + +// ChangeInfo is A complex type that describes change information about changes made to your hosted zone. +type ChangeInfo struct { + ID string `xml:"Id"` + Status string `xml:"Status"` + SubmittedAt string `xml:"SubmittedAt"` +} + +// NewClient Creates a new client of NIFCLOUD DNS +func NewClient(accessKey string, secretKey string) (*Client, error) { + if len(accessKey) == 0 || len(secretKey) == 0 { + return nil, errors.New("credentials missing") + } + + return &Client{ + accessKey: accessKey, + secretKey: secretKey, + BaseURL: defaultBaseURL, + HTTPClient: &http.Client{}, + }, nil +} + +// Client client of NIFCLOUD DNS +type Client struct { + accessKey string + secretKey string + BaseURL string + HTTPClient *http.Client +} + +// ChangeResourceRecordSets Call ChangeResourceRecordSets API and return response. +func (c *Client) ChangeResourceRecordSets(hostedZoneID string, input ChangeResourceRecordSetsRequest) (*ChangeResourceRecordSetsResponse, error) { + requestURL := fmt.Sprintf("%s/%s/hostedzone/%s/rrset", c.BaseURL, apiVersion, hostedZoneID) + + body := &bytes.Buffer{} + body.Write([]byte(xml.Header)) + err := xml.NewEncoder(body).Encode(input) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, requestURL, body) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "text/xml; charset=utf-8") + + err = c.sign(req) + if err != nil { + return nil, fmt.Errorf("an error occurred during the creation of the signature: %v", err) + } + + res, err := c.HTTPClient.Do(req) + if err != nil { + return nil, err + } + if res.Body == nil { + return nil, errors.New("the response body is nil") + } + + defer res.Body.Close() + + if res.StatusCode != http.StatusOK { + errResp := &ErrorResponse{} + err = xml.NewDecoder(res.Body).Decode(errResp) + if err != nil { + return nil, fmt.Errorf("an error occurred while unmarshaling the error body to XML: %v", err) + } + + return nil, fmt.Errorf("an error occurred: %s", errResp.Error.Message) + } + + output := &ChangeResourceRecordSetsResponse{} + err = xml.NewDecoder(res.Body).Decode(output) + if err != nil { + return nil, fmt.Errorf("an error occurred while unmarshaling the response body to XML: %v", err) + } + + return output, err +} + +// GetChange Call GetChange API and return response. +func (c *Client) GetChange(statusID string) (*GetChangeResponse, error) { + requestURL := fmt.Sprintf("%s/%s/change/%s", c.BaseURL, apiVersion, statusID) + + req, err := http.NewRequest(http.MethodGet, requestURL, nil) + if err != nil { + return nil, err + } + + err = c.sign(req) + if err != nil { + return nil, fmt.Errorf("an error occurred during the creation of the signature: %v", err) + } + + res, err := c.HTTPClient.Do(req) + if err != nil { + return nil, err + } + if res.Body == nil { + return nil, errors.New("the response body is nil") + } + + defer res.Body.Close() + + if res.StatusCode != http.StatusOK { + errResp := &ErrorResponse{} + err = xml.NewDecoder(res.Body).Decode(errResp) + if err != nil { + return nil, fmt.Errorf("an error occurred while unmarshaling the error body to XML: %v", err) + } + + return nil, fmt.Errorf("an error occurred: %s", errResp.Error.Message) + } + + output := &GetChangeResponse{} + err = xml.NewDecoder(res.Body).Decode(output) + if err != nil { + return nil, fmt.Errorf("an error occurred while unmarshaling the response body to XML: %v", err) + } + + return output, nil +} + +func (c *Client) sign(req *http.Request) error { + if req.Header.Get("Date") == "" { + location, err := time.LoadLocation("GMT") + if err != nil { + return err + } + + req.Header.Set("Date", time.Now().In(location).Format(time.RFC1123)) + } + + if req.URL.Path == "" { + req.URL.Path += "/" + } + + mac := hmac.New(sha1.New, []byte(c.secretKey)) + _, err := mac.Write([]byte(req.Header.Get("Date"))) + if err != nil { + return err + } + + hashed := mac.Sum(nil) + signature := base64.StdEncoding.EncodeToString(hashed) + + auth := fmt.Sprintf("NIFTY3-HTTPS NiftyAccessKeyId=%s,Algorithm=HmacSHA1,Signature=%s", c.accessKey, signature) + req.Header.Set("X-Nifty-Authorization", auth) + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/nifcloud.go b/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/nifcloud.go new file mode 100644 index 000000000..154725b12 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/nifcloud.go @@ -0,0 +1,156 @@ +// Package nifcloud implements a DNS provider for solving the DNS-01 challenge using NIFCLOUD DNS. +package nifcloud + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/providers/dns/nifcloud/internal" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/go-acme/lego/v3/platform/wait" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + AccessKey string + SecretKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("NIFCLOUD_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("NIFCLOUD_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("NIFCLOUD_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("NIFCLOUD_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider implements the acme.ChallengeProvider interface +type DNSProvider struct { + client *internal.Client + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for the NIFCLOUD DNS service. +// Credentials must be passed in the environment variables: +// NIFCLOUD_ACCESS_KEY_ID and NIFCLOUD_SECRET_ACCESS_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("NIFCLOUD_ACCESS_KEY_ID", "NIFCLOUD_SECRET_ACCESS_KEY") + if err != nil { + return nil, fmt.Errorf("nifcloud: %v", err) + } + + config := NewDefaultConfig() + config.BaseURL = env.GetOrFile("NIFCLOUD_DNS_ENDPOINT") + config.AccessKey = values["NIFCLOUD_ACCESS_KEY_ID"] + config.SecretKey = values["NIFCLOUD_SECRET_ACCESS_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for NIFCLOUD. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("nifcloud: the configuration of the DNS provider is nil") + } + + client, err := internal.NewClient(config.AccessKey, config.SecretKey) + if err != nil { + return nil, fmt.Errorf("nifcloud: %v", err) + } + + if config.HTTPClient != nil { + client.HTTPClient = config.HTTPClient + } + + if len(config.BaseURL) > 0 { + client.BaseURL = config.BaseURL + } + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + err := d.changeRecord("CREATE", fqdn, value, domain, d.config.TTL) + if err != nil { + return fmt.Errorf("nifcloud: %v", err) + } + return err +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + err := d.changeRecord("DELETE", fqdn, value, domain, d.config.TTL) + if err != nil { + return fmt.Errorf("nifcloud: %v", err) + } + return err +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) changeRecord(action, fqdn, value, domain string, ttl int) error { + name := dns01.UnFqdn(fqdn) + + reqParams := internal.ChangeResourceRecordSetsRequest{ + XMLNs: internal.XMLNs, + ChangeBatch: internal.ChangeBatch{ + Comment: "Managed by Lego", + Changes: internal.Changes{ + Change: []internal.Change{ + { + Action: action, + ResourceRecordSet: internal.ResourceRecordSet{ + Name: name, + Type: "TXT", + TTL: ttl, + ResourceRecords: internal.ResourceRecords{ + ResourceRecord: []internal.ResourceRecord{ + { + Value: value, + }, + }, + }, + }, + }, + }, + }, + }, + } + + resp, err := d.client.ChangeResourceRecordSets(domain, reqParams) + if err != nil { + return fmt.Errorf("failed to change NIFCLOUD record set: %v", err) + } + + statusID := resp.ChangeInfo.ID + + return wait.For("nifcloud", 120*time.Second, 4*time.Second, func() (bool, error) { + resp, err := d.client.GetChange(statusID) + if err != nil { + return false, fmt.Errorf("failed to query NIFCLOUD DNS change status: %v", err) + } + return resp.ChangeInfo.Status == "INSYNC", nil + }) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/nifcloud.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/nifcloud.toml new file mode 100644 index 000000000..9394cc8e6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/nifcloud/nifcloud.toml @@ -0,0 +1,20 @@ +Name = "NIFCloud" +Description = '''''' +URL = "https://www.nifcloud.com/" +Code = "nifcloud" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + NIFCLOUD_ACCESS_KEY_ID = "Access key" + NIFCLOUD_SECRET_ACCESS_KEY = "Secret access key" + [Configuration.Additional] + NIFCLOUD_POLLING_INTERVAL = "Time between DNS propagation check" + NIFCLOUD_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + NIFCLOUD_TTL = "The TTL of the TXT record used for the DNS challenge" + NIFCLOUD_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://mbaas.nifcloud.com/doc/current/rest/common/format.html" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/ns1/ns1.go b/vendor/github.com/go-acme/lego/v3/providers/dns/ns1/ns1.go new file mode 100644 index 000000000..f80643248 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/ns1/ns1.go @@ -0,0 +1,162 @@ +// Package ns1 implements a DNS provider for solving the DNS-01 challenge using NS1 DNS. +package ns1 + +import ( + "errors" + "fmt" + "net/http" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" + "gopkg.in/ns1/ns1-go.v2/rest" + "gopkg.in/ns1/ns1-go.v2/rest/model/dns" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("NS1_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("NS1_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("NS1_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("NS1_HTTP_TIMEOUT", 10*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + client *rest.Client + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for NS1. +// Credentials must be passed in the environment variables: NS1_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("NS1_API_KEY") + if err != nil { + return nil, fmt.Errorf("ns1: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["NS1_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for NS1. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("ns1: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + return nil, fmt.Errorf("ns1: credentials missing") + } + + client := rest.NewClient(config.HTTPClient, rest.SetAPIKey(config.APIKey)) + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZone(fqdn) + if err != nil { + return fmt.Errorf("ns1: %v", err) + } + + record, _, err := d.client.Records.Get(zone.Zone, dns01.UnFqdn(fqdn), "TXT") + + // Create a new record + if err == rest.ErrRecordMissing || record == nil { + log.Infof("Create a new record for [zone: %s, fqdn: %s, domain: %s]", zone.Zone, fqdn) + + record = dns.NewRecord(zone.Zone, dns01.UnFqdn(fqdn), "TXT") + record.TTL = d.config.TTL + record.Answers = []*dns.Answer{{Rdata: []string{value}}} + + _, err = d.client.Records.Create(record) + if err != nil { + return fmt.Errorf("ns1: failed to create record [zone: %q, fqdn: %q]: %v", zone.Zone, fqdn, err) + } + + return nil + } + + if err != nil { + return fmt.Errorf("ns1: failed to get the existing record: %v", err) + } + + // Update the existing records + record.Answers = append(record.Answers, &dns.Answer{Rdata: []string{value}}) + + log.Infof("Update an existing record for [zone: %s, fqdn: %s, domain: %s]", zone.Zone, fqdn, domain) + + _, err = d.client.Records.Update(record) + if err != nil { + return fmt.Errorf("ns1: failed to update record [zone: %q, fqdn: %q]: %v", zone.Zone, fqdn, err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZone(fqdn) + if err != nil { + return fmt.Errorf("ns1: %v", err) + } + + name := dns01.UnFqdn(fqdn) + _, err = d.client.Records.Delete(zone.Zone, name, "TXT") + if err != nil { + return fmt.Errorf("ns1: failed to delete record [zone: %q, domain: %q]: %v", zone.Zone, name, err) + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) getHostedZone(fqdn string) (*dns.Zone, error) { + authZone, err := getAuthZone(fqdn) + if err != nil { + return nil, fmt.Errorf("failed to extract auth zone from fqdn %q: %v", fqdn, err) + } + + zone, _, err := d.client.Zones.Get(authZone) + if err != nil { + return nil, fmt.Errorf("failed to get zone [authZone: %q, fqdn: %q]: %v", authZone, fqdn, err) + } + + return zone, nil +} + +func getAuthZone(fqdn string) (string, error) { + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return "", err + } + + return strings.TrimSuffix(authZone, "."), nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/ns1/ns1.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/ns1/ns1.toml new file mode 100644 index 000000000..94200cf34 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/ns1/ns1.toml @@ -0,0 +1,20 @@ +Name = "NS1" +Description = '''''' +URL = "https://ns1.com" +Code = "ns1" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + NS1_API_KEY = "API key" + [Configuration.Additional] + NS1_POLLING_INTERVAL = "Time between DNS propagation check" + NS1_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + NS1_TTL = "The TTL of the TXT record used for the DNS challenge" + NS1_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://ns1.com/api" + GoClient = "https://github.com/ns1/ns1-go" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/configprovider.go b/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/configprovider.go new file mode 100644 index 000000000..a0eecf8b6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/configprovider.go @@ -0,0 +1,101 @@ +package oraclecloud + +import ( + "crypto/rsa" + "encoding/base64" + "fmt" + "io/ioutil" + "os" + + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/oracle/oci-go-sdk/common" +) + +const ( + ociPrivkey = "OCI_PRIVKEY" + ociPrivkeyPass = "OCI_PRIVKEY_PASS" + ociTenancyOCID = "OCI_TENANCY_OCID" + ociUserOCID = "OCI_USER_OCID" + ociPubkeyFingerprint = "OCI_PUBKEY_FINGERPRINT" + ociRegion = "OCI_REGION" +) + +type configProvider struct { + values map[string]string + privateKeyPassphrase string +} + +func newConfigProvider(values map[string]string) *configProvider { + return &configProvider{ + values: values, + privateKeyPassphrase: env.GetOrFile(ociPrivkeyPass), + } +} + +func (p *configProvider) PrivateRSAKey() (*rsa.PrivateKey, error) { + privateKey, err := getPrivateKey(ociPrivkey) + if err != nil { + return nil, err + } + + return common.PrivateKeyFromBytes(privateKey, common.String(p.privateKeyPassphrase)) +} + +func (p *configProvider) KeyID() (string, error) { + tenancy, err := p.TenancyOCID() + if err != nil { + return "", err + } + + user, err := p.UserOCID() + if err != nil { + return "", err + } + + fingerprint, err := p.KeyFingerprint() + if err != nil { + return "", err + } + + return fmt.Sprintf("%s/%s/%s", tenancy, user, fingerprint), nil +} + +func (p *configProvider) TenancyOCID() (value string, err error) { + return p.values[ociTenancyOCID], nil +} + +func (p *configProvider) UserOCID() (string, error) { + return p.values[ociUserOCID], nil +} + +func (p *configProvider) KeyFingerprint() (string, error) { + return p.values[ociPubkeyFingerprint], nil +} + +func (p *configProvider) Region() (string, error) { + return p.values[ociRegion], nil +} + +func getPrivateKey(envVar string) ([]byte, error) { + envVarValue := os.Getenv(envVar) + if envVarValue != "" { + bytes, err := base64.StdEncoding.DecodeString(envVarValue) + if err != nil { + return nil, fmt.Errorf("failed to read base64 value %s (defined by env var %s): %s", envVarValue, envVar, err) + } + return bytes, nil + } + + fileVar := envVar + "_FILE" + fileVarValue := os.Getenv(fileVar) + if fileVarValue == "" { + return nil, fmt.Errorf("no value provided for: %s or %s", envVar, fileVar) + } + + fileContents, err := ioutil.ReadFile(fileVarValue) + if err != nil { + return nil, fmt.Errorf("failed to read the file %s (defined by env var %s): %s", fileVarValue, fileVar, err) + } + + return fileContents, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/oraclecloud.go b/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/oraclecloud.go new file mode 100644 index 000000000..716211ed3 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/oraclecloud.go @@ -0,0 +1,175 @@ +package oraclecloud + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/oracle/oci-go-sdk/common" + "github.com/oracle/oci-go-sdk/dns" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + CompartmentID string + OCIConfigProvider common.ConfigurationProvider + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("OCI_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("OCI_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("OCI_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("OCI_HTTP_TIMEOUT", 60*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + client *dns.DnsClient + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for OracleCloud. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get(ociPrivkey, ociTenancyOCID, ociUserOCID, ociPubkeyFingerprint, ociRegion, "OCI_COMPARTMENT_OCID") + if err != nil { + return nil, fmt.Errorf("oraclecloud: %v", err) + } + + config := NewDefaultConfig() + config.CompartmentID = values["OCI_COMPARTMENT_OCID"] + config.OCIConfigProvider = newConfigProvider(values) + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for OracleCloud. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("oraclecloud: the configuration of the DNS provider is nil") + } + + if config.CompartmentID == "" { + return nil, errors.New("oraclecloud: CompartmentID is missing") + } + + if config.OCIConfigProvider == nil { + return nil, errors.New("oraclecloud: OCIConfigProvider is missing") + } + + client, err := dns.NewDnsClientWithConfigurationProvider(config.OCIConfigProvider) + if err != nil { + return nil, fmt.Errorf("oraclecloud: %v", err) + } + + if config.HTTPClient != nil { + client.HTTPClient = config.HTTPClient + } + + return &DNSProvider{client: &client, config: config}, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + // generate request to dns.PatchDomainRecordsRequest + recordOperation := dns.RecordOperation{ + Domain: common.String(dns01.UnFqdn(fqdn)), + Rdata: common.String(value), + Rtype: common.String("TXT"), + Ttl: common.Int(d.config.TTL), + IsProtected: common.Bool(false), + } + + request := dns.PatchDomainRecordsRequest{ + CompartmentId: common.String(d.config.CompartmentID), + ZoneNameOrId: common.String(domain), + Domain: common.String(dns01.UnFqdn(fqdn)), + PatchDomainRecordsDetails: dns.PatchDomainRecordsDetails{ + Items: []dns.RecordOperation{recordOperation}, + }, + } + + _, err := d.client.PatchDomainRecords(context.Background(), request) + if err != nil { + return fmt.Errorf("oraclecloud: %v", err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + // search to TXT record's hash to delete + getRequest := dns.GetDomainRecordsRequest{ + ZoneNameOrId: common.String(domain), + Domain: common.String(dns01.UnFqdn(fqdn)), + CompartmentId: common.String(d.config.CompartmentID), + Rtype: common.String("TXT"), + } + + ctx := context.Background() + + domainRecords, err := d.client.GetDomainRecords(ctx, getRequest) + if err != nil { + return fmt.Errorf("oraclecloud: %v", err) + } + + if *domainRecords.OpcTotalItems == 0 { + return fmt.Errorf("oraclecloud: no record to CleanUp") + } + + var deleteHash *string + for _, record := range domainRecords.RecordCollection.Items { + if record.Rdata != nil && *record.Rdata == `"`+value+`"` { + deleteHash = record.RecordHash + break + } + } + + if deleteHash == nil { + return fmt.Errorf("oraclecloud: no record to CleanUp") + } + + recordOperation := dns.RecordOperation{ + RecordHash: deleteHash, + Operation: dns.RecordOperationOperationRemove, + } + + patchRequest := dns.PatchDomainRecordsRequest{ + ZoneNameOrId: common.String(domain), + Domain: common.String(dns01.UnFqdn(fqdn)), + PatchDomainRecordsDetails: dns.PatchDomainRecordsDetails{ + Items: []dns.RecordOperation{recordOperation}, + }, + CompartmentId: common.String(d.config.CompartmentID), + } + + _, err = d.client.PatchDomainRecords(ctx, patchRequest) + if err != nil { + return fmt.Errorf("oraclecloud: %v", err) + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/oraclecloud.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/oraclecloud.toml new file mode 100644 index 000000000..b97ca8523 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/oraclecloud/oraclecloud.toml @@ -0,0 +1,35 @@ +Name = "Oracle Cloud" +Description = '''''' +URL = "https://cloud.oracle.com/home" +Code = "oraclecloud" +Since = "v2.3.0" + +Example = ''' +OCI_PRIVKEY_FILE="~/.oci/oci_api_key.pem" \ +OCI_PRIVKEY_PASS="secret" \ +OCI_TENANCY_OCID="ocid1.tenancy.oc1..secret" \ +OCI_USER_OCID="ocid1.user.oc1..secret" \ +OCI_PUBKEY_FINGERPRINT="00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00" \ +OCI_REGION="us-phoenix-1" \ +OCI_COMPARTMENT_OCID="ocid1.tenancy.oc1..secret" \ +lego --dns oraclecloud --domains my.domain.com --email my@email.com run +''' + +[Configuration] + [Configuration.Credentials] + OCI_PRIVKEY_FILE = "Private key file" + OCI_PRIVKEY_PASS = "Private key password" + OCI_TENANCY_OCID = "Tenanct OCID" + OCI_USER_OCID = "User OCID" + OCI_PUBKEY_FINGERPRINT = "Public key fingerprint" + OCI_REGION = "Region" + OCI_COMPARTMENT_OCID = "Compartment OCID" + [Configuration.Additional] + OCI_POLLING_INTERVAL = "Time between DNS propagation check" + OCI_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + OCI_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://docs.cloud.oracle.com/iaas/Content/DNS/Concepts/dnszonemanagement.htm" + GoClient = "https://github.com/oracle/oci-go-sdk" + diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/otc/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/otc/client.go new file mode 100644 index 000000000..fa4c5edc5 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/otc/client.go @@ -0,0 +1,267 @@ +package otc + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" +) + +type recordset struct { + Name string `json:"name"` + Description string `json:"description"` + Type string `json:"type"` + TTL int `json:"ttl"` + Records []string `json:"records"` +} + +type nameResponse struct { + Name string `json:"name"` +} + +type userResponse struct { + Name string `json:"name"` + Password string `json:"password"` + Domain nameResponse `json:"domain"` +} + +type passwordResponse struct { + User userResponse `json:"user"` +} + +type identityResponse struct { + Methods []string `json:"methods"` + Password passwordResponse `json:"password"` +} + +type scopeResponse struct { + Project nameResponse `json:"project"` +} + +type authResponse struct { + Identity identityResponse `json:"identity"` + Scope scopeResponse `json:"scope"` +} + +type loginResponse struct { + Auth authResponse `json:"auth"` +} + +type endpointResponse struct { + Token token `json:"token"` +} + +type token struct { + Catalog []catalog `json:"catalog"` +} + +type catalog struct { + Type string `json:"type"` + Endpoints []endpoint `json:"endpoints"` +} + +type endpoint struct { + URL string `json:"url"` +} + +type zoneItem struct { + ID string `json:"id"` +} + +type zonesResponse struct { + Zones []zoneItem `json:"zones"` +} + +type recordSet struct { + ID string `json:"id"` +} + +type recordSetsResponse struct { + RecordSets []recordSet `json:"recordsets"` +} + +// Starts a new OTC API Session. Authenticates using userName, password +// and receives a token to be used in for subsequent requests. +func (d *DNSProvider) login() error { + return d.loginRequest() +} + +func (d *DNSProvider) loginRequest() error { + userResp := userResponse{ + Name: d.config.UserName, + Password: d.config.Password, + Domain: nameResponse{ + Name: d.config.DomainName, + }, + } + + loginResp := loginResponse{ + Auth: authResponse{ + Identity: identityResponse{ + Methods: []string{"password"}, + Password: passwordResponse{ + User: userResp, + }, + }, + Scope: scopeResponse{ + Project: nameResponse{ + Name: d.config.ProjectName, + }, + }, + }, + } + + body, err := json.Marshal(loginResp) + if err != nil { + return err + } + + req, err := http.NewRequest(http.MethodPost, d.config.IdentityEndpoint, bytes.NewReader(body)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{Timeout: d.config.HTTPClient.Timeout} + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode >= 400 { + return fmt.Errorf("OTC API request failed with HTTP status code %d", resp.StatusCode) + } + + d.token = resp.Header.Get("X-Subject-Token") + + if d.token == "" { + return fmt.Errorf("unable to get auth token") + } + + var endpointResp endpointResponse + + err = json.NewDecoder(resp.Body).Decode(&endpointResp) + if err != nil { + return err + } + + var endpoints []endpoint + for _, v := range endpointResp.Token.Catalog { + if v.Type == "dns" { + endpoints = append(endpoints, v.Endpoints...) + } + } + + if len(endpoints) > 0 { + d.baseURL = fmt.Sprintf("%s/v2", endpoints[0].URL) + } else { + return fmt.Errorf("unable to get dns endpoint") + } + + return nil +} + +func (d *DNSProvider) getZoneID(zone string) (string, error) { + resource := fmt.Sprintf("zones?name=%s", zone) + resp, err := d.sendRequest(http.MethodGet, resource, nil) + if err != nil { + return "", err + } + + var zonesRes zonesResponse + err = json.NewDecoder(resp).Decode(&zonesRes) + if err != nil { + return "", err + } + + if len(zonesRes.Zones) < 1 { + return "", fmt.Errorf("zone %s not found", zone) + } + + if len(zonesRes.Zones) > 1 { + return "", fmt.Errorf("to many zones found") + } + + if zonesRes.Zones[0].ID == "" { + return "", fmt.Errorf("id not found") + } + + return zonesRes.Zones[0].ID, nil +} + +func (d *DNSProvider) getRecordSetID(zoneID string, fqdn string) (string, error) { + resource := fmt.Sprintf("zones/%s/recordsets?type=TXT&name=%s", zoneID, fqdn) + resp, err := d.sendRequest(http.MethodGet, resource, nil) + if err != nil { + return "", err + } + + var recordSetsRes recordSetsResponse + err = json.NewDecoder(resp).Decode(&recordSetsRes) + if err != nil { + return "", err + } + + if len(recordSetsRes.RecordSets) < 1 { + return "", fmt.Errorf("record not found") + } + + if len(recordSetsRes.RecordSets) > 1 { + return "", fmt.Errorf("to many records found") + } + + if recordSetsRes.RecordSets[0].ID == "" { + return "", fmt.Errorf("id not found") + } + + return recordSetsRes.RecordSets[0].ID, nil +} + +func (d *DNSProvider) deleteRecordSet(zoneID, recordID string) error { + resource := fmt.Sprintf("zones/%s/recordsets/%s", zoneID, recordID) + + _, err := d.sendRequest(http.MethodDelete, resource, nil) + return err +} + +func (d *DNSProvider) sendRequest(method, resource string, payload interface{}) (io.Reader, error) { + url := fmt.Sprintf("%s/%s", d.baseURL, resource) + + var body io.Reader + if payload != nil { + content, err := json.Marshal(payload) + if err != nil { + return nil, err + } + body = bytes.NewReader(content) + } + + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + if len(d.token) > 0 { + req.Header.Set("X-Auth-Token", d.token) + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode >= 400 { + return nil, fmt.Errorf("OTC API request %s failed with HTTP status code %d", url, resp.StatusCode) + } + + body1, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return bytes.NewReader(body1), nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/otc/otc.go b/vendor/github.com/go-acme/lego/v3/providers/dns/otc/otc.go new file mode 100644 index 000000000..184de7964 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/otc/otc.go @@ -0,0 +1,179 @@ +// Package otc implements a DNS provider for solving the DNS-01 challenge using Open Telekom Cloud Managed DNS. +package otc + +import ( + "errors" + "fmt" + "net" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +const defaultIdentityEndpoint = "https://iam.eu-de.otc.t-systems.com:443/v3/auth/tokens" + +// minTTL 300 is otc minimum value for ttl +const minTTL = 300 + +// Config is used to configure the creation of the DNSProvider +type Config struct { + IdentityEndpoint string + DomainName string + ProjectName string + UserName string + Password string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + IdentityEndpoint: env.GetOrDefaultString("OTC_IDENTITY_ENDPOINT", defaultIdentityEndpoint), + PropagationTimeout: env.GetOrDefaultSecond("OTC_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("OTC_POLLING_INTERVAL", dns01.DefaultPollingInterval), + TTL: env.GetOrDefaultInt("OTC_TTL", minTTL), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("OTC_HTTP_TIMEOUT", 10*time.Second), + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + + // Workaround for keep alive bug in otc api + DisableKeepAlives: true, + }, + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface that uses +// OTC's Managed DNS API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + baseURL string + token string +} + +// NewDNSProvider returns a DNSProvider instance configured for OTC DNS. +// Credentials must be passed in the environment variables: OTC_USER_NAME, +// OTC_DOMAIN_NAME, OTC_PASSWORD OTC_PROJECT_NAME and OTC_IDENTITY_ENDPOINT. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("OTC_DOMAIN_NAME", "OTC_USER_NAME", "OTC_PASSWORD", "OTC_PROJECT_NAME") + if err != nil { + return nil, fmt.Errorf("otc: %v", err) + } + + config := NewDefaultConfig() + config.DomainName = values["OTC_DOMAIN_NAME"] + config.UserName = values["OTC_USER_NAME"] + config.Password = values["OTC_PASSWORD"] + config.ProjectName = values["OTC_PROJECT_NAME"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for OTC DNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("otc: the configuration of the DNS provider is nil") + } + + if config.DomainName == "" || config.UserName == "" || config.Password == "" || config.ProjectName == "" { + return nil, fmt.Errorf("otc: credentials missing") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("otc: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + if config.IdentityEndpoint == "" { + config.IdentityEndpoint = defaultIdentityEndpoint + } + + return &DNSProvider{config: config}, nil +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("otc: %v", err) + } + + err = d.login() + if err != nil { + return fmt.Errorf("otc: %v", err) + } + + zoneID, err := d.getZoneID(authZone) + if err != nil { + return fmt.Errorf("otc: unable to get zone: %s", err) + } + + resource := fmt.Sprintf("zones/%s/recordsets", zoneID) + + r1 := &recordset{ + Name: fqdn, + Description: "Added TXT record for ACME dns-01 challenge using lego client", + Type: "TXT", + TTL: d.config.TTL, + Records: []string{fmt.Sprintf("\"%s\"", value)}, + } + + _, err = d.sendRequest(http.MethodPost, resource, r1) + if err != nil { + return fmt.Errorf("otc: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("otc: %v", err) + } + + err = d.login() + if err != nil { + return fmt.Errorf("otc: %v", err) + } + + zoneID, err := d.getZoneID(authZone) + if err != nil { + return fmt.Errorf("otc: %v", err) + } + + recordID, err := d.getRecordSetID(zoneID, fqdn) + if err != nil { + return fmt.Errorf("otc: unable go get record %s for zone %s: %s", fqdn, domain, err) + } + + err = d.deleteRecordSet(zoneID, recordID) + if err != nil { + return fmt.Errorf("otc: %v", err) + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/otc/otc.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/otc/otc.toml new file mode 100644 index 000000000..d60aa3fc3 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/otc/otc.toml @@ -0,0 +1,24 @@ +Name = "Open Telekom Cloud" +Description = '''''' +URL = "https://cloud.telekom.de/en" +Code = "otc" +Since = "v0.4.1" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + OTC_USER_NAME = "User name" + OTC_PASSWORD = "Password" + OTC_PROJECT_NAME = "Project name" + OTC_DOMAIN_NAME = "Domain name" + OTC_IDENTITY_ENDPOINT = "Identity endpoint URL" + [Configuration.Additional] + OTC_POLLING_INTERVAL = "Time between DNS propagation check" + OTC_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + OTC_TTL = "The TTL of the TXT record used for the DNS challenge" + OTC_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://docs.otc.t-systems.com/en-us/dns/index.html" + diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/ovh/ovh.go b/vendor/github.com/go-acme/lego/v3/providers/dns/ovh/ovh.go new file mode 100644 index 000000000..c4c4b704e --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/ovh/ovh.go @@ -0,0 +1,203 @@ +// Package ovh implements a DNS provider for solving the DNS-01 challenge using OVH DNS. +package ovh + +import ( + "errors" + "fmt" + "net/http" + "strings" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/ovh/go-ovh/ovh" +) + +// OVH API reference: https://eu.api.ovh.com/ +// Create a Token: https://eu.api.ovh.com/createToken/ + +// Record a DNS record +type Record struct { + ID int `json:"id,omitempty"` + FieldType string `json:"fieldType,omitempty"` + SubDomain string `json:"subDomain,omitempty"` + Target string `json:"target,omitempty"` + TTL int `json:"ttl,omitempty"` + Zone string `json:"zone,omitempty"` +} + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIEndpoint string + ApplicationKey string + ApplicationSecret string + ConsumerKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("OVH_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("OVH_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("OVH_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("OVH_HTTP_TIMEOUT", ovh.DefaultTimeout), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +// that uses OVH's REST API to manage TXT records for a domain. +type DNSProvider struct { + config *Config + client *ovh.Client + recordIDs map[string]int + recordIDsMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance configured for OVH +// Credentials must be passed in the environment variable: +// OVH_ENDPOINT : it must be ovh-eu or ovh-ca +// OVH_APPLICATION_KEY +// OVH_APPLICATION_SECRET +// OVH_CONSUMER_KEY +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("OVH_ENDPOINT", "OVH_APPLICATION_KEY", "OVH_APPLICATION_SECRET", "OVH_CONSUMER_KEY") + if err != nil { + return nil, fmt.Errorf("ovh: %v", err) + } + + config := NewDefaultConfig() + config.APIEndpoint = values["OVH_ENDPOINT"] + config.ApplicationKey = values["OVH_APPLICATION_KEY"] + config.ApplicationSecret = values["OVH_APPLICATION_SECRET"] + config.ConsumerKey = values["OVH_CONSUMER_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for OVH. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("ovh: the configuration of the DNS provider is nil") + } + + if config.APIEndpoint == "" || config.ApplicationKey == "" || config.ApplicationSecret == "" || config.ConsumerKey == "" { + return nil, fmt.Errorf("ovh: credentials missing") + } + + client, err := ovh.NewClient( + config.APIEndpoint, + config.ApplicationKey, + config.ApplicationSecret, + config.ConsumerKey, + ) + if err != nil { + return nil, fmt.Errorf("ovh: %v", err) + } + + client.Client = config.HTTPClient + + return &DNSProvider{ + config: config, + client: client, + recordIDs: make(map[string]int), + }, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + // Parse domain name + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return fmt.Errorf("ovh: could not determine zone for domain: '%s'. %s", domain, err) + } + + authZone = dns01.UnFqdn(authZone) + subDomain := d.extractRecordName(fqdn, authZone) + + reqURL := fmt.Sprintf("/domain/zone/%s/record", authZone) + reqData := Record{FieldType: "TXT", SubDomain: subDomain, Target: value, TTL: d.config.TTL} + + // Create TXT record + var respData Record + err = d.client.Post(reqURL, reqData, &respData) + if err != nil { + return fmt.Errorf("ovh: error when call api to add record (%s): %v", reqURL, err) + } + + // Apply the change + reqURL = fmt.Sprintf("/domain/zone/%s/refresh", authZone) + err = d.client.Post(reqURL, nil, nil) + if err != nil { + return fmt.Errorf("ovh: error when call api to refresh zone (%s): %v", reqURL, err) + } + + d.recordIDsMu.Lock() + d.recordIDs[fqdn] = respData.ID + d.recordIDsMu.Unlock() + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + // get the record's unique ID from when we created it + d.recordIDsMu.Lock() + recordID, ok := d.recordIDs[fqdn] + d.recordIDsMu.Unlock() + if !ok { + return fmt.Errorf("ovh: unknown record ID for '%s'", fqdn) + } + + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return fmt.Errorf("ovh: could not determine zone for domain: '%s'. %s", domain, err) + } + + authZone = dns01.UnFqdn(authZone) + + reqURL := fmt.Sprintf("/domain/zone/%s/record/%d", authZone, recordID) + + err = d.client.Delete(reqURL, nil) + if err != nil { + return fmt.Errorf("ovh: error when call OVH api to delete challenge record (%s): %v", reqURL, err) + } + + // Apply the change + reqURL = fmt.Sprintf("/domain/zone/%s/refresh", authZone) + err = d.client.Post(reqURL, nil, nil) + if err != nil { + return fmt.Errorf("ovh: error when call api to refresh zone (%s): %v", reqURL, err) + } + + // Delete record ID from map + d.recordIDsMu.Lock() + delete(d.recordIDs, fqdn) + d.recordIDsMu.Unlock() + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/ovh/ovh.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/ovh/ovh.toml new file mode 100644 index 000000000..46ba81ba3 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/ovh/ovh.toml @@ -0,0 +1,23 @@ +Name = "OVH" +Description = '''''' +URL = "https://www.ovh.com/" +Code = "ovh" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + OVH_ENDPOINT = "Endpoint URL (ovh-eu or ovh-ca)" + OVH_APPLICATION_KEY = "Application key" + OVH_APPLICATION_SECRET = "Application secret" + OVH_CONSUMER_KEY = "Consumer key" + [Configuration.Additional] + OVH_POLLING_INTERVAL = "Time between DNS propagation check" + OVH_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + OVH_TTL = "The TTL of the TXT record used for the DNS challenge" + OVH_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://eu.api.ovh.com/" + GoClient = "https://github.com/ovh/go-ovh" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/client.go new file mode 100644 index 000000000..c075bdde3 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/client.go @@ -0,0 +1,220 @@ +package pdns + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "strconv" + "strings" + + "github.com/go-acme/lego/v3/challenge/dns01" +) + +type Record struct { + Content string `json:"content"` + Disabled bool `json:"disabled"` + + // pre-v1 API + Name string `json:"name"` + Type string `json:"type"` + TTL int `json:"ttl,omitempty"` +} + +type hostedZone struct { + ID string `json:"id"` + Name string `json:"name"` + URL string `json:"url"` + RRSets []rrSet `json:"rrsets"` + + // pre-v1 API + Records []Record `json:"records"` +} + +type rrSet struct { + Name string `json:"name"` + Type string `json:"type"` + Kind string `json:"kind"` + ChangeType string `json:"changetype"` + Records []Record `json:"records"` + TTL int `json:"ttl,omitempty"` +} + +type rrSets struct { + RRSets []rrSet `json:"rrsets"` +} + +type apiError struct { + ShortMsg string `json:"error"` +} + +func (a apiError) Error() string { + return a.ShortMsg +} + +type apiVersion struct { + URL string `json:"url"` + Version int `json:"version"` +} + +func (d *DNSProvider) getHostedZone(fqdn string) (*hostedZone, error) { + var zone hostedZone + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return nil, err + } + + u := "/servers/localhost/zones" + result, err := d.sendRequest(http.MethodGet, u, nil) + if err != nil { + return nil, err + } + + var zones []hostedZone + err = json.Unmarshal(result, &zones) + if err != nil { + return nil, err + } + + u = "" + for _, zone := range zones { + if dns01.UnFqdn(zone.Name) == dns01.UnFqdn(authZone) { + u = zone.URL + break + } + } + + result, err = d.sendRequest(http.MethodGet, u, nil) + if err != nil { + return nil, err + } + + err = json.Unmarshal(result, &zone) + if err != nil { + return nil, err + } + + // convert pre-v1 API result + if len(zone.Records) > 0 { + zone.RRSets = []rrSet{} + for _, record := range zone.Records { + set := rrSet{ + Name: record.Name, + Type: record.Type, + Records: []Record{record}, + } + zone.RRSets = append(zone.RRSets, set) + } + } + + return &zone, nil +} + +func (d *DNSProvider) findTxtRecord(fqdn string) (*rrSet, error) { + zone, err := d.getHostedZone(fqdn) + if err != nil { + return nil, err + } + + _, err = d.sendRequest(http.MethodGet, zone.URL, nil) + if err != nil { + return nil, err + } + + for _, set := range zone.RRSets { + if (set.Name == dns01.UnFqdn(fqdn) || set.Name == fqdn) && set.Type == "TXT" { + return &set, nil + } + } + + return nil, nil +} + +func (d *DNSProvider) getAPIVersion() (int, error) { + result, err := d.sendRequest(http.MethodGet, "/api", nil) + if err != nil { + return 0, err + } + + var versions []apiVersion + err = json.Unmarshal(result, &versions) + if err != nil { + return 0, err + } + + latestVersion := 0 + for _, v := range versions { + if v.Version > latestVersion { + latestVersion = v.Version + } + } + + return latestVersion, err +} + +func (d *DNSProvider) sendRequest(method, uri string, body io.Reader) (json.RawMessage, error) { + req, err := d.makeRequest(method, uri, body) + if err != nil { + return nil, err + } + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return nil, fmt.Errorf("error talking to PDNS API -> %v", err) + } + + defer resp.Body.Close() + + if resp.StatusCode != http.StatusUnprocessableEntity && (resp.StatusCode < 200 || resp.StatusCode >= 300) { + return nil, fmt.Errorf("unexpected HTTP status code %d when fetching '%s'", resp.StatusCode, req.URL) + } + + var msg json.RawMessage + err = json.NewDecoder(resp.Body).Decode(&msg) + if err != nil { + if err == io.EOF { + // empty body + return nil, nil + } + // other error + return nil, err + } + + // check for PowerDNS error message + if len(msg) > 0 && msg[0] == '{' { + var errInfo apiError + err = json.Unmarshal(msg, &errInfo) + if err != nil { + return nil, err + } + if errInfo.ShortMsg != "" { + return nil, fmt.Errorf("error talking to PDNS API -> %v", errInfo) + } + } + return msg, nil +} + +func (d *DNSProvider) makeRequest(method, uri string, body io.Reader) (*http.Request, error) { + var path = "" + if d.config.Host.Path != "/" { + path = d.config.Host.Path + } + + if !strings.HasPrefix(uri, "/") { + uri = "/" + uri + } + + if d.apiVersion > 0 && !strings.HasPrefix(uri, "/api/v") { + uri = "/api/v" + strconv.Itoa(d.apiVersion) + uri + } + + u := d.config.Host.Scheme + "://" + d.config.Host.Host + path + uri + req, err := http.NewRequest(method, u, body) + if err != nil { + return nil, err + } + + req.Header.Set("X-API-Key", d.config.APIKey) + + return req, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/pdns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/pdns.go new file mode 100644 index 000000000..60bc42bc7 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/pdns.go @@ -0,0 +1,198 @@ +// Package pdns implements a DNS provider for solving the DNS-01 challenge using PowerDNS nameserver. +package pdns + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + Host *url.URL + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("PDNS_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("PDNS_PROPAGATION_TIMEOUT", 120*time.Second), + PollingInterval: env.GetOrDefaultSecond("PDNS_POLLING_INTERVAL", 2*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("PDNS_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +type DNSProvider struct { + apiVersion int + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for pdns. +// Credentials must be passed in the environment variable: +// PDNS_API_URL and PDNS_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("PDNS_API_KEY", "PDNS_API_URL") + if err != nil { + return nil, fmt.Errorf("pdns: %v", err) + } + + hostURL, err := url.Parse(values["PDNS_API_URL"]) + if err != nil { + return nil, fmt.Errorf("pdns: %v", err) + } + + config := NewDefaultConfig() + config.Host = hostURL + config.APIKey = values["PDNS_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for pdns. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("pdns: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + return nil, fmt.Errorf("pdns: API key missing") + } + + if config.Host == nil || config.Host.Host == "" { + return nil, fmt.Errorf("pdns: API URL missing") + } + + d := &DNSProvider{config: config} + + apiVersion, err := d.getAPIVersion() + if err != nil { + log.Warnf("pdns: failed to get API version %v", err) + } + d.apiVersion = apiVersion + + return d, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS +// propagation. Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZone(fqdn) + if err != nil { + return fmt.Errorf("pdns: %v", err) + } + + name := fqdn + + // pre-v1 API wants non-fqdn + if d.apiVersion == 0 { + name = dns01.UnFqdn(fqdn) + } + + rec := Record{ + Content: "\"" + value + "\"", + Disabled: false, + + // pre-v1 API + Type: "TXT", + Name: name, + TTL: d.config.TTL, + } + + // Look for existing records. + existingRrSet, err := d.findTxtRecord(fqdn) + if err != nil { + return fmt.Errorf("pdns: %v", err) + } + + // merge the existing and new records + var records []Record + if existingRrSet != nil { + records = existingRrSet.Records + } + records = append(records, rec) + + rrsets := rrSets{ + RRSets: []rrSet{ + { + Name: name, + ChangeType: "REPLACE", + Type: "TXT", + Kind: "Master", + TTL: d.config.TTL, + Records: records, + }, + }, + } + + body, err := json.Marshal(rrsets) + if err != nil { + return fmt.Errorf("pdns: %v", err) + } + + _, err = d.sendRequest(http.MethodPatch, zone.URL, bytes.NewReader(body)) + if err != nil { + return fmt.Errorf("pdns: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zone, err := d.getHostedZone(fqdn) + if err != nil { + return fmt.Errorf("pdns: %v", err) + } + + set, err := d.findTxtRecord(fqdn) + if err != nil { + return fmt.Errorf("pdns: %v", err) + } + if set == nil { + return fmt.Errorf("pdns: no existing record found for %s", fqdn) + } + + rrsets := rrSets{ + RRSets: []rrSet{ + { + Name: set.Name, + Type: set.Type, + ChangeType: "DELETE", + }, + }, + } + body, err := json.Marshal(rrsets) + if err != nil { + return fmt.Errorf("pdns: %v", err) + } + + _, err = d.sendRequest(http.MethodPatch, zone.URL, bytes.NewReader(body)) + if err != nil { + return fmt.Errorf("pdns: %v", err) + } + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/pdns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/pdns.toml new file mode 100644 index 000000000..f6b8370ae --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/pdns/pdns.toml @@ -0,0 +1,30 @@ +Name = "PowerDNS" +Description = '''''' +URL = "https://www.powerdns.com/" +Code = "pdns" +Since = "v0.4.0" + +Example = '''''' + +Additional = ''' +## Information + +Tested and confirmed to work with PowerDNS authoritative server 3.4.8 and 4.0.1. Refer to [PowerDNS documentation](https://doc.powerdns.com/md/httpapi/README/) instructions on how to enable the built-in API interface. + +PowerDNS Notes: +- PowerDNS API does not currently support SSL, therefore you should take care to ensure that traffic between lego and the PowerDNS API is over a trusted network, VPN etc. +- In order to have the SOA serial automatically increment each time the `_acme-challenge` record is added/modified via the API, set `SOA-EDIT-API` to `INCEPTION-INCREMENT` for the zone in the `domainmetadata` table +''' + +[Configuration] + [Configuration.Credentials] + PDNS_API_KEY = "API key" + PDNS_API_URL = "API url" + [Configuration.Additional] + PDNS_POLLING_INTERVAL = "Time between DNS propagation check" + PDNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + PDNS_TTL = "The TTL of the TXT record used for the DNS challenge" + PDNS_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://doc.powerdns.com/md/httpapi/README/" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/client.go new file mode 100644 index 000000000..c664c309c --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/client.go @@ -0,0 +1,205 @@ +package rackspace + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + + "github.com/go-acme/lego/v3/challenge/dns01" +) + +// APIKeyCredentials API credential +type APIKeyCredentials struct { + Username string `json:"username"` + APIKey string `json:"apiKey"` +} + +// Auth auth credentials +type Auth struct { + APIKeyCredentials `json:"RAX-KSKEY:apiKeyCredentials"` +} + +// AuthData Auth data +type AuthData struct { + Auth `json:"auth"` +} + +// Identity Identity +type Identity struct { + Access Access `json:"access"` +} + +// Access Access +type Access struct { + ServiceCatalog []ServiceCatalog `json:"serviceCatalog"` + Token Token `json:"token"` +} + +// Token Token +type Token struct { + ID string `json:"id"` +} + +// ServiceCatalog ServiceCatalog +type ServiceCatalog struct { + Endpoints []Endpoint `json:"endpoints"` + Name string `json:"name"` +} + +// Endpoint Endpoint +type Endpoint struct { + PublicURL string `json:"publicURL"` + TenantID string `json:"tenantId"` +} + +// ZoneSearchResponse represents the response when querying Rackspace DNS zones +type ZoneSearchResponse struct { + TotalEntries int `json:"totalEntries"` + HostedZones []HostedZone `json:"domains"` +} + +// HostedZone HostedZone +type HostedZone struct { + ID int `json:"id"` + Name string `json:"name"` +} + +// Records is the list of records sent/received from the DNS API +type Records struct { + Record []Record `json:"records"` +} + +// Record represents a Rackspace DNS record +type Record struct { + Name string `json:"name"` + Type string `json:"type"` + Data string `json:"data"` + TTL int `json:"ttl,omitempty"` + ID string `json:"id,omitempty"` +} + +// getHostedZoneID performs a lookup to get the DNS zone which needs +// modifying for a given FQDN +func (d *DNSProvider) getHostedZoneID(fqdn string) (int, error) { + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return 0, err + } + + result, err := d.makeRequest(http.MethodGet, fmt.Sprintf("/domains?name=%s", dns01.UnFqdn(authZone)), nil) + if err != nil { + return 0, err + } + + var zoneSearchResponse ZoneSearchResponse + err = json.Unmarshal(result, &zoneSearchResponse) + if err != nil { + return 0, err + } + + // If nothing was returned, or for whatever reason more than 1 was returned (the search uses exact match, so should not occur) + if zoneSearchResponse.TotalEntries != 1 { + return 0, fmt.Errorf("found %d zones for %s in Rackspace for domain %s", zoneSearchResponse.TotalEntries, authZone, fqdn) + } + + return zoneSearchResponse.HostedZones[0].ID, nil +} + +// findTxtRecord searches a DNS zone for a TXT record with a specific name +func (d *DNSProvider) findTxtRecord(fqdn string, zoneID int) (*Record, error) { + result, err := d.makeRequest(http.MethodGet, fmt.Sprintf("/domains/%d/records?type=TXT&name=%s", zoneID, dns01.UnFqdn(fqdn)), nil) + if err != nil { + return nil, err + } + + var records Records + err = json.Unmarshal(result, &records) + if err != nil { + return nil, err + } + + switch len(records.Record) { + case 1: + case 0: + return nil, fmt.Errorf("no TXT record found for %s", fqdn) + default: + return nil, fmt.Errorf("more than 1 TXT record found for %s", fqdn) + } + + return &records.Record[0], nil +} + +// makeRequest is a wrapper function used for making DNS API requests +func (d *DNSProvider) makeRequest(method, uri string, body io.Reader) (json.RawMessage, error) { + url := d.cloudDNSEndpoint + uri + + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + + req.Header.Set("X-Auth-Token", d.token) + req.Header.Set("Content-Type", "application/json") + + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return nil, fmt.Errorf("error querying DNS API: %v", err) + } + + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted { + return nil, fmt.Errorf("request failed for %s %s. Response code: %d", method, url, resp.StatusCode) + } + + var r json.RawMessage + err = json.NewDecoder(resp.Body).Decode(&r) + if err != nil { + return nil, fmt.Errorf("JSON decode failed for %s %s. Response code: %d", method, url, resp.StatusCode) + } + + return r, nil +} + +func login(config *Config) (*Identity, error) { + authData := AuthData{ + Auth: Auth{ + APIKeyCredentials: APIKeyCredentials{ + Username: config.APIUser, + APIKey: config.APIKey, + }, + }, + } + + body, err := json.Marshal(authData) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, config.BaseURL, bytes.NewReader(body)) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + + resp, err := config.HTTPClient.Do(req) + if err != nil { + return nil, fmt.Errorf("error querying Identity API: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("authentication failed: response code: %d", resp.StatusCode) + } + + var identity Identity + err = json.NewDecoder(resp.Body).Decode(&identity) + if err != nil { + return nil, err + } + + return &identity, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/rackspace.go b/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/rackspace.go new file mode 100644 index 000000000..fa1950e8b --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/rackspace.go @@ -0,0 +1,159 @@ +// Package rackspace implements a DNS provider for solving the DNS-01 challenge using rackspace DNS. +package rackspace + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// defaultBaseURL represents the Identity API endpoint to call +const defaultBaseURL = "https://identity.api.rackspacecloud.com/v2.0/tokens" + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + APIUser string + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + BaseURL: defaultBaseURL, + TTL: env.GetOrDefaultInt("RACKSPACE_TTL", 300), + PropagationTimeout: env.GetOrDefaultSecond("RACKSPACE_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("RACKSPACE_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("RACKSPACE_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface +// used to store the reusable token and DNS API endpoint +type DNSProvider struct { + config *Config + token string + cloudDNSEndpoint string +} + +// NewDNSProvider returns a DNSProvider instance configured for Rackspace. +// Credentials must be passed in the environment variables: +// RACKSPACE_USER and RACKSPACE_API_KEY. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("RACKSPACE_USER", "RACKSPACE_API_KEY") + if err != nil { + return nil, fmt.Errorf("rackspace: %v", err) + } + + config := NewDefaultConfig() + config.APIUser = values["RACKSPACE_USER"] + config.APIKey = values["RACKSPACE_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Rackspace. +// It authenticates against the API, also grabbing the DNS Endpoint. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("rackspace: the configuration of the DNS provider is nil") + } + + if config.APIUser == "" || config.APIKey == "" { + return nil, fmt.Errorf("rackspace: credentials missing") + } + + identity, err := login(config) + if err != nil { + return nil, fmt.Errorf("rackspace: %v", err) + } + + // Iterate through the Service Catalog to get the DNS Endpoint + var dnsEndpoint string + for _, service := range identity.Access.ServiceCatalog { + if service.Name == "cloudDNS" { + dnsEndpoint = service.Endpoints[0].PublicURL + break + } + } + + if dnsEndpoint == "" { + return nil, fmt.Errorf("rackspace: failed to populate DNS endpoint, check Rackspace API for changes") + } + + return &DNSProvider{ + config: config, + token: identity.Access.Token.ID, + cloudDNSEndpoint: dnsEndpoint, + }, nil + +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zoneID, err := d.getHostedZoneID(fqdn) + if err != nil { + return fmt.Errorf("rackspace: %v", err) + } + + rec := Records{ + Record: []Record{{ + Name: dns01.UnFqdn(fqdn), + Type: "TXT", + Data: value, + TTL: d.config.TTL, + }}, + } + + body, err := json.Marshal(rec) + if err != nil { + return fmt.Errorf("rackspace: %v", err) + } + + _, err = d.makeRequest(http.MethodPost, fmt.Sprintf("/domains/%d/records", zoneID), bytes.NewReader(body)) + if err != nil { + return fmt.Errorf("rackspace: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zoneID, err := d.getHostedZoneID(fqdn) + if err != nil { + return fmt.Errorf("rackspace: %v", err) + } + + record, err := d.findTxtRecord(fqdn, zoneID) + if err != nil { + return fmt.Errorf("rackspace: %v", err) + } + + _, err = d.makeRequest(http.MethodDelete, fmt.Sprintf("/domains/%d/records?id=%s", zoneID, record.ID), nil) + if err != nil { + return fmt.Errorf("rackspace: %v", err) + } + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/rackspace.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/rackspace.toml new file mode 100644 index 000000000..5688ddb92 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/rackspace/rackspace.toml @@ -0,0 +1,20 @@ +Name = "Rackspace" +Description = '''''' +URL = "https://www.rackspace.com/" +Code = "rackspace" +Since = "v0.4.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + RACKSPACE_USER = "API user" + RACKSPACE_API_KEY = "API key" + [Configuration.Additional] + RACKSPACE_POLLING_INTERVAL = "Time between DNS propagation check" + RACKSPACE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + RACKSPACE_TTL = "The TTL of the TXT record used for the DNS challenge" + RACKSPACE_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://developer.rackspace.com/docs/cloud-dns/v1/" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/rfc2136/rfc2136.go b/vendor/github.com/go-acme/lego/v3/providers/dns/rfc2136/rfc2136.go new file mode 100644 index 000000000..4ed00352a --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/rfc2136/rfc2136.go @@ -0,0 +1,183 @@ +// Package rfc2136 implements a DNS provider for solving the DNS-01 challenge using the rfc2136 dynamic update. +package rfc2136 + +import ( + "errors" + "fmt" + "net" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/miekg/dns" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Nameserver string + TSIGAlgorithm string + TSIGKey string + TSIGSecret string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + SequenceInterval time.Duration + DNSTimeout time.Duration +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TSIGAlgorithm: env.GetOrDefaultString("RFC2136_TSIG_ALGORITHM", dns.HmacMD5), + TTL: env.GetOrDefaultInt("RFC2136_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("RFC2136_PROPAGATION_TIMEOUT", env.GetOrDefaultSecond("RFC2136_TIMEOUT", 60*time.Second)), + PollingInterval: env.GetOrDefaultSecond("RFC2136_POLLING_INTERVAL", 2*time.Second), + SequenceInterval: env.GetOrDefaultSecond("RFC2136_SEQUENCE_INTERVAL", dns01.DefaultPropagationTimeout), + DNSTimeout: env.GetOrDefaultSecond("RFC2136_DNS_TIMEOUT", 10*time.Second), + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface that +// uses dynamic DNS updates (RFC 2136) to create TXT records on a nameserver. +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for rfc2136 +// dynamic update. Configured with environment variables: +// RFC2136_NAMESERVER: Network address in the form "host" or "host:port". +// RFC2136_TSIG_ALGORITHM: Defaults to hmac-md5.sig-alg.reg.int. (HMAC-MD5). +// See https://github.com/miekg/dns/blob/master/tsig.go for supported values. +// RFC2136_TSIG_KEY: Name of the secret key as defined in DNS server configuration. +// RFC2136_TSIG_SECRET: Secret key payload. +// RFC2136_PROPAGATION_TIMEOUT: DNS propagation timeout in time.ParseDuration format. (60s) +// To disable TSIG authentication, leave the RFC2136_TSIG* variables unset. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("RFC2136_NAMESERVER") + if err != nil { + return nil, fmt.Errorf("rfc2136: %v", err) + } + + config := NewDefaultConfig() + config.Nameserver = values["RFC2136_NAMESERVER"] + config.TSIGKey = env.GetOrFile("RFC2136_TSIG_KEY") + config.TSIGSecret = env.GetOrFile("RFC2136_TSIG_SECRET") + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for rfc2136. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("rfc2136: the configuration of the DNS provider is nil") + } + + if config.Nameserver == "" { + return nil, fmt.Errorf("rfc2136: nameserver missing") + } + + if config.TSIGAlgorithm == "" { + config.TSIGAlgorithm = dns.HmacMD5 + } + + // Append the default DNS port if none is specified. + if _, _, err := net.SplitHostPort(config.Nameserver); err != nil { + if strings.Contains(err.Error(), "missing port") { + config.Nameserver = net.JoinHostPort(config.Nameserver, "53") + } else { + return nil, fmt.Errorf("rfc2136: %v", err) + } + } + + if len(config.TSIGKey) == 0 && len(config.TSIGSecret) > 0 || + len(config.TSIGKey) > 0 && len(config.TSIGSecret) == 0 { + config.TSIGKey = "" + config.TSIGSecret = "" + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Sequential All DNS challenges for this provider will be resolved sequentially. +// Returns the interval between each iteration. +func (d *DNSProvider) Sequential() time.Duration { + return d.config.SequenceInterval +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + err := d.changeRecord("INSERT", fqdn, value, d.config.TTL) + if err != nil { + return fmt.Errorf("rfc2136: failed to insert: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + err := d.changeRecord("REMOVE", fqdn, value, d.config.TTL) + if err != nil { + return fmt.Errorf("rfc2136: failed to remove: %v", err) + } + return nil +} + +func (d *DNSProvider) changeRecord(action, fqdn, value string, ttl int) error { + // Find the zone for the given fqdn + zone, err := dns01.FindZoneByFqdnCustom(fqdn, []string{d.config.Nameserver}) + if err != nil { + return err + } + + // Create RR + rr := new(dns.TXT) + rr.Hdr = dns.RR_Header{Name: fqdn, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: uint32(ttl)} + rr.Txt = []string{value} + rrs := []dns.RR{rr} + + // Create dynamic update packet + m := new(dns.Msg) + m.SetUpdate(zone) + switch action { + case "INSERT": + // Always remove old challenge left over from who knows what. + m.RemoveRRset(rrs) + m.Insert(rrs) + case "REMOVE": + m.Remove(rrs) + default: + return fmt.Errorf("unexpected action: %s", action) + } + + // Setup client + c := &dns.Client{Timeout: d.config.DNSTimeout} + c.SingleInflight = true + + // TSIG authentication / msg signing + if len(d.config.TSIGKey) > 0 && len(d.config.TSIGSecret) > 0 { + m.SetTsig(dns.Fqdn(d.config.TSIGKey), d.config.TSIGAlgorithm, 300, time.Now().Unix()) + c.TsigSecret = map[string]string{dns.Fqdn(d.config.TSIGKey): d.config.TSIGSecret} + } + + // Send the query + reply, _, err := c.Exchange(m, d.config.Nameserver) + if err != nil { + return fmt.Errorf("DNS update failed: %v", err) + } + if reply != nil && reply.Rcode != dns.RcodeSuccess { + return fmt.Errorf("DNS update failed: server replied: %s", dns.RcodeToString[reply.Rcode]) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/rfc2136/rfc2136.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/rfc2136/rfc2136.toml new file mode 100644 index 000000000..6e213c886 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/rfc2136/rfc2136.toml @@ -0,0 +1,23 @@ +Name = "RFC2136" +Description = '''''' +URL = "https://tools.ietf.org/html/rfc2136" +Code = "rfc2136" +Since = "v0.3.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + RFC2136_TSIG_KEY = "Name of the secret key as defined in DNS server configuration. To disable TSIG authentication, leave the `RFC2136_TSIG*` variables unset." + RFC2136_TSIG_SECRET = "Secret key payload. To disable TSIG authentication, leave the` RFC2136_TSIG*` variables unset." + RFC2136_TSIG_ALGORITHM = "TSIG algorythm. See [miekg/dns#tsig.go](https://github.com/miekg/dns/blob/master/tsig.go) for supported values. To disable TSIG authentication, leave the `RFC2136_TSIG*` variables unset." + RFC2136_NAMESERVER = 'Network address in the form "host" or "host:port"' + [Configuration.Additional] + RFC2136_POLLING_INTERVAL = "Time between DNS propagation check" + RFC2136_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + RFC2136_TTL = "The TTL of the TXT record used for the DNS challenge" + RFC2136_DNS_TIMEOUT = "API request timeout" + RFC2136_SEQUENCE_INTERVAL = "Interval between iteration" + +[Links] + API = "https://tools.ietf.org/html/rfc2136" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/route53/route53.go b/vendor/github.com/go-acme/lego/v3/providers/dns/route53/route53.go new file mode 100644 index 000000000..e8ffc680e --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/route53/route53.go @@ -0,0 +1,279 @@ +// Package route53 implements a DNS provider for solving the DNS-01 challenge using AWS Route 53 DNS. +package route53 + +import ( + "errors" + "fmt" + "math/rand" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/route53" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/go-acme/lego/v3/platform/wait" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + MaxRetries int + TTL int + PropagationTimeout time.Duration + PollingInterval time.Duration + HostedZoneID string +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + MaxRetries: env.GetOrDefaultInt("AWS_MAX_RETRIES", 5), + TTL: env.GetOrDefaultInt("AWS_TTL", 10), + PropagationTimeout: env.GetOrDefaultSecond("AWS_PROPAGATION_TIMEOUT", 2*time.Minute), + PollingInterval: env.GetOrDefaultSecond("AWS_POLLING_INTERVAL", 4*time.Second), + HostedZoneID: env.GetOrFile("AWS_HOSTED_ZONE_ID"), + } +} + +// DNSProvider implements the acme.ChallengeProvider interface +type DNSProvider struct { + client *route53.Route53 + config *Config +} + +// customRetryer implements the client.Retryer interface by composing the DefaultRetryer. +// It controls the logic for retrying recoverable request errors (e.g. when rate limits are exceeded). +type customRetryer struct { + client.DefaultRetryer +} + +// RetryRules overwrites the DefaultRetryer's method. +// It uses a basic exponential backoff algorithm: +// that returns an initial delay of ~400ms with an upper limit of ~30 seconds, +// which should prevent causing a high number of consecutive throttling errors. +// For reference: Route 53 enforces an account-wide(!) 5req/s query limit. +func (d customRetryer) RetryRules(r *request.Request) time.Duration { + retryCount := r.RetryCount + if retryCount > 7 { + retryCount = 7 + } + + delay := (1 << uint(retryCount)) * (rand.Intn(50) + 200) + return time.Duration(delay) * time.Millisecond +} + +// NewDNSProvider returns a DNSProvider instance configured for the AWS Route 53 service. +// +// AWS Credentials are automatically detected in the following locations and prioritized in the following order: +// 1. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, +// AWS_REGION, [AWS_SESSION_TOKEN] +// 2. Shared credentials file (defaults to ~/.aws/credentials) +// 3. Amazon EC2 IAM role +// +// If AWS_HOSTED_ZONE_ID is not set, Lego tries to determine the correct public hosted zone via the FQDN. +// +// See also: https://github.com/aws/aws-sdk-go/wiki/configuring-sdk +func NewDNSProvider() (*DNSProvider, error) { + return NewDNSProviderConfig(NewDefaultConfig()) +} + +// NewDNSProviderConfig takes a given config ans returns a custom configured DNSProvider instance +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("route53: the configuration of the Route53 DNS provider is nil") + } + + retry := customRetryer{} + retry.NumMaxRetries = config.MaxRetries + sessionCfg := request.WithRetryer(aws.NewConfig(), retry) + + sess, err := session.NewSessionWithOptions(session.Options{Config: *sessionCfg}) + if err != nil { + return nil, err + } + + cl := route53.New(sess) + return &DNSProvider{client: cl, config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS +// propagation. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record using the specified parameters +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + hostedZoneID, err := d.getHostedZoneID(fqdn) + if err != nil { + return fmt.Errorf("route53: failed to determine hosted zone ID: %v", err) + } + + records, err := d.getExistingRecordSets(hostedZoneID, fqdn) + if err != nil { + return fmt.Errorf("route53: %v", err) + } + + realValue := `"` + value + `"` + + var found bool + for _, record := range records { + if aws.StringValue(record.Value) == realValue { + found = true + } + } + + if !found { + records = append(records, &route53.ResourceRecord{Value: aws.String(realValue)}) + } + + recordSet := &route53.ResourceRecordSet{ + Name: aws.String(fqdn), + Type: aws.String("TXT"), + TTL: aws.Int64(int64(d.config.TTL)), + ResourceRecords: records, + } + + err = d.changeRecord(route53.ChangeActionUpsert, hostedZoneID, recordSet) + if err != nil { + return fmt.Errorf("route53: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + hostedZoneID, err := d.getHostedZoneID(fqdn) + if err != nil { + return fmt.Errorf("failed to determine Route 53 hosted zone ID: %v", err) + } + + records, err := d.getExistingRecordSets(hostedZoneID, fqdn) + if err != nil { + return fmt.Errorf("route53: %v", err) + } + + if len(records) == 0 { + return nil + } + + recordSet := &route53.ResourceRecordSet{ + Name: aws.String(fqdn), + Type: aws.String("TXT"), + TTL: aws.Int64(int64(d.config.TTL)), + ResourceRecords: records, + } + + err = d.changeRecord(route53.ChangeActionDelete, hostedZoneID, recordSet) + if err != nil { + return fmt.Errorf("route53: %v", err) + } + return nil +} + +func (d *DNSProvider) changeRecord(action, hostedZoneID string, recordSet *route53.ResourceRecordSet) error { + recordSetInput := &route53.ChangeResourceRecordSetsInput{ + HostedZoneId: aws.String(hostedZoneID), + ChangeBatch: &route53.ChangeBatch{ + Comment: aws.String("Managed by Lego"), + Changes: []*route53.Change{{ + Action: aws.String(action), + ResourceRecordSet: recordSet, + }}, + }, + } + + resp, err := d.client.ChangeResourceRecordSets(recordSetInput) + if err != nil { + return fmt.Errorf("failed to change record set: %v", err) + } + + changeID := resp.ChangeInfo.Id + + return wait.For("route53", d.config.PropagationTimeout, d.config.PollingInterval, func() (bool, error) { + reqParams := &route53.GetChangeInput{Id: changeID} + + resp, err := d.client.GetChange(reqParams) + if err != nil { + return false, fmt.Errorf("failed to query change status: %v", err) + } + + if aws.StringValue(resp.ChangeInfo.Status) == route53.ChangeStatusInsync { + return true, nil + } + return false, fmt.Errorf("unable to retrieve change: ID=%s", aws.StringValue(changeID)) + }) +} + +func (d *DNSProvider) getExistingRecordSets(hostedZoneID string, fqdn string) ([]*route53.ResourceRecord, error) { + listInput := &route53.ListResourceRecordSetsInput{ + HostedZoneId: aws.String(hostedZoneID), + StartRecordName: aws.String(fqdn), + StartRecordType: aws.String("TXT"), + } + + recordSetsOutput, err := d.client.ListResourceRecordSets(listInput) + if err != nil { + return nil, err + } + + if recordSetsOutput == nil { + return nil, nil + } + + var records []*route53.ResourceRecord + + for _, recordSet := range recordSetsOutput.ResourceRecordSets { + if aws.StringValue(recordSet.Name) == fqdn { + records = append(records, recordSet.ResourceRecords...) + } + } + + return records, nil +} + +func (d *DNSProvider) getHostedZoneID(fqdn string) (string, error) { + if d.config.HostedZoneID != "" { + return d.config.HostedZoneID, nil + } + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return "", err + } + + // .DNSName should not have a trailing dot + reqParams := &route53.ListHostedZonesByNameInput{ + DNSName: aws.String(dns01.UnFqdn(authZone)), + } + resp, err := d.client.ListHostedZonesByName(reqParams) + if err != nil { + return "", err + } + + var hostedZoneID string + for _, hostedZone := range resp.HostedZones { + // .Name has a trailing dot + if !aws.BoolValue(hostedZone.Config.PrivateZone) && aws.StringValue(hostedZone.Name) == authZone { + hostedZoneID = aws.StringValue(hostedZone.Id) + break + } + } + + if len(hostedZoneID) == 0 { + return "", fmt.Errorf("zone %s not found for domain %s", authZone, fqdn) + } + + if strings.HasPrefix(hostedZoneID, "/hostedzone/") { + hostedZoneID = strings.TrimPrefix(hostedZoneID, "/hostedzone/") + } + + return hostedZoneID, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/route53/route53.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/route53/route53.toml new file mode 100644 index 000000000..b6e8776fc --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/route53/route53.toml @@ -0,0 +1,69 @@ +Name = "Amazon Route 53" +Description = '''''' +URL = "https://aws.amazon.com/route53/" +Code = "route53" +Since = "v0.3.0" + +Example = '''''' + +Additional = ''' +## Description + +AWS Credentials are automatically detected in the following locations and prioritized in the following order: + +1. Environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`, [`AWS_SESSION_TOKEN`] +2. Shared credentials file (defaults to `~/.aws/credentials`) +3. Amazon EC2 IAM role + +If `AWS_HOSTED_ZONE_ID` is not set, Lego tries to determine the correct public hosted zone via the FQDN. + +See also: [sessions](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/sessions.html) + +## Policy + +The following AWS IAM policy document describes the permissions required for lego to complete the DNS challenge. + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "", + "Effect": "Allow", + "Action": [ + "route53:GetChange", + "route53:ChangeResourceRecordSets", + "route53:ListResourceRecordSets" + ], + "Resource": [ + "arn:aws:route53:::hostedzone/*", + "arn:aws:route53:::change/*" + ] + }, + { + "Sid": "", + "Effect": "Allow", + "Action": "route53:ListHostedZonesByName", + "Resource": "*" + } + ] +} +``` + +''' + +[Configuration] + [Configuration.Credentials] + AWS_ACCESS_KEY_ID = "Managed by the AWS client" + AWS_SECRET_ACCESS_KEY = "Managed by the AWS client" + AWS_REGION = "Managed by the AWS client" + AWS_HOSTED_ZONE_ID = "Override the hosted zone ID" + [Configuration.Additional] + AWS_MAX_RETRIES = "The number of maximum returns the service will use to make an individual API request" + AWS_POLLING_INTERVAL = "Time between DNS propagation check" + AWS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + AWS_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://docs.aws.amazon.com/Route53/latest/APIReference/API_Operations_Amazon_Route_53.html" + GoClient = "https://github.com/aws/aws-sdk-go/aws" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/client.go new file mode 100644 index 000000000..50bbdf2a1 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/client.go @@ -0,0 +1,106 @@ +package sakuracloud + +import ( + "fmt" + "net/http" + "strings" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/sacloud/libsacloud/api" + "github.com/sacloud/libsacloud/sacloud" +) + +const sacloudAPILockKey = "lego/dns/sacloud" + +func (d *DNSProvider) addTXTRecord(fqdn, domain, value string, ttl int) error { + sacloud.LockByKey(sacloudAPILockKey) + defer sacloud.UnlockByKey(sacloudAPILockKey) + + zone, err := d.getHostedZone(domain) + if err != nil { + return fmt.Errorf("sakuracloud: %v", err) + } + + name := d.extractRecordName(fqdn, zone.Name) + + zone.AddRecord(zone.CreateNewRecord(name, "TXT", value, ttl)) + _, err = d.client.Update(zone.ID, zone) + if err != nil { + return fmt.Errorf("sakuracloud: API call failed: %v", err) + } + + return nil +} + +func (d *DNSProvider) cleanupTXTRecord(fqdn, domain string) error { + sacloud.LockByKey(sacloudAPILockKey) + defer sacloud.UnlockByKey(sacloudAPILockKey) + + zone, err := d.getHostedZone(domain) + if err != nil { + return fmt.Errorf("sakuracloud: %v", err) + } + + records := d.findTxtRecords(fqdn, zone) + + for _, record := range records { + var updRecords []sacloud.DNSRecordSet + for _, r := range zone.Settings.DNS.ResourceRecordSets { + if !(r.Name == record.Name && r.Type == record.Type && r.RData == record.RData) { + updRecords = append(updRecords, r) + } + } + zone.Settings.DNS.ResourceRecordSets = updRecords + } + + _, err = d.client.Update(zone.ID, zone) + if err != nil { + return fmt.Errorf("sakuracloud: API call failed: %v", err) + } + return nil +} + +func (d *DNSProvider) getHostedZone(domain string) (*sacloud.DNS, error) { + authZone, err := dns01.FindZoneByFqdn(dns01.ToFqdn(domain)) + if err != nil { + return nil, err + } + + zoneName := dns01.UnFqdn(authZone) + + res, err := d.client.Reset().WithNameLike(zoneName).Find() + if err != nil { + if notFound, ok := err.(api.Error); ok && notFound.ResponseCode() == http.StatusNotFound { + return nil, fmt.Errorf("zone %s not found on SakuraCloud DNS: %v", zoneName, err) + } + return nil, fmt.Errorf("API call failed: %v", err) + } + + for _, zone := range res.CommonServiceDNSItems { + if zone.Name == zoneName { + return &zone, nil + } + } + + return nil, fmt.Errorf("zone %s not found", zoneName) +} + +func (d *DNSProvider) findTxtRecords(fqdn string, zone *sacloud.DNS) []sacloud.DNSRecordSet { + recordName := d.extractRecordName(fqdn, zone.Name) + + var res []sacloud.DNSRecordSet + for _, record := range zone.Settings.DNS.ResourceRecordSets { + if record.Name == recordName && record.Type == "TXT" { + res = append(res, record) + } + } + return res +} + +func (d *DNSProvider) extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/sakuracloud.go b/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/sakuracloud.go new file mode 100644 index 000000000..969ba2c30 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/sakuracloud.go @@ -0,0 +1,101 @@ +// Package sakuracloud implements a DNS provider for solving the DNS-01 challenge using SakuraCloud DNS. +package sakuracloud + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/sacloud/libsacloud/api" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Token string + Secret string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("SAKURACLOUD_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("SAKURACLOUD_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("SAKURACLOUD_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("SAKURACLOUD_HTTP_TIMEOUT", 10*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *api.DNSAPI +} + +// NewDNSProvider returns a DNSProvider instance configured for SakuraCloud. +// Credentials must be passed in the environment variables: SAKURACLOUD_ACCESS_TOKEN & SAKURACLOUD_ACCESS_TOKEN_SECRET +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("SAKURACLOUD_ACCESS_TOKEN", "SAKURACLOUD_ACCESS_TOKEN_SECRET") + if err != nil { + return nil, fmt.Errorf("sakuracloud: %v", err) + } + + config := NewDefaultConfig() + config.Token = values["SAKURACLOUD_ACCESS_TOKEN"] + config.Secret = values["SAKURACLOUD_ACCESS_TOKEN_SECRET"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for SakuraCloud. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("sakuracloud: the configuration of the DNS provider is nil") + } + + if config.Token == "" { + return nil, errors.New("sakuracloud: AccessToken is missing") + } + + if config.Secret == "" { + return nil, errors.New("sakuracloud: AccessSecret is missing") + } + + apiClient := api.NewClient(config.Token, config.Secret, "is1a") + if config.HTTPClient == nil { + apiClient.HTTPClient = http.DefaultClient + } else { + apiClient.HTTPClient = config.HTTPClient + } + + return &DNSProvider{ + client: apiClient.GetDNSAPI(), + config: config, + }, nil +} + +// Present creates a TXT record to fulfill the dns-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + return d.addTXTRecord(fqdn, domain, value, d.config.TTL) +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + return d.cleanupTXTRecord(fqdn, domain) +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/sakuracloud.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/sakuracloud.toml new file mode 100644 index 000000000..0dfcb944c --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/sakuracloud/sakuracloud.toml @@ -0,0 +1,21 @@ +Name = "Sakura Cloud" +Description = '''''' +URL = "https://cloud.sakura.ad.jp/" +Code = "sakuracloud" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + SAKURACLOUD_ACCESS_TOKEN = "Access token" + SAKURACLOUD_ACCESS_TOKEN_SECRET = "Access token secret" + [Configuration.Additional] + SAKURACLOUD_POLLING_INTERVAL = "Time between DNS propagation check" + SAKURACLOUD_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + SAKURACLOUD_TTL = "The TTL of the TXT record used for the DNS challenge" + SAKURACLOUD_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://developer.sakura.ad.jp/cloud/api/1.1/" + GoClient = "https://github.com/sacloud/libsacloud" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/internal/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/internal/client.go new file mode 100644 index 000000000..8457bc4aa --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/internal/client.go @@ -0,0 +1,221 @@ +package internal + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" +) + +// Domain represents domain name. +type Domain struct { + ID int `json:"id,omitempty"` + Name string `json:"name,omitempty"` +} + +// Record represents DNS record. +type Record struct { + ID int `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` // Record type (SOA, NS, A/AAAA, CNAME, SRV, MX, TXT, SPF) + TTL int `json:"ttl,omitempty"` + Email string `json:"email,omitempty"` // Email of domain's admin (only for SOA records) + Content string `json:"content,omitempty"` // Record content (not for SRV) +} + +// APIError API error message +type APIError struct { + Description string `json:"error"` + Code int `json:"code"` + Field string `json:"field"` +} + +func (a *APIError) Error() string { + return fmt.Sprintf("API error: %d - %s - %s", a.Code, a.Description, a.Field) +} + +// ClientOpts represents options to init client. +type ClientOpts struct { + BaseURL string + Token string + UserAgent string + HTTPClient *http.Client +} + +// Client represents DNS client. +type Client struct { + baseURL string + token string + userAgent string + httpClient *http.Client +} + +// NewClient returns a client instance. +func NewClient(opts ClientOpts) *Client { + if opts.HTTPClient == nil { + opts.HTTPClient = &http.Client{} + } + + return &Client{ + token: opts.Token, + baseURL: opts.BaseURL, + httpClient: opts.HTTPClient, + userAgent: opts.UserAgent, + } +} + +// GetDomainByName gets Domain object by its name. If `domainName` level > 2 and there is +// no such domain on the account - it'll recursively search for the first +// which is exists in Selectel Domain API. +func (c *Client) GetDomainByName(domainName string) (*Domain, error) { + uri := fmt.Sprintf("/%s", domainName) + req, err := c.newRequest(http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + + domain := &Domain{} + resp, err := c.do(req, domain) + if err != nil { + switch { + case resp.StatusCode == http.StatusNotFound && strings.Count(domainName, ".") > 1: + // Look up for the next sub domain + subIndex := strings.Index(domainName, ".") + return c.GetDomainByName(domainName[subIndex+1:]) + default: + return nil, err + } + } + + return domain, nil +} + +// AddRecord adds Record for given domain. +func (c *Client) AddRecord(domainID int, body Record) (*Record, error) { + uri := fmt.Sprintf("/%d/records/", domainID) + req, err := c.newRequest(http.MethodPost, uri, body) + if err != nil { + return nil, err + } + + record := &Record{} + _, err = c.do(req, record) + if err != nil { + return nil, err + } + + return record, nil +} + +// ListRecords returns list records for specific domain. +func (c *Client) ListRecords(domainID int) ([]*Record, error) { + uri := fmt.Sprintf("/%d/records/", domainID) + req, err := c.newRequest(http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + + var records []*Record + _, err = c.do(req, &records) + if err != nil { + return nil, err + } + return records, nil +} + +// DeleteRecord deletes specific record. +func (c *Client) DeleteRecord(domainID, recordID int) error { + uri := fmt.Sprintf("/%d/records/%d", domainID, recordID) + req, err := c.newRequest(http.MethodDelete, uri, nil) + if err != nil { + return err + } + + _, err = c.do(req, nil) + return err +} + +func (c *Client) newRequest(method, uri string, body interface{}) (*http.Request, error) { + buf := new(bytes.Buffer) + + if body != nil { + err := json.NewEncoder(buf).Encode(body) + if err != nil { + return nil, fmt.Errorf("failed to encode request body with error: %v", err) + } + } + + req, err := http.NewRequest(method, c.baseURL+uri, buf) + if err != nil { + return nil, fmt.Errorf("failed to create new http request with error: %v", err) + } + + req.Header.Add("X-Token", c.token) + req.Header.Add("Content-Type", "application/json") + req.Header.Add("Accept", "application/json") + + return req, nil +} + +func (c *Client) do(req *http.Request, to interface{}) (*http.Response, error) { + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("request failed with error: %v", err) + } + + err = checkResponse(resp) + if err != nil { + return resp, err + } + + if to != nil { + if err = unmarshalBody(resp, to); err != nil { + return resp, err + } + } + + return resp, nil +} + +func checkResponse(resp *http.Response) error { + if resp.StatusCode >= http.StatusBadRequest && + resp.StatusCode <= http.StatusNetworkAuthenticationRequired { + + if resp.Body == nil { + return fmt.Errorf("request failed with status code %d and empty body", resp.StatusCode) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + defer resp.Body.Close() + + apiError := APIError{} + err = json.Unmarshal(body, &apiError) + if err != nil { + return fmt.Errorf("request failed with status code %d, response body: %s", resp.StatusCode, string(body)) + } + + return fmt.Errorf("request failed with status code %d: %v", resp.StatusCode, apiError) + } + + return nil +} + +func unmarshalBody(resp *http.Response, to interface{}) error { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + defer resp.Body.Close() + + err = json.Unmarshal(body, to) + if err != nil { + return fmt.Errorf("unmarshaling error: %v: %s", err, string(body)) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/selectel.go b/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/selectel.go new file mode 100644 index 000000000..aab1a6a38 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/selectel.go @@ -0,0 +1,154 @@ +// Package selectel implements a DNS provider for solving the DNS-01 challenge using Selectel Domains API. +// Selectel Domain API reference: https://kb.selectel.com/23136054.html +// Token: https://my.selectel.ru/profile/apikeys +package selectel + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/go-acme/lego/v3/providers/dns/selectel/internal" +) + +const ( + defaultBaseURL = "https://api.selectel.ru/domains/v1" + minTTL = 60 +) + +const ( + envNamespace = "SELECTEL_" + baseURLEnvVar = envNamespace + "BASE_URL" + apiTokenEnvVar = envNamespace + "API_TOKEN" + ttlEnvVar = envNamespace + "TTL" + propagationTimeoutEnvVar = envNamespace + "PROPAGATION_TIMEOUT" + pollingIntervalEnvVar = envNamespace + "POLLING_INTERVAL" + httpTimeoutEnvVar = envNamespace + "HTTP_TIMEOUT" +) + +// Config is used to configure the creation of the DNSProvider. +type Config struct { + BaseURL string + Token string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider. +func NewDefaultConfig() *Config { + return &Config{ + BaseURL: env.GetOrDefaultString(baseURLEnvVar, defaultBaseURL), + TTL: env.GetOrDefaultInt(ttlEnvVar, minTTL), + PropagationTimeout: env.GetOrDefaultSecond(propagationTimeoutEnvVar, 120*time.Second), + PollingInterval: env.GetOrDefaultSecond(pollingIntervalEnvVar, 2*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond(httpTimeoutEnvVar, 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *internal.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for Selectel Domains API. +// API token must be passed in the environment variable SELECTEL_API_TOKEN. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get(apiTokenEnvVar) + if err != nil { + return nil, fmt.Errorf("selectel: %v", err) + } + + config := NewDefaultConfig() + config.Token = values[apiTokenEnvVar] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for selectel. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("selectel: the configuration of the DNS provider is nil") + } + + if config.Token == "" { + return nil, errors.New("selectel: credentials missing") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("selectel: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + client := internal.NewClient(internal.ClientOpts{ + BaseURL: config.BaseURL, + Token: config.Token, + HTTPClient: config.HTTPClient, + }) + + return &DNSProvider{config: config, client: client}, nil +} + +// Timeout returns the Timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill DNS-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + domainObj, err := d.client.GetDomainByName(domain) + if err != nil { + return fmt.Errorf("selectel: %v", err) + } + + txtRecord := internal.Record{ + Type: "TXT", + TTL: d.config.TTL, + Name: fqdn, + Content: value, + } + _, err = d.client.AddRecord(domainObj.ID, txtRecord) + if err != nil { + return fmt.Errorf("selectel: %v", err) + } + + return nil +} + +// CleanUp removes a TXT record used for DNS-01 challenge. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + recordName := dns01.UnFqdn(fqdn) + + domainObj, err := d.client.GetDomainByName(domain) + if err != nil { + return fmt.Errorf("selectel: %v", err) + } + + records, err := d.client.ListRecords(domainObj.ID) + if err != nil { + return fmt.Errorf("selectel: %v", err) + } + + // Delete records with specific FQDN + var lastErr error + for _, record := range records { + if record.Name == recordName { + err = d.client.DeleteRecord(domainObj.ID, record.ID) + if err != nil { + lastErr = fmt.Errorf("selectel: %v", err) + } + } + } + + return lastErr +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/selectel.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/selectel.toml new file mode 100644 index 000000000..2d9ee4861 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/selectel/selectel.toml @@ -0,0 +1,20 @@ +Name = "Selectel" +Description = '''''' +URL = "https://kb.selectel.com/" +Code = "selectel" +Since = "v1.2.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + SELECTEL_API_TOKEN = "API token" + [Configuration.Additional] + SELECTEL_BASE_URL = "API endpoint URL" + SELECTEL_POLLING_INTERVAL = "Time between DNS propagation check" + SELECTEL_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + SELECTEL_TTL = "The TTL of the TXT record used for the DNS challenge" + SELECTEL_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://kb.selectel.com/23136054.html" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/client.go new file mode 100644 index 000000000..5fe7f3f62 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/client.go @@ -0,0 +1,217 @@ +package stackpath + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "path" + + "github.com/go-acme/lego/v3/challenge/dns01" + "golang.org/x/net/publicsuffix" +) + +// Zones is the response struct from the Stackpath api GetZones +type Zones struct { + Zones []Zone `json:"zones"` +} + +// Zone a DNS zone representation +type Zone struct { + ID string + Domain string +} + +// Records is the response struct from the Stackpath api GetZoneRecords +type Records struct { + Records []Record `json:"records"` +} + +// Record a DNS record representation +type Record struct { + ID string `json:"id,omitempty"` + Name string `json:"name"` + Type string `json:"type"` + TTL int `json:"ttl"` + Data string `json:"data"` +} + +// ErrorResponse the API error response representation +type ErrorResponse struct { + Code int `json:"code"` + Message string `json:"error"` +} + +func (e *ErrorResponse) Error() string { + return fmt.Sprintf("%d %s", e.Code, e.Message) +} + +// https://developer.stackpath.com/en/api/dns/#operation/GetZones +func (d *DNSProvider) getZones(domain string) (*Zone, error) { + domain = dns01.UnFqdn(domain) + tld, err := publicsuffix.EffectiveTLDPlusOne(domain) + if err != nil { + return nil, err + } + + req, err := d.newRequest(http.MethodGet, "/zones", nil) + if err != nil { + return nil, err + } + + query := req.URL.Query() + query.Add("page_request.filter", fmt.Sprintf("domain='%s'", tld)) + req.URL.RawQuery = query.Encode() + + var zones Zones + err = d.do(req, &zones) + if err != nil { + return nil, err + } + + if len(zones.Zones) == 0 { + return nil, fmt.Errorf("did not find zone with domain %s", domain) + } + + return &zones.Zones[0], nil +} + +// https://developer.stackpath.com/en/api/dns/#operation/GetZoneRecords +func (d *DNSProvider) getZoneRecords(name string, zone *Zone) ([]Record, error) { + u := fmt.Sprintf("/zones/%s/records", zone.ID) + req, err := d.newRequest(http.MethodGet, u, nil) + if err != nil { + return nil, err + } + + query := req.URL.Query() + query.Add("page_request.filter", fmt.Sprintf("name='%s' and type='TXT'", name)) + req.URL.RawQuery = query.Encode() + + var records Records + err = d.do(req, &records) + if err != nil { + return nil, err + } + + if len(records.Records) == 0 { + return nil, fmt.Errorf("did not find record with name %s", name) + } + + return records.Records, nil +} + +// https://developer.stackpath.com/en/api/dns/#operation/CreateZoneRecord +func (d *DNSProvider) createZoneRecord(zone *Zone, record Record) error { + u := fmt.Sprintf("/zones/%s/records", zone.ID) + req, err := d.newRequest(http.MethodPost, u, record) + if err != nil { + return err + } + + return d.do(req, nil) +} + +// https://developer.stackpath.com/en/api/dns/#operation/DeleteZoneRecord +func (d *DNSProvider) deleteZoneRecord(zone *Zone, record Record) error { + u := fmt.Sprintf("/zones/%s/records/%s", zone.ID, record.ID) + req, err := d.newRequest(http.MethodDelete, u, nil) + if err != nil { + return err + } + + return d.do(req, nil) +} + +func (d *DNSProvider) newRequest(method, urlStr string, body interface{}) (*http.Request, error) { + u, err := d.BaseURL.Parse(path.Join(d.config.StackID, urlStr)) + if err != nil { + return nil, err + } + + if body == nil { + var req *http.Request + req, err = http.NewRequest(method, u.String(), nil) + if err != nil { + return nil, err + } + + return req, nil + } + + reqBody, err := json.Marshal(body) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, u.String(), bytes.NewBuffer(reqBody)) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + + return req, nil +} + +func (d *DNSProvider) do(req *http.Request, v interface{}) error { + resp, err := d.client.Do(req) + if err != nil { + return err + } + + err = checkResponse(resp) + if err != nil { + return err + } + + if v == nil { + return nil + } + + raw, err := readBody(resp) + if err != nil { + return fmt.Errorf("failed to read body: %v", err) + } + + err = json.Unmarshal(raw, v) + if err != nil { + return fmt.Errorf("unmarshaling error: %v: %s", err, string(raw)) + } + + return nil +} + +func checkResponse(resp *http.Response) error { + if resp.StatusCode > 299 { + data, err := readBody(resp) + if err != nil { + return &ErrorResponse{Code: resp.StatusCode, Message: err.Error()} + } + + errResp := &ErrorResponse{} + err = json.Unmarshal(data, errResp) + if err != nil { + return &ErrorResponse{Code: resp.StatusCode, Message: fmt.Sprintf("unmarshaling error: %v: %s", err, string(data))} + } + return errResp + } + + return nil +} + +func readBody(resp *http.Response) ([]byte, error) { + if resp.Body == nil { + return nil, fmt.Errorf("response body is nil") + } + + defer resp.Body.Close() + + rawBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return rawBody, nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/stackpath.go b/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/stackpath.go new file mode 100644 index 000000000..c68589a7a --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/stackpath.go @@ -0,0 +1,150 @@ +// Package stackpath implements a DNS provider for solving the DNS-01 challenge using Stackpath DNS. +// https://developer.stackpath.com/en/api/dns/ +package stackpath + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/log" + "github.com/go-acme/lego/v3/platform/config/env" + "golang.org/x/oauth2/clientcredentials" +) + +const ( + defaultBaseURL = "https://gateway.stackpath.com/dns/v1/stacks/" + defaultAuthURL = "https://gateway.stackpath.com/identity/v1/oauth2/token" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + ClientID string + ClientSecret string + StackID string + TTL int + PropagationTimeout time.Duration + PollingInterval time.Duration +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("STACKPATH_TTL", 120), + PropagationTimeout: env.GetOrDefaultSecond("STACKPATH_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("STACKPATH_POLLING_INTERVAL", dns01.DefaultPollingInterval), + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + BaseURL *url.URL + client *http.Client + config *Config +} + +// NewDNSProvider returns a DNSProvider instance configured for Stackpath. +// Credentials must be passed in the environment variables: +// STACKPATH_CLIENT_ID, STACKPATH_CLIENT_SECRET, and STACKPATH_STACK_ID. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("STACKPATH_CLIENT_ID", "STACKPATH_CLIENT_SECRET", "STACKPATH_STACK_ID") + if err != nil { + return nil, fmt.Errorf("stackpath: %v", err) + } + + config := NewDefaultConfig() + config.ClientID = values["STACKPATH_CLIENT_ID"] + config.ClientSecret = values["STACKPATH_CLIENT_SECRET"] + config.StackID = values["STACKPATH_STACK_ID"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Stackpath. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("stackpath: the configuration of the DNS provider is nil") + } + + if len(config.ClientID) == 0 || len(config.ClientSecret) == 0 { + return nil, errors.New("stackpath: credentials missing") + } + + if len(config.StackID) == 0 { + return nil, errors.New("stackpath: stack id missing") + } + + baseURL, _ := url.Parse(defaultBaseURL) + + return &DNSProvider{ + BaseURL: baseURL, + client: getOathClient(config), + config: config, + }, nil +} + +func getOathClient(config *Config) *http.Client { + oathConfig := &clientcredentials.Config{ + TokenURL: defaultAuthURL, + ClientID: config.ClientID, + ClientSecret: config.ClientSecret, + } + + return oathConfig.Client(context.Background()) +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + zone, err := d.getZones(domain) + if err != nil { + return fmt.Errorf("stackpath: %v", err) + } + + fqdn, value := dns01.GetRecord(domain, keyAuth) + parts := strings.Split(fqdn, ".") + + record := Record{ + Name: parts[0], + Type: "TXT", + TTL: d.config.TTL, + Data: value, + } + + return d.createZoneRecord(zone, record) +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + zone, err := d.getZones(domain) + if err != nil { + return fmt.Errorf("stackpath: %v", err) + } + + fqdn, _ := dns01.GetRecord(domain, keyAuth) + parts := strings.Split(fqdn, ".") + + records, err := d.getZoneRecords(parts[0], zone) + if err != nil { + return err + } + + for _, record := range records { + err = d.deleteZoneRecord(zone, record) + if err != nil { + log.Printf("stackpath: failed to delete TXT record: %v", err) + } + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/stackpath.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/stackpath.toml new file mode 100644 index 000000000..1a492ebb8 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/stackpath/stackpath.toml @@ -0,0 +1,20 @@ +Name = "Stackpath" +Description = '''''' +URL = "https://www.stackpath.com/" +Code = "stackpath" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + STACKPATH_CLIENT_ID = "Client ID" + STACKPATH_CLIENT_SECRET = "Client secret" + STACKPATH_STACK_ID = "Stack ID" + [Configuration.Additional] + STACKPATH_POLLING_INTERVAL = "Time between DNS propagation check" + STACKPATH_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + STACKPATH_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://developer.stackpath.com/en/api/dns/#tag/Zone" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/transip/transip.go b/vendor/github.com/go-acme/lego/v3/providers/dns/transip/transip.go new file mode 100644 index 000000000..ed539e5c6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/transip/transip.go @@ -0,0 +1,160 @@ +// Package transip implements a DNS provider for solving the DNS-01 challenge using TransIP. +package transip + +import ( + "errors" + "fmt" + "strings" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/transip/gotransip" + transipdomain "github.com/transip/gotransip/domain" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + AccountName string + PrivateKeyPath string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int64 +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: int64(env.GetOrDefaultInt("TRANSIP_TTL", 10)), + PropagationTimeout: env.GetOrDefaultSecond("TRANSIP_PROPAGATION_TIMEOUT", 10*time.Minute), + PollingInterval: env.GetOrDefaultSecond("TRANSIP_POLLING_INTERVAL", 10*time.Second), + } +} + +// DNSProvider describes a provider for TransIP +type DNSProvider struct { + config *Config + client gotransip.Client + dnsEntriesMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance configured for TransIP. +// Credentials must be passed in the environment variables: +// TRANSIP_ACCOUNTNAME, TRANSIP_PRIVATEKEYPATH. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("TRANSIP_ACCOUNT_NAME", "TRANSIP_PRIVATE_KEY_PATH") + if err != nil { + return nil, fmt.Errorf("transip: %v", err) + } + + config := NewDefaultConfig() + config.AccountName = values["TRANSIP_ACCOUNT_NAME"] + config.PrivateKeyPath = values["TRANSIP_PRIVATE_KEY_PATH"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for TransIP. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("transip: the configuration of the DNS provider is nil") + } + + client, err := gotransip.NewSOAPClient(gotransip.ClientConfig{ + AccountName: config.AccountName, + PrivateKeyPath: config.PrivateKeyPath, + }) + if err != nil { + return nil, fmt.Errorf("transip: %v", err) + } + + return &DNSProvider{client: client, config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return err + } + + domainName := dns01.UnFqdn(authZone) + + // get the subDomain + subDomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+domainName) + + // use mutex to prevent race condition from GetInfo until SetDNSEntries + d.dnsEntriesMu.Lock() + defer d.dnsEntriesMu.Unlock() + + // get all DNS entries + info, err := transipdomain.GetInfo(d.client, domainName) + if err != nil { + return fmt.Errorf("transip: error for %s in Present: %v", domain, err) + } + + // include the new DNS entry + dnsEntries := append(info.DNSEntries, transipdomain.DNSEntry{ + Name: subDomain, + TTL: d.config.TTL, + Type: transipdomain.DNSEntryTypeTXT, + Content: value, + }) + + // set the updated DNS entries + err = transipdomain.SetDNSEntries(d.client, domainName, dnsEntries) + if err != nil { + return fmt.Errorf("transip: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return err + } + + domainName := dns01.UnFqdn(authZone) + + // get the subDomain + subDomain := strings.TrimSuffix(dns01.UnFqdn(fqdn), "."+domainName) + + // use mutex to prevent race condition from GetInfo until SetDNSEntries + d.dnsEntriesMu.Lock() + defer d.dnsEntriesMu.Unlock() + + // get all DNS entries + info, err := transipdomain.GetInfo(d.client, domainName) + if err != nil { + return fmt.Errorf("transip: error for %s in CleanUp: %v", fqdn, err) + } + + // loop through the existing entries and remove the specific record + updatedEntries := info.DNSEntries[:0] + for _, e := range info.DNSEntries { + if e.Name != subDomain { + updatedEntries = append(updatedEntries, e) + } + } + + // set the updated DNS entries + err = transipdomain.SetDNSEntries(d.client, domainName, updatedEntries) + if err != nil { + return fmt.Errorf("transip: couldn't get Record ID in CleanUp: %sv", err) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/transip/transip.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/transip/transip.toml new file mode 100644 index 000000000..57bebe9be --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/transip/transip.toml @@ -0,0 +1,21 @@ +Name = "TransIP" +Description = '''''' +URL = "https://www.transip.nl/" +Code = "transip" +Since = "v2.0.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + TRANSIP_ACCOUNT_NAME = "Account name" + TRANSIP_PRIVATE_KEY_PATH = "Private key path" + [Configuration.Additional] + TRANSIP_POLLING_INTERVAL = "Time between DNS propagation check" + TRANSIP_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + TRANSIP_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://api.transip.nl/docs/transip.nl/package-Transip.html" + GoClient = "https://github.com/transip/gotransip" + diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/vegadns/vegadns.go b/vendor/github.com/go-acme/lego/v3/providers/dns/vegadns/vegadns.go new file mode 100644 index 000000000..25e318303 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/vegadns/vegadns.go @@ -0,0 +1,113 @@ +// Package vegadns implements a DNS provider for solving the DNS-01 challenge using VegaDNS. +package vegadns + +import ( + "errors" + "fmt" + "strings" + "time" + + vegaClient "github.com/OpenDNS/vegadns2client" + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL string + APIKey string + APISecret string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("VEGADNS_TTL", 10), + PropagationTimeout: env.GetOrDefaultSecond("VEGADNS_PROPAGATION_TIMEOUT", 12*time.Minute), + PollingInterval: env.GetOrDefaultSecond("VEGADNS_POLLING_INTERVAL", 1*time.Minute), + } +} + +// DNSProvider describes a provider for VegaDNS +type DNSProvider struct { + config *Config + client vegaClient.VegaDNSClient +} + +// NewDNSProvider returns a DNSProvider instance configured for VegaDNS. +// Credentials must be passed in the environment variables: +// VEGADNS_URL, SECRET_VEGADNS_KEY, SECRET_VEGADNS_SECRET. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("VEGADNS_URL") + if err != nil { + return nil, fmt.Errorf("vegadns: %v", err) + } + + config := NewDefaultConfig() + config.BaseURL = values["VEGADNS_URL"] + config.APIKey = env.GetOrFile("SECRET_VEGADNS_KEY") + config.APISecret = env.GetOrFile("SECRET_VEGADNS_SECRET") + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for VegaDNS. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("vegadns: the configuration of the DNS provider is nil") + } + + vega := vegaClient.NewVegaDNSClient(config.BaseURL) + vega.APIKey = config.APIKey + vega.APISecret = config.APISecret + + return &DNSProvider{client: vega, config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + _, domainID, err := d.client.GetAuthZone(fqdn) + if err != nil { + return fmt.Errorf("vegadns: can't find Authoritative Zone for %s in Present: %v", fqdn, err) + } + + err = d.client.CreateTXT(domainID, fqdn, value, d.config.TTL) + if err != nil { + return fmt.Errorf("vegadns: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + _, domainID, err := d.client.GetAuthZone(fqdn) + if err != nil { + return fmt.Errorf("vegadns: can't find Authoritative Zone for %s in CleanUp: %v", fqdn, err) + } + + txt := strings.TrimSuffix(fqdn, ".") + + recordID, err := d.client.GetRecordID(domainID, txt, "TXT") + if err != nil { + return fmt.Errorf("vegadns: couldn't get Record ID in CleanUp: %s", err) + } + + err = d.client.DeleteRecord(recordID) + if err != nil { + return fmt.Errorf("vegadns: %v", err) + } + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/vegadns/vegadns.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/vegadns/vegadns.toml new file mode 100644 index 000000000..e1a7cc713 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/vegadns/vegadns.toml @@ -0,0 +1,22 @@ +Name = "VegaDNS" +Description = '''''' +URL = "https://github.com/shupp/VegaDNS-API" +Code = "vegadns" +Since = "v1.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + SECRET_VEGADNS_KEY = "API key" + SECRET_VEGADNS_SECRET = "API secret" + VEGADNS_URL = "API endpoint URL" + [Configuration.Additional] + VEGADNS_POLLING_INTERVAL = "Time between DNS propagation check" + VEGADNS_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + VEGADNS_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://github.com/shupp/VegaDNS-API" + GoClient = "https://github.com/OpenDNS/vegadns2client" + diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/versio/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/versio/client.go new file mode 100644 index 000000000..a0f483784 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/versio/client.go @@ -0,0 +1,127 @@ +package versio + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "path" +) + +const defaultBaseURL = "https://www.versio.nl/api/v1/" + +type dnsRecordsResponse struct { + Record dnsRecord `json:"domainInfo"` +} + +type dnsRecord struct { + DNSRecords []record `json:"dns_records"` +} + +type record struct { + Type string `json:"type,omitempty"` + Name string `json:"name,omitempty"` + Value string `json:"value,omitempty"` + Priority int `json:"prio,omitempty"` + TTL int `json:"ttl,omitempty"` +} + +type dnsErrorResponse struct { + Error errorMessage `json:"error"` +} + +type errorMessage struct { + Code int `json:"code,omitempty"` + Message string `json:"message,omitempty"` +} + +func (d *DNSProvider) postDNSRecords(domain string, msg interface{}) error { + reqBody := &bytes.Buffer{} + err := json.NewEncoder(reqBody).Encode(msg) + if err != nil { + return err + } + + req, err := d.makeRequest(http.MethodPost, "domains/"+domain+"/update", reqBody) + if err != nil { + return err + } + + return d.do(req, nil) +} + +func (d *DNSProvider) getDNSRecords(domain string) (*dnsRecordsResponse, error) { + req, err := d.makeRequest(http.MethodGet, "domains/"+domain+"?show_dns_records=true", nil) + if err != nil { + return nil, err + } + + // we'll need all the dns_records to add the new TXT record + respData := &dnsRecordsResponse{} + err = d.do(req, respData) + if err != nil { + return nil, err + } + + return respData, nil +} + +func (d *DNSProvider) makeRequest(method string, uri string, body io.Reader) (*http.Request, error) { + endpoint, err := d.config.BaseURL.Parse(path.Join(d.config.BaseURL.EscapedPath(), uri)) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, endpoint.String(), body) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + + if len(d.config.Username) > 0 && len(d.config.Password) > 0 { + req.SetBasicAuth(d.config.Username, d.config.Password) + } + + return req, nil +} + +func (d *DNSProvider) do(req *http.Request, result interface{}) error { + resp, err := d.config.HTTPClient.Do(req) + if resp != nil { + defer resp.Body.Close() + } + if err != nil { + return err + } + + if resp.StatusCode >= http.StatusBadRequest { + var body []byte + body, err = ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("%d: failed to read response body: %v", resp.StatusCode, err) + } + + respError := &dnsErrorResponse{} + err = json.Unmarshal(body, respError) + if err != nil { + return fmt.Errorf("%d: request failed: %s", resp.StatusCode, string(body)) + } + return fmt.Errorf("%d: request failed: %s", resp.StatusCode, respError.Error.Message) + } + + if result != nil { + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("request failed: %v", err) + } + + if err = json.Unmarshal(content, result); err != nil { + return fmt.Errorf("%v: %s", err, content) + } + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/versio/versio.go b/vendor/github.com/go-acme/lego/v3/providers/dns/versio/versio.go new file mode 100644 index 000000000..9542cc6e7 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/versio/versio.go @@ -0,0 +1,155 @@ +// Package versio implements a DNS provider for solving the DNS-01 challenge using versio DNS. +package versio + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "sync" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + BaseURL *url.URL + TTL int + Username string + Password string + PropagationTimeout time.Duration + PollingInterval time.Duration + SequenceInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + baseURL, err := url.Parse(env.GetOrDefaultString("VERSIO_ENDPOINT", defaultBaseURL)) + if err != nil { + baseURL, _ = url.Parse(defaultBaseURL) + } + + return &Config{ + BaseURL: baseURL, + TTL: env.GetOrDefaultInt("VERSIO_TTL", 300), + PropagationTimeout: env.GetOrDefaultSecond("VERSIO_PROPAGATION_TIMEOUT", 60*time.Second), + PollingInterval: env.GetOrDefaultSecond("VERSIO_POLLING_INTERVAL", 5*time.Second), + SequenceInterval: env.GetOrDefaultSecond("VERSIO_SEQUENCE_INTERVAL", dns01.DefaultPropagationTimeout), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("VERSIO_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider describes a provider for acme-proxy +type DNSProvider struct { + config *Config + dnsEntriesMu sync.Mutex +} + +// NewDNSProvider returns a DNSProvider instance. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("VERSIO_USERNAME", "VERSIO_PASSWORD") + if err != nil { + return nil, fmt.Errorf("versio: %v", err) + } + + config := NewDefaultConfig() + config.Username = values["VERSIO_USERNAME"] + config.Password = values["VERSIO_PASSWORD"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider . +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("versio: the configuration of the DNS provider is nil") + } + if config.Username == "" { + return nil, errors.New("versio: the versio username is missing") + } + if config.Password == "" { + return nil, errors.New("versio: the versio password is missing") + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("versio: %v", err) + } + + // use mutex to prevent race condition from getDNSRecords until postDNSRecords + d.dnsEntriesMu.Lock() + defer d.dnsEntriesMu.Unlock() + + zoneName := dns01.UnFqdn(authZone) + domains, err := d.getDNSRecords(zoneName) + if err != nil { + return fmt.Errorf("versio: %v", err) + } + + txtRecord := record{ + Type: "TXT", + Name: fqdn, + Value: `"` + value + `"`, + TTL: d.config.TTL, + } + // Add new txtRercord to existing array of DNSRecords + msg := &domains.Record + msg.DNSRecords = append(msg.DNSRecords, txtRecord) + + err = d.postDNSRecords(zoneName, msg) + if err != nil { + return fmt.Errorf("versio: %v", err) + } + return nil +} + +// CleanUp removes the TXT record matching the specified parameters +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + authZone, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return fmt.Errorf("versio: %v", err) + } + + // use mutex to prevent race condition from getDNSRecords until postDNSRecords + d.dnsEntriesMu.Lock() + defer d.dnsEntriesMu.Unlock() + + zoneName := dns01.UnFqdn(authZone) + domains, err := d.getDNSRecords(zoneName) + if err != nil { + return fmt.Errorf("versio: %v", err) + } + + // loop through the existing entries and remove the specific record + msg := &dnsRecord{} + for _, e := range domains.Record.DNSRecords { + if e.Name != fqdn { + msg.DNSRecords = append(msg.DNSRecords, e) + } + } + + err = d.postDNSRecords(zoneName, msg) + if err != nil { + return fmt.Errorf("versio: %v", err) + } + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/versio/versio.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/versio/versio.toml new file mode 100644 index 000000000..697a1ce35 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/versio/versio.toml @@ -0,0 +1,30 @@ +Name = "Versio.[nl|eu|uk]" +Description = '''''' +URL = "https://www.versio.nl/domeinnamen" +Code = "versio" +Since = "v2.7.0" + +Example = ''' +VERSIO_USERNAME= \ +VERSIO_PASSWORD= \ +lego --dns versio --domains my.domain.com --email my@email.com run +''' + +Additional = ''' +To test with the sandbox environment set ```VERSIO_ENDPOINT=https://www.versio.nl/testapi/v1/``` +''' + +[Configuration] + [Configuration.Credentials] + VERSIO_USERNAME = "Basic authentication username" + VERSIO_PASSWORD = "Basic authentication password" + [Configuration.Additional] + VERSIO_ENDPOINT = "The endpoint URL of the API Server" + VERSIO_POLLING_INTERVAL = "Time between DNS propagation check" + VERSIO_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + VERSIO_HTTP_TIMEOUT = "API request timeout" + VERSIO_SEQUENCE_INTERVAL = "Interval between iteration, default 60s" + VERSIO_TTL = "The TTL of the TXT record used for the DNS challenge" + +[Links] + API = "https://www.versio.nl/RESTapidoc/" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/internal/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/internal/client.go new file mode 100644 index 000000000..7ce7495e9 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/internal/client.go @@ -0,0 +1,221 @@ +package internal + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" +) + +// Domain represents domain name. +type Domain struct { + ID int `json:"id,omitempty"` + Name string `json:"name,omitempty"` +} + +// Record represents DNS record. +type Record struct { + ID int `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` // Record type (SOA, NS, A/AAAA, CNAME, SRV, MX, TXT, SPF) + TTL int `json:"ttl,omitempty"` + Email string `json:"email,omitempty"` // Email of domain's admin (only for SOA records) + Content string `json:"content,omitempty"` // Record content (not for SRV) +} + +// APIError API error message +type APIError struct { + Description string `json:"error"` + Code int `json:"code"` + Field string `json:"field"` +} + +func (a *APIError) Error() string { + return fmt.Sprintf("API error: %d - %s - %s", a.Code, a.Description, a.Field) +} + +// ClientOpts represents options to init client. +type ClientOpts struct { + BaseURL string + Token string + UserAgent string + HTTPClient *http.Client +} + +// Client represents DNS client. +type Client struct { + baseURL string + token string + userAgent string + httpClient *http.Client +} + +// NewClient returns a client instance. +func NewClient(opts ClientOpts) *Client { + if opts.HTTPClient == nil { + opts.HTTPClient = &http.Client{} + } + + return &Client{ + token: opts.Token, + baseURL: opts.BaseURL, + httpClient: opts.HTTPClient, + userAgent: opts.UserAgent, + } +} + +// GetDomainByName gets Domain object by its name. If `domainName` level > 2 and there is +// no such domain on the account - it'll recursively search for the first +// which is exists in Vscale Domains API. +func (c *Client) GetDomainByName(domainName string) (*Domain, error) { + uri := fmt.Sprintf("/%s", domainName) + req, err := c.newRequest(http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + + domain := &Domain{} + resp, err := c.do(req, domain) + if err != nil { + switch { + case resp.StatusCode == http.StatusNotFound && strings.Count(domainName, ".") > 1: + // Look up for the next sub domain + subIndex := strings.Index(domainName, ".") + return c.GetDomainByName(domainName[subIndex+1:]) + default: + return nil, err + } + } + + return domain, nil +} + +// AddRecord adds Record for given domain. +func (c *Client) AddRecord(domainID int, body Record) (*Record, error) { + uri := fmt.Sprintf("/%d/records/", domainID) + req, err := c.newRequest(http.MethodPost, uri, body) + if err != nil { + return nil, err + } + + record := &Record{} + _, err = c.do(req, record) + if err != nil { + return nil, err + } + + return record, nil +} + +// ListRecords returns list records for specific domain. +func (c *Client) ListRecords(domainID int) ([]*Record, error) { + uri := fmt.Sprintf("/%d/records/", domainID) + req, err := c.newRequest(http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + + var records []*Record + _, err = c.do(req, &records) + if err != nil { + return nil, err + } + return records, nil +} + +// DeleteRecord deletes specific record. +func (c *Client) DeleteRecord(domainID, recordID int) error { + uri := fmt.Sprintf("/%d/records/%d", domainID, recordID) + req, err := c.newRequest(http.MethodDelete, uri, nil) + if err != nil { + return err + } + + _, err = c.do(req, nil) + return err +} + +func (c *Client) newRequest(method, uri string, body interface{}) (*http.Request, error) { + buf := new(bytes.Buffer) + + if body != nil { + err := json.NewEncoder(buf).Encode(body) + if err != nil { + return nil, fmt.Errorf("failed to encode request body with error: %v", err) + } + } + + req, err := http.NewRequest(method, c.baseURL+uri, buf) + if err != nil { + return nil, fmt.Errorf("failed to create new http request with error: %v", err) + } + + req.Header.Add("X-Token", c.token) + req.Header.Add("Content-Type", "application/json") + req.Header.Add("Accept", "application/json") + + return req, nil +} + +func (c *Client) do(req *http.Request, to interface{}) (*http.Response, error) { + resp, err := c.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("request failed with error: %v", err) + } + + err = checkResponse(resp) + if err != nil { + return resp, err + } + + if to != nil { + if err = unmarshalBody(resp, to); err != nil { + return resp, err + } + } + + return resp, nil +} + +func checkResponse(resp *http.Response) error { + if resp.StatusCode >= http.StatusBadRequest && + resp.StatusCode <= http.StatusNetworkAuthenticationRequired { + + if resp.Body == nil { + return fmt.Errorf("request failed with status code %d and empty body", resp.StatusCode) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + defer resp.Body.Close() + + apiError := APIError{} + err = json.Unmarshal(body, &apiError) + if err != nil { + return fmt.Errorf("request failed with status code %d, response body: %s", resp.StatusCode, string(body)) + } + + return fmt.Errorf("request failed with status code %d: %v", resp.StatusCode, apiError) + } + + return nil +} + +func unmarshalBody(resp *http.Response, to interface{}) error { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + defer resp.Body.Close() + + err = json.Unmarshal(body, to) + if err != nil { + return fmt.Errorf("unmarshaling error: %v: %s", err, string(body)) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/vscale.go b/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/vscale.go new file mode 100644 index 000000000..047497f1b --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/vscale.go @@ -0,0 +1,155 @@ +// Package vscale implements a DNS provider for solving the DNS-01 challenge using Vscale Domains API. +// Vscale Domain API reference: https://developers.vscale.io/documentation/api/v1/#api-Domains +// Token: https://vscale.io/panel/settings/tokens/ +package vscale + +import ( + "errors" + "fmt" + "net/http" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/providers/dns/vscale/internal" + + "github.com/go-acme/lego/v3/platform/config/env" +) + +const ( + defaultBaseURL = "https://api.vscale.io/v1/domains" + minTTL = 60 +) + +const ( + envNamespace = "VSCALE_" + baseURLEnvVar = envNamespace + "BASE_URL" + apiTokenEnvVar = envNamespace + "API_TOKEN" + ttlEnvVar = envNamespace + "TTL" + propagationTimeoutEnvVar = envNamespace + "PROPAGATION_TIMEOUT" + pollingIntervalEnvVar = envNamespace + "POLLING_INTERVAL" + httpTimeoutEnvVar = envNamespace + "HTTP_TIMEOUT" +) + +// Config is used to configure the creation of the DNSProvider. +type Config struct { + BaseURL string + Token string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider. +func NewDefaultConfig() *Config { + return &Config{ + BaseURL: env.GetOrDefaultString(baseURLEnvVar, defaultBaseURL), + TTL: env.GetOrDefaultInt(ttlEnvVar, minTTL), + PropagationTimeout: env.GetOrDefaultSecond(propagationTimeoutEnvVar, 120*time.Second), + PollingInterval: env.GetOrDefaultSecond(pollingIntervalEnvVar, 2*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond(httpTimeoutEnvVar, 30*time.Second), + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *internal.Client +} + +// NewDNSProvider returns a DNSProvider instance configured for Vscale Domains API. +// API token must be passed in the environment variable VSCALE_API_TOKEN. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get(apiTokenEnvVar) + if err != nil { + return nil, fmt.Errorf("vscale: %v", err) + } + + config := NewDefaultConfig() + config.Token = values[apiTokenEnvVar] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Vscale. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("vscale: the configuration of the DNS provider is nil") + } + + if config.Token == "" { + return nil, errors.New("vscale: credentials missing") + } + + if config.TTL < minTTL { + return nil, fmt.Errorf("vscale: invalid TTL, TTL (%d) must be greater than %d", config.TTL, minTTL) + } + + client := internal.NewClient(internal.ClientOpts{ + BaseURL: config.BaseURL, + Token: config.Token, + HTTPClient: config.HTTPClient, + }) + + return &DNSProvider{config: config, client: client}, nil +} + +// Timeout returns the Timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill DNS-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + domainObj, err := d.client.GetDomainByName(domain) + if err != nil { + return fmt.Errorf("vscale: %v", err) + } + + txtRecord := internal.Record{ + Type: "TXT", + TTL: d.config.TTL, + Name: fqdn, + Content: value, + } + _, err = d.client.AddRecord(domainObj.ID, txtRecord) + if err != nil { + return fmt.Errorf("vscale: %v", err) + } + + return nil +} + +// CleanUp removes a TXT record used for DNS-01 challenge. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + fqdn, _ := dns01.GetRecord(domain, keyAuth) + recordName := dns01.UnFqdn(fqdn) + + domainObj, err := d.client.GetDomainByName(domain) + if err != nil { + return fmt.Errorf("vscale: %v", err) + } + + records, err := d.client.ListRecords(domainObj.ID) + if err != nil { + return fmt.Errorf("vscale: %v", err) + } + + // Delete records with specific FQDN + var lastErr error + for _, record := range records { + if record.Name == recordName { + err = d.client.DeleteRecord(domainObj.ID, record.ID) + if err != nil { + lastErr = fmt.Errorf("vscale: %v", err) + } + } + } + + return lastErr +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/vscale.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/vscale.toml new file mode 100644 index 000000000..b86da6507 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/vscale/vscale.toml @@ -0,0 +1,20 @@ +Name = "Vscale" +Description = '''''' +URL = "https://vscale.io/" +Code = "vscale" +Since = "v2.0.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + VSCALE_API_TOKEN = "API token" + [Configuration.Additional] + VSCALE_BASE_URL = "API enddpoint URL" + VSCALE_POLLING_INTERVAL = "Time between DNS propagation check" + VSCALE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + VSCALE_TTL = "The TTL of the TXT record used for the DNS challenge" + VSCALE_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://developers.vscale.io/documentation/api/v1/#api-Domains_Records" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/vultr/vultr.go b/vendor/github.com/go-acme/lego/v3/providers/dns/vultr/vultr.go new file mode 100644 index 000000000..a22c052dd --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/vultr/vultr.go @@ -0,0 +1,182 @@ +// Package vultr implements a DNS provider for solving the DNS-01 challenge using the Vultr DNS. +// See https://www.vultr.com/api/#dns +package vultr + +import ( + "context" + "crypto/tls" + "errors" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" + "github.com/vultr/govultr" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + TTL int + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + return &Config{ + TTL: env.GetOrDefaultInt("VULTR_TTL", dns01.DefaultTTL), + PropagationTimeout: env.GetOrDefaultSecond("VULTR_PROPAGATION_TIMEOUT", dns01.DefaultPropagationTimeout), + PollingInterval: env.GetOrDefaultSecond("VULTR_POLLING_INTERVAL", dns01.DefaultPollingInterval), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("VULTR_HTTP_TIMEOUT", 0), + // from Vultr Client + Transport: &http.Transport{ + TLSNextProto: make(map[string]func(string, *tls.Conn) http.RoundTripper), + }, + }, + } +} + +// DNSProvider is an implementation of the acme.ChallengeProvider interface. +type DNSProvider struct { + config *Config + client *govultr.Client +} + +// NewDNSProvider returns a DNSProvider instance with a configured Vultr client. +// Authentication uses the VULTR_API_KEY environment variable. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("VULTR_API_KEY") + if err != nil { + return nil, fmt.Errorf("vultr: %v", err) + } + + config := NewDefaultConfig() + config.APIKey = values["VULTR_API_KEY"] + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider instance configured for Vultr. +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("vultr: the configuration of the DNS provider is nil") + } + + if config.APIKey == "" { + return nil, fmt.Errorf("vultr: credentials missing") + } + + client := govultr.NewClient(config.HTTPClient, config.APIKey) + + return &DNSProvider{client: client, config: config}, nil +} + +// Present creates a TXT record to fulfill the DNS-01 challenge. +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + ctx := context.Background() + + fqdn, value := dns01.GetRecord(domain, keyAuth) + + zoneDomain, err := d.getHostedZone(ctx, domain) + if err != nil { + return fmt.Errorf("vultr: %v", err) + } + + name := d.extractRecordName(fqdn, zoneDomain) + + err = d.client.DNSRecord.Create(ctx, zoneDomain, "TXT", name, `"`+value+`"`, d.config.TTL, 0) + if err != nil { + return fmt.Errorf("vultr: API call failed: %v", err) + } + + return nil +} + +// CleanUp removes the TXT record matching the specified parameters. +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + ctx := context.Background() + + fqdn, _ := dns01.GetRecord(domain, keyAuth) + + zoneDomain, records, err := d.findTxtRecords(ctx, domain, fqdn) + if err != nil { + return fmt.Errorf("vultr: %v", err) + } + + var allErr []string + for _, rec := range records { + err := d.client.DNSRecord.Delete(ctx, zoneDomain, strconv.Itoa(rec.RecordID)) + if err != nil { + allErr = append(allErr, err.Error()) + } + } + + if len(allErr) > 0 { + return errors.New(strings.Join(allErr, ": ")) + } + + return nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +func (d *DNSProvider) getHostedZone(ctx context.Context, domain string) (string, error) { + domains, err := d.client.DNSDomain.List(ctx) + if err != nil { + return "", fmt.Errorf("API call failed: %v", err) + } + + var hostedDomain govultr.DNSDomain + for _, dom := range domains { + if strings.HasSuffix(domain, dom.Domain) { + if len(dom.Domain) > len(hostedDomain.Domain) { + hostedDomain = dom + } + } + } + if hostedDomain.Domain == "" { + return "", fmt.Errorf("no matching Vultr domain found for domain %s", domain) + } + + return hostedDomain.Domain, nil +} + +func (d *DNSProvider) findTxtRecords(ctx context.Context, domain, fqdn string) (string, []govultr.DNSRecord, error) { + zoneDomain, err := d.getHostedZone(ctx, domain) + if err != nil { + return "", nil, err + } + + var records []govultr.DNSRecord + result, err := d.client.DNSRecord.List(ctx, zoneDomain) + if err != nil { + return "", records, fmt.Errorf("API call has failed: %v", err) + } + + recordName := d.extractRecordName(fqdn, zoneDomain) + for _, record := range result { + if record.Type == "TXT" && record.Name == recordName { + records = append(records, record) + } + } + + return zoneDomain, records, nil +} + +func (d *DNSProvider) extractRecordName(fqdn, domain string) string { + name := dns01.UnFqdn(fqdn) + if idx := strings.Index(name, "."+domain); idx != -1 { + return name[:idx] + } + return name +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/vultr/vultr.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/vultr/vultr.toml new file mode 100644 index 000000000..8e59a0d5e --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/vultr/vultr.toml @@ -0,0 +1,20 @@ +Name = "Vultr" +Description = '''''' +URL = "https://www.vultr.com/" +Code = "vultr" +Since = "v0.3.1" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + VULTR_API_KEY = "API key" + [Configuration.Additional] + VULTR_POLLING_INTERVAL = "Time between DNS propagation check" + VULTR_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + VULTR_TTL = "The TTL of the TXT record used for the DNS challenge" + VULTR_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://www.vultr.com/api/#dns" + GoClient = "https://github.com/vultr/govultr" diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/client.go b/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/client.go new file mode 100644 index 000000000..b48808b84 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/client.go @@ -0,0 +1,132 @@ +package zoneee + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "path" +) + +const defaultEndpoint = "https://api.zone.eu/v2/dns/" + +type txtRecord struct { + // Identifier (identificator) + ID string `json:"id,omitempty"` + // Hostname + Name string `json:"name"` + // TXT content value + Destination string `json:"destination"` + // Can this record be deleted + Delete bool `json:"delete,omitempty"` + // Can this record be modified + Modify bool `json:"modify,omitempty"` + // API url to get this entity + ResourceURL string `json:"resource_url,omitempty"` +} + +func (d *DNSProvider) addTxtRecord(domain string, record txtRecord) ([]txtRecord, error) { + reqBody := &bytes.Buffer{} + if err := json.NewEncoder(reqBody).Encode(record); err != nil { + return nil, err + } + + req, err := d.makeRequest(http.MethodPost, path.Join(domain, "txt"), reqBody) + if err != nil { + return nil, err + } + + var resp []txtRecord + if err := d.sendRequest(req, &resp); err != nil { + return nil, err + } + return resp, nil +} + +func (d *DNSProvider) getTxtRecords(domain string) ([]txtRecord, error) { + req, err := d.makeRequest(http.MethodGet, path.Join(domain, "txt"), nil) + if err != nil { + return nil, err + } + + var resp []txtRecord + if err := d.sendRequest(req, &resp); err != nil { + return nil, err + } + return resp, nil +} + +func (d *DNSProvider) removeTxtRecord(domain, id string) error { + req, err := d.makeRequest(http.MethodDelete, path.Join(domain, "txt", id), nil) + if err != nil { + return err + } + + return d.sendRequest(req, nil) +} + +func (d *DNSProvider) makeRequest(method, resource string, body io.Reader) (*http.Request, error) { + uri, err := d.config.Endpoint.Parse(resource) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, uri.String(), body) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + req.SetBasicAuth(d.config.Username, d.config.APIKey) + + return req, nil +} + +func (d *DNSProvider) sendRequest(req *http.Request, result interface{}) error { + resp, err := d.config.HTTPClient.Do(req) + if err != nil { + return err + } + + if err = checkResponse(resp); err != nil { + return err + } + + defer resp.Body.Close() + + if result == nil { + return nil + } + + raw, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + err = json.Unmarshal(raw, result) + if err != nil { + return fmt.Errorf("unmarshaling %T error [status code=%d]: %v: %s", result, resp.StatusCode, err, string(raw)) + } + return err +} + +func checkResponse(resp *http.Response) error { + if resp.StatusCode < http.StatusBadRequest { + return nil + } + + if resp.Body == nil { + return fmt.Errorf("response body is nil, status code=%d", resp.StatusCode) + } + + defer resp.Body.Close() + + raw, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("unable to read body: status code=%d, error=%v", resp.StatusCode, err) + } + + return fmt.Errorf("status code=%d: %s", resp.StatusCode, string(raw)) +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/zoneee.go b/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/zoneee.go new file mode 100644 index 000000000..6fc6880b7 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/zoneee.go @@ -0,0 +1,134 @@ +// Package zoneee implements a DNS provider for solving the DNS-01 challenge through zone.ee. +package zoneee + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/go-acme/lego/v3/challenge/dns01" + "github.com/go-acme/lego/v3/platform/config/env" +) + +// Config is used to configure the creation of the DNSProvider +type Config struct { + Endpoint *url.URL + Username string + APIKey string + PropagationTimeout time.Duration + PollingInterval time.Duration + HTTPClient *http.Client +} + +// NewDefaultConfig returns a default configuration for the DNSProvider +func NewDefaultConfig() *Config { + endpoint, _ := url.Parse(defaultEndpoint) + + return &Config{ + Endpoint: endpoint, + // zone.ee can take up to 5min to propagate according to the support + PropagationTimeout: env.GetOrDefaultSecond("ZONEEE_PROPAGATION_TIMEOUT", 5*time.Minute), + PollingInterval: env.GetOrDefaultSecond("ZONEEE_POLLING_INTERVAL", 5*time.Second), + HTTPClient: &http.Client{ + Timeout: env.GetOrDefaultSecond("ZONEEE_HTTP_TIMEOUT", 30*time.Second), + }, + } +} + +// DNSProvider describes a provider for acme-proxy +type DNSProvider struct { + config *Config +} + +// NewDNSProvider returns a DNSProvider instance. +func NewDNSProvider() (*DNSProvider, error) { + values, err := env.Get("ZONEEE_API_USER", "ZONEEE_API_KEY") + if err != nil { + return nil, fmt.Errorf("zoneee: %v", err) + } + + rawEndpoint := env.GetOrDefaultString("ZONEEE_ENDPOINT", defaultEndpoint) + endpoint, err := url.Parse(rawEndpoint) + if err != nil { + return nil, fmt.Errorf("zoneee: %v", err) + } + + config := NewDefaultConfig() + config.Username = values["ZONEEE_API_USER"] + config.APIKey = values["ZONEEE_API_KEY"] + config.Endpoint = endpoint + + return NewDNSProviderConfig(config) +} + +// NewDNSProviderConfig return a DNSProvider . +func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { + if config == nil { + return nil, errors.New("zoneee: the configuration of the DNS provider is nil") + } + + if config.Username == "" { + return nil, fmt.Errorf("zoneee: credentials missing: username") + } + + if config.APIKey == "" { + return nil, fmt.Errorf("zoneee: credentials missing: API key") + } + + if config.Endpoint == nil { + return nil, errors.New("zoneee: the endpoint is missing") + } + + return &DNSProvider{config: config}, nil +} + +// Timeout returns the timeout and interval to use when checking for DNS propagation. +// Adjusting here to cope with spikes in propagation times. +func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { + return d.config.PropagationTimeout, d.config.PollingInterval +} + +// Present creates a TXT record to fulfill the dns-01 challenge +func (d *DNSProvider) Present(domain, token, keyAuth string) error { + fqdn, value := dns01.GetRecord(domain, keyAuth) + + record := txtRecord{ + Name: fqdn[:len(fqdn)-1], + Destination: value, + } + + _, err := d.addTxtRecord(domain, record) + if err != nil { + return fmt.Errorf("zoneee: %v", err) + } + return nil +} + +// CleanUp removes the TXT record previously created +func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { + _, value := dns01.GetRecord(domain, keyAuth) + + records, err := d.getTxtRecords(domain) + if err != nil { + return fmt.Errorf("zoneee: %v", err) + } + + var id string + for _, record := range records { + if record.Destination == value { + id = record.ID + } + } + + if id == "" { + return fmt.Errorf("zoneee: txt record does not exist for %v", value) + } + + if err = d.removeTxtRecord(domain, id); err != nil { + return fmt.Errorf("zoneee: %v", err) + } + + return nil +} diff --git a/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/zoneee.toml b/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/zoneee.toml new file mode 100644 index 000000000..fbff725c4 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/dns/zoneee/zoneee.toml @@ -0,0 +1,21 @@ +Name = "Zone.ee" +Description = '''''' +URL = "https://www.zone.ee/" +Code = "zoneee" +Since = "v2.1.0" + +Example = '''''' + +[Configuration] + [Configuration.Credentials] + ZONEEE_API_USER = "API user" + ZONEEE_API_KEY = "API key" + [Configuration.Additional] + ZONEEE_ENDPOINT = "API endpoint URL" + ZONEEE_POLLING_INTERVAL = "Time between DNS propagation check" + ZONEEE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" + ZONEEE_TTL = "The TTL of the TXT record used for the DNS challenge" + ZONEEE_HTTP_TIMEOUT = "API request timeout" + +[Links] + API = "https://api.zone.eu/v2" diff --git a/vendor/github.com/go-acme/lego/v3/providers/http/webroot/webroot.go b/vendor/github.com/go-acme/lego/v3/providers/http/webroot/webroot.go new file mode 100644 index 000000000..14dcd2cd6 --- /dev/null +++ b/vendor/github.com/go-acme/lego/v3/providers/http/webroot/webroot.go @@ -0,0 +1,53 @@ +// Package webroot implements a HTTP provider for solving the HTTP-01 challenge using web server's root path. +package webroot + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/go-acme/lego/v3/challenge/http01" +) + +// HTTPProvider implements ChallengeProvider for `http-01` challenge +type HTTPProvider struct { + path string +} + +// NewHTTPProvider returns a HTTPProvider instance with a configured webroot path +func NewHTTPProvider(path string) (*HTTPProvider, error) { + if _, err := os.Stat(path); os.IsNotExist(err) { + return nil, fmt.Errorf("webroot path does not exist") + } + + return &HTTPProvider{path: path}, nil +} + +// Present makes the token available at `HTTP01ChallengePath(token)` by creating a file in the given webroot path +func (w *HTTPProvider) Present(domain, token, keyAuth string) error { + var err error + + challengeFilePath := filepath.Join(w.path, http01.ChallengePath(token)) + err = os.MkdirAll(filepath.Dir(challengeFilePath), 0755) + if err != nil { + return fmt.Errorf("could not create required directories in webroot for HTTP challenge -> %v", err) + } + + err = ioutil.WriteFile(challengeFilePath, []byte(keyAuth), 0644) + if err != nil { + return fmt.Errorf("could not write file in webroot for HTTP challenge -> %v", err) + } + + return nil +} + +// CleanUp removes the file created for the challenge +func (w *HTTPProvider) CleanUp(domain, token, keyAuth string) error { + err := os.Remove(filepath.Join(w.path, http01.ChallengePath(token))) + if err != nil { + return fmt.Errorf("could not remove file in webroot after HTTP challenge -> %v", err) + } + + return nil +} diff --git a/vendor/github.com/go-errors/errors/.travis.yml b/vendor/github.com/go-errors/errors/.travis.yml new file mode 100644 index 000000000..9d00fdd5d --- /dev/null +++ b/vendor/github.com/go-errors/errors/.travis.yml @@ -0,0 +1,5 @@ +language: go + +go: + - "1.8.x" + - "1.10.x" diff --git a/vendor/github.com/go-errors/errors/LICENSE.MIT b/vendor/github.com/go-errors/errors/LICENSE.MIT new file mode 100644 index 000000000..c9a5b2eeb --- /dev/null +++ b/vendor/github.com/go-errors/errors/LICENSE.MIT @@ -0,0 +1,7 @@ +Copyright (c) 2015 Conrad Irwin + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/go-errors/errors/README.md b/vendor/github.com/go-errors/errors/README.md new file mode 100644 index 000000000..5d4f1873d --- /dev/null +++ b/vendor/github.com/go-errors/errors/README.md @@ -0,0 +1,66 @@ +go-errors/errors +================ + +[![Build Status](https://travis-ci.org/go-errors/errors.svg?branch=master)](https://travis-ci.org/go-errors/errors) + +Package errors adds stacktrace support to errors in go. + +This is particularly useful when you want to understand the state of execution +when an error was returned unexpectedly. + +It provides the type \*Error which implements the standard golang error +interface, so you can use this library interchangably with code that is +expecting a normal error return. + +Usage +----- + +Full documentation is available on +[godoc](https://godoc.org/github.com/go-errors/errors), but here's a simple +example: + +```go +package crashy + +import "github.com/go-errors/errors" + +var Crashed = errors.Errorf("oh dear") + +func Crash() error { + return errors.New(Crashed) +} +``` + +This can be called as follows: + +```go +package main + +import ( + "crashy" + "fmt" + "github.com/go-errors/errors" +) + +func main() { + err := crashy.Crash() + if err != nil { + if errors.Is(err, crashy.Crashed) { + fmt.Println(err.(*errors.Error).ErrorStack()) + } else { + panic(err) + } + } +} +``` + +Meta-fu +------- + +This package was original written to allow reporting to +[Bugsnag](https://bugsnag.com/) from +[bugsnag-go](https://github.com/bugsnag/bugsnag-go), but after I found similar +packages by Facebook and Dropbox, it was moved to one canonical location so +everyone can benefit. + +This package is licensed under the MIT license, see LICENSE.MIT for details. diff --git a/vendor/github.com/go-errors/errors/cover.out b/vendor/github.com/go-errors/errors/cover.out new file mode 100644 index 000000000..ab18b0519 --- /dev/null +++ b/vendor/github.com/go-errors/errors/cover.out @@ -0,0 +1,89 @@ +mode: set +github.com/go-errors/errors/stackframe.go:27.51,30.25 2 1 +github.com/go-errors/errors/stackframe.go:33.2,38.8 3 1 +github.com/go-errors/errors/stackframe.go:30.25,32.3 1 0 +github.com/go-errors/errors/stackframe.go:43.47,44.31 1 1 +github.com/go-errors/errors/stackframe.go:47.2,47.48 1 1 +github.com/go-errors/errors/stackframe.go:44.31,46.3 1 1 +github.com/go-errors/errors/stackframe.go:52.42,56.16 3 1 +github.com/go-errors/errors/stackframe.go:60.2,60.60 1 1 +github.com/go-errors/errors/stackframe.go:56.16,58.3 1 0 +github.com/go-errors/errors/stackframe.go:64.55,67.16 2 1 +github.com/go-errors/errors/stackframe.go:71.2,72.61 2 1 +github.com/go-errors/errors/stackframe.go:76.2,76.66 1 1 +github.com/go-errors/errors/stackframe.go:67.16,69.3 1 0 +github.com/go-errors/errors/stackframe.go:72.61,74.3 1 0 +github.com/go-errors/errors/stackframe.go:79.56,91.63 3 1 +github.com/go-errors/errors/stackframe.go:95.2,95.53 1 1 +github.com/go-errors/errors/stackframe.go:100.2,101.18 2 1 +github.com/go-errors/errors/stackframe.go:91.63,94.3 2 1 +github.com/go-errors/errors/stackframe.go:95.53,98.3 2 1 +github.com/go-errors/errors/error.go:70.32,73.23 2 1 +github.com/go-errors/errors/error.go:80.2,85.3 3 1 +github.com/go-errors/errors/error.go:74.2,75.10 1 1 +github.com/go-errors/errors/error.go:76.2,77.28 1 1 +github.com/go-errors/errors/error.go:92.43,95.23 2 1 +github.com/go-errors/errors/error.go:104.2,109.3 3 1 +github.com/go-errors/errors/error.go:96.2,97.11 1 1 +github.com/go-errors/errors/error.go:98.2,99.10 1 1 +github.com/go-errors/errors/error.go:100.2,101.28 1 1 +github.com/go-errors/errors/error.go:115.39,117.19 1 1 +github.com/go-errors/errors/error.go:121.2,121.29 1 1 +github.com/go-errors/errors/error.go:125.2,125.43 1 1 +github.com/go-errors/errors/error.go:129.2,129.14 1 1 +github.com/go-errors/errors/error.go:117.19,119.3 1 1 +github.com/go-errors/errors/error.go:121.29,123.3 1 1 +github.com/go-errors/errors/error.go:125.43,127.3 1 1 +github.com/go-errors/errors/error.go:135.53,137.2 1 1 +github.com/go-errors/errors/error.go:140.34,142.2 1 1 +github.com/go-errors/errors/error.go:146.34,149.42 2 1 +github.com/go-errors/errors/error.go:153.2,153.20 1 1 +github.com/go-errors/errors/error.go:149.42,151.3 1 1 +github.com/go-errors/errors/error.go:158.39,160.2 1 1 +github.com/go-errors/errors/error.go:164.46,165.23 1 1 +github.com/go-errors/errors/error.go:173.2,173.19 1 1 +github.com/go-errors/errors/error.go:165.23,168.32 2 1 +github.com/go-errors/errors/error.go:168.32,170.4 1 1 +github.com/go-errors/errors/error.go:177.37,178.42 1 1 +github.com/go-errors/errors/error.go:181.2,181.41 1 1 +github.com/go-errors/errors/error.go:178.42,180.3 1 1 +github.com/go-errors/errors/parse_panic.go:10.39,12.2 1 1 +github.com/go-errors/errors/parse_panic.go:16.46,24.34 5 1 +github.com/go-errors/errors/parse_panic.go:70.2,70.43 1 1 +github.com/go-errors/errors/parse_panic.go:73.2,73.55 1 0 +github.com/go-errors/errors/parse_panic.go:24.34,27.23 2 1 +github.com/go-errors/errors/parse_panic.go:27.23,28.42 1 1 +github.com/go-errors/errors/parse_panic.go:28.42,31.5 2 1 +github.com/go-errors/errors/parse_panic.go:31.6,33.5 1 0 +github.com/go-errors/errors/parse_panic.go:35.5,35.29 1 1 +github.com/go-errors/errors/parse_panic.go:35.29,36.86 1 1 +github.com/go-errors/errors/parse_panic.go:36.86,38.5 1 1 +github.com/go-errors/errors/parse_panic.go:40.5,40.32 1 1 +github.com/go-errors/errors/parse_panic.go:40.32,41.18 1 1 +github.com/go-errors/errors/parse_panic.go:45.4,46.46 2 1 +github.com/go-errors/errors/parse_panic.go:51.4,53.23 2 1 +github.com/go-errors/errors/parse_panic.go:57.4,58.18 2 1 +github.com/go-errors/errors/parse_panic.go:62.4,63.17 2 1 +github.com/go-errors/errors/parse_panic.go:41.18,43.10 2 1 +github.com/go-errors/errors/parse_panic.go:46.46,49.5 2 1 +github.com/go-errors/errors/parse_panic.go:53.23,55.5 1 0 +github.com/go-errors/errors/parse_panic.go:58.18,60.5 1 0 +github.com/go-errors/errors/parse_panic.go:63.17,65.10 2 1 +github.com/go-errors/errors/parse_panic.go:70.43,72.3 1 1 +github.com/go-errors/errors/parse_panic.go:80.85,82.29 2 1 +github.com/go-errors/errors/parse_panic.go:85.2,85.15 1 1 +github.com/go-errors/errors/parse_panic.go:88.2,90.63 2 1 +github.com/go-errors/errors/parse_panic.go:94.2,94.53 1 1 +github.com/go-errors/errors/parse_panic.go:99.2,101.36 2 1 +github.com/go-errors/errors/parse_panic.go:105.2,106.15 2 1 +github.com/go-errors/errors/parse_panic.go:109.2,112.49 3 1 +github.com/go-errors/errors/parse_panic.go:116.2,117.16 2 1 +github.com/go-errors/errors/parse_panic.go:121.2,126.8 1 1 +github.com/go-errors/errors/parse_panic.go:82.29,84.3 1 0 +github.com/go-errors/errors/parse_panic.go:85.15,87.3 1 1 +github.com/go-errors/errors/parse_panic.go:90.63,93.3 2 1 +github.com/go-errors/errors/parse_panic.go:94.53,97.3 2 1 +github.com/go-errors/errors/parse_panic.go:101.36,103.3 1 0 +github.com/go-errors/errors/parse_panic.go:106.15,108.3 1 0 +github.com/go-errors/errors/parse_panic.go:112.49,114.3 1 1 +github.com/go-errors/errors/parse_panic.go:117.16,119.3 1 0 diff --git a/vendor/github.com/go-errors/errors/error.go b/vendor/github.com/go-errors/errors/error.go new file mode 100644 index 000000000..60062a437 --- /dev/null +++ b/vendor/github.com/go-errors/errors/error.go @@ -0,0 +1,217 @@ +// Package errors provides errors that have stack-traces. +// +// This is particularly useful when you want to understand the +// state of execution when an error was returned unexpectedly. +// +// It provides the type *Error which implements the standard +// golang error interface, so you can use this library interchangably +// with code that is expecting a normal error return. +// +// For example: +// +// package crashy +// +// import "github.com/go-errors/errors" +// +// var Crashed = errors.Errorf("oh dear") +// +// func Crash() error { +// return errors.New(Crashed) +// } +// +// This can be called as follows: +// +// package main +// +// import ( +// "crashy" +// "fmt" +// "github.com/go-errors/errors" +// ) +// +// func main() { +// err := crashy.Crash() +// if err != nil { +// if errors.Is(err, crashy.Crashed) { +// fmt.Println(err.(*errors.Error).ErrorStack()) +// } else { +// panic(err) +// } +// } +// } +// +// This package was original written to allow reporting to Bugsnag, +// but after I found similar packages by Facebook and Dropbox, it +// was moved to one canonical location so everyone can benefit. +package errors + +import ( + "bytes" + "fmt" + "reflect" + "runtime" +) + +// The maximum number of stackframes on any error. +var MaxStackDepth = 50 + +// Error is an error with an attached stacktrace. It can be used +// wherever the builtin error interface is expected. +type Error struct { + Err error + stack []uintptr + frames []StackFrame + prefix string +} + +// New makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The stacktrace will point to the line of code that +// called New. +func New(e interface{}) *Error { + var err error + + switch e := e.(type) { + case error: + err = e + default: + err = fmt.Errorf("%v", e) + } + + stack := make([]uintptr, MaxStackDepth) + length := runtime.Callers(2, stack[:]) + return &Error{ + Err: err, + stack: stack[:length], + } +} + +// Wrap makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The skip parameter indicates how far up the stack +// to start the stacktrace. 0 is from the current call, 1 from its caller, etc. +func Wrap(e interface{}, skip int) *Error { + var err error + + switch e := e.(type) { + case *Error: + return e + case error: + err = e + default: + err = fmt.Errorf("%v", e) + } + + stack := make([]uintptr, MaxStackDepth) + length := runtime.Callers(2+skip, stack[:]) + return &Error{ + Err: err, + stack: stack[:length], + } +} + +// WrapPrefix makes an Error from the given value. If that value is already an +// error then it will be used directly, if not, it will be passed to +// fmt.Errorf("%v"). The prefix parameter is used to add a prefix to the +// error message when calling Error(). The skip parameter indicates how far +// up the stack to start the stacktrace. 0 is from the current call, +// 1 from its caller, etc. +func WrapPrefix(e interface{}, prefix string, skip int) *Error { + + err := Wrap(e, 1+skip) + + if err.prefix != "" { + prefix = fmt.Sprintf("%s: %s", prefix, err.prefix) + } + + return &Error{ + Err: err.Err, + stack: err.stack, + prefix: prefix, + } + +} + +// Is detects whether the error is equal to a given error. Errors +// are considered equal by this function if they are the same object, +// or if they both contain the same error inside an errors.Error. +func Is(e error, original error) bool { + + if e == original { + return true + } + + if e, ok := e.(*Error); ok { + return Is(e.Err, original) + } + + if original, ok := original.(*Error); ok { + return Is(e, original.Err) + } + + return false +} + +// Errorf creates a new error with the given message. You can use it +// as a drop-in replacement for fmt.Errorf() to provide descriptive +// errors in return values. +func Errorf(format string, a ...interface{}) *Error { + return Wrap(fmt.Errorf(format, a...), 1) +} + +// Error returns the underlying error's message. +func (err *Error) Error() string { + + msg := err.Err.Error() + if err.prefix != "" { + msg = fmt.Sprintf("%s: %s", err.prefix, msg) + } + + return msg +} + +// Stack returns the callstack formatted the same way that go does +// in runtime/debug.Stack() +func (err *Error) Stack() []byte { + buf := bytes.Buffer{} + + for _, frame := range err.StackFrames() { + buf.WriteString(frame.String()) + } + + return buf.Bytes() +} + +// Callers satisfies the bugsnag ErrorWithCallerS() interface +// so that the stack can be read out. +func (err *Error) Callers() []uintptr { + return err.stack +} + +// ErrorStack returns a string that contains both the +// error message and the callstack. +func (err *Error) ErrorStack() string { + return err.TypeName() + " " + err.Error() + "\n" + string(err.Stack()) +} + +// StackFrames returns an array of frames containing information about the +// stack. +func (err *Error) StackFrames() []StackFrame { + if err.frames == nil { + err.frames = make([]StackFrame, len(err.stack)) + + for i, pc := range err.stack { + err.frames[i] = NewStackFrame(pc) + } + } + + return err.frames +} + +// TypeName returns the type this error. e.g. *errors.stringError. +func (err *Error) TypeName() string { + if _, ok := err.Err.(uncaughtPanic); ok { + return "panic" + } + return reflect.TypeOf(err.Err).String() +} diff --git a/vendor/github.com/go-errors/errors/parse_panic.go b/vendor/github.com/go-errors/errors/parse_panic.go new file mode 100644 index 000000000..cc37052d7 --- /dev/null +++ b/vendor/github.com/go-errors/errors/parse_panic.go @@ -0,0 +1,127 @@ +package errors + +import ( + "strconv" + "strings" +) + +type uncaughtPanic struct{ message string } + +func (p uncaughtPanic) Error() string { + return p.message +} + +// ParsePanic allows you to get an error object from the output of a go program +// that panicked. This is particularly useful with https://github.com/mitchellh/panicwrap. +func ParsePanic(text string) (*Error, error) { + lines := strings.Split(text, "\n") + + state := "start" + + var message string + var stack []StackFrame + + for i := 0; i < len(lines); i++ { + line := lines[i] + + if state == "start" { + if strings.HasPrefix(line, "panic: ") { + message = strings.TrimPrefix(line, "panic: ") + state = "seek" + } else { + return nil, Errorf("bugsnag.panicParser: Invalid line (no prefix): %s", line) + } + + } else if state == "seek" { + if strings.HasPrefix(line, "goroutine ") && strings.HasSuffix(line, "[running]:") { + state = "parsing" + } + + } else if state == "parsing" { + if line == "" { + state = "done" + break + } + createdBy := false + if strings.HasPrefix(line, "created by ") { + line = strings.TrimPrefix(line, "created by ") + createdBy = true + } + + i++ + + if i >= len(lines) { + return nil, Errorf("bugsnag.panicParser: Invalid line (unpaired): %s", line) + } + + frame, err := parsePanicFrame(line, lines[i], createdBy) + if err != nil { + return nil, err + } + + stack = append(stack, *frame) + if createdBy { + state = "done" + break + } + } + } + + if state == "done" || state == "parsing" { + return &Error{Err: uncaughtPanic{message}, frames: stack}, nil + } + return nil, Errorf("could not parse panic: %v", text) +} + +// The lines we're passing look like this: +// +// main.(*foo).destruct(0xc208067e98) +// /0/go/src/github.com/bugsnag/bugsnag-go/pan/main.go:22 +0x151 +func parsePanicFrame(name string, line string, createdBy bool) (*StackFrame, error) { + idx := strings.LastIndex(name, "(") + if idx == -1 && !createdBy { + return nil, Errorf("bugsnag.panicParser: Invalid line (no call): %s", name) + } + if idx != -1 { + name = name[:idx] + } + pkg := "" + + if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { + pkg += name[:lastslash] + "/" + name = name[lastslash+1:] + } + if period := strings.Index(name, "."); period >= 0 { + pkg += name[:period] + name = name[period+1:] + } + + name = strings.Replace(name, "·", ".", -1) + + if !strings.HasPrefix(line, "\t") { + return nil, Errorf("bugsnag.panicParser: Invalid line (no tab): %s", line) + } + + idx = strings.LastIndex(line, ":") + if idx == -1 { + return nil, Errorf("bugsnag.panicParser: Invalid line (no line number): %s", line) + } + file := line[1:idx] + + number := line[idx+1:] + if idx = strings.Index(number, " +"); idx > -1 { + number = number[:idx] + } + + lno, err := strconv.ParseInt(number, 10, 32) + if err != nil { + return nil, Errorf("bugsnag.panicParser: Invalid line (bad line number): %s", line) + } + + return &StackFrame{ + File: file, + LineNumber: int(lno), + Package: pkg, + Name: name, + }, nil +} diff --git a/vendor/github.com/go-errors/errors/stackframe.go b/vendor/github.com/go-errors/errors/stackframe.go new file mode 100644 index 000000000..750ab9a52 --- /dev/null +++ b/vendor/github.com/go-errors/errors/stackframe.go @@ -0,0 +1,102 @@ +package errors + +import ( + "bytes" + "fmt" + "io/ioutil" + "runtime" + "strings" +) + +// A StackFrame contains all necessary information about to generate a line +// in a callstack. +type StackFrame struct { + // The path to the file containing this ProgramCounter + File string + // The LineNumber in that file + LineNumber int + // The Name of the function that contains this ProgramCounter + Name string + // The Package that contains this function + Package string + // The underlying ProgramCounter + ProgramCounter uintptr +} + +// NewStackFrame popoulates a stack frame object from the program counter. +func NewStackFrame(pc uintptr) (frame StackFrame) { + + frame = StackFrame{ProgramCounter: pc} + if frame.Func() == nil { + return + } + frame.Package, frame.Name = packageAndName(frame.Func()) + + // pc -1 because the program counters we use are usually return addresses, + // and we want to show the line that corresponds to the function call + frame.File, frame.LineNumber = frame.Func().FileLine(pc - 1) + return + +} + +// Func returns the function that contained this frame. +func (frame *StackFrame) Func() *runtime.Func { + if frame.ProgramCounter == 0 { + return nil + } + return runtime.FuncForPC(frame.ProgramCounter) +} + +// String returns the stackframe formatted in the same way as go does +// in runtime/debug.Stack() +func (frame *StackFrame) String() string { + str := fmt.Sprintf("%s:%d (0x%x)\n", frame.File, frame.LineNumber, frame.ProgramCounter) + + source, err := frame.SourceLine() + if err != nil { + return str + } + + return str + fmt.Sprintf("\t%s: %s\n", frame.Name, source) +} + +// SourceLine gets the line of code (from File and Line) of the original source if possible. +func (frame *StackFrame) SourceLine() (string, error) { + data, err := ioutil.ReadFile(frame.File) + + if err != nil { + return "", New(err) + } + + lines := bytes.Split(data, []byte{'\n'}) + if frame.LineNumber <= 0 || frame.LineNumber >= len(lines) { + return "???", nil + } + // -1 because line-numbers are 1 based, but our array is 0 based + return string(bytes.Trim(lines[frame.LineNumber-1], " \t")), nil +} + +func packageAndName(fn *runtime.Func) (string, string) { + name := fn.Name() + pkg := "" + + // The name includes the path name to the package, which is unnecessary + // since the file name is already included. Plus, it has center dots. + // That is, we see + // runtime/debug.*T·ptrmethod + // and want + // *T.ptrmethod + // Since the package path might contains dots (e.g. code.google.com/...), + // we first remove the path prefix if there is one. + if lastslash := strings.LastIndex(name, "/"); lastslash >= 0 { + pkg += name[:lastslash] + "/" + name = name[lastslash+1:] + } + if period := strings.Index(name, "."); period >= 0 { + pkg += name[:period] + name = name[period+1:] + } + + name = strings.Replace(name, "·", ".", -1) + return pkg, name +} diff --git a/vendor/github.com/go-ini/ini/.gitignore b/vendor/github.com/go-ini/ini/.gitignore new file mode 100644 index 000000000..12411127b --- /dev/null +++ b/vendor/github.com/go-ini/ini/.gitignore @@ -0,0 +1,6 @@ +testdata/conf_out.ini +ini.sublime-project +ini.sublime-workspace +testdata/conf_reflect.ini +.idea +/.vscode diff --git a/vendor/github.com/go-ini/ini/.travis.yml b/vendor/github.com/go-ini/ini/.travis.yml new file mode 100644 index 000000000..17d3dc5a9 --- /dev/null +++ b/vendor/github.com/go-ini/ini/.travis.yml @@ -0,0 +1,18 @@ +sudo: false +language: go +go: + - 1.6.x + - 1.7.x + - 1.8.x + - 1.9.x + - 1.10.x + - 1.11.x + - 1.12.x + +script: + - go get golang.org/x/tools/cmd/cover + - go get github.com/smartystreets/goconvey + - mkdir -p $HOME/gopath/src/gopkg.in + - ln -s $HOME/gopath/src/github.com/go-ini/ini $HOME/gopath/src/gopkg.in/ini.v1 + - cd $HOME/gopath/src/gopkg.in/ini.v1 + - go test -v -cover -race diff --git a/vendor/github.com/go-ini/ini/LICENSE b/vendor/github.com/go-ini/ini/LICENSE new file mode 100644 index 000000000..d361bbcdf --- /dev/null +++ b/vendor/github.com/go-ini/ini/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright 2014 Unknwon + + 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. diff --git a/vendor/github.com/go-ini/ini/Makefile b/vendor/github.com/go-ini/ini/Makefile new file mode 100644 index 000000000..af27ff076 --- /dev/null +++ b/vendor/github.com/go-ini/ini/Makefile @@ -0,0 +1,15 @@ +.PHONY: build test bench vet coverage + +build: vet bench + +test: + go test -v -cover -race + +bench: + go test -v -cover -race -test.bench=. -test.benchmem + +vet: + go vet + +coverage: + go test -coverprofile=c.out && go tool cover -html=c.out && rm c.out diff --git a/vendor/github.com/go-ini/ini/README.md b/vendor/github.com/go-ini/ini/README.md new file mode 100644 index 000000000..ae4dfc3a5 --- /dev/null +++ b/vendor/github.com/go-ini/ini/README.md @@ -0,0 +1,46 @@ +INI [![Build Status](https://travis-ci.org/go-ini/ini.svg?branch=master)](https://travis-ci.org/go-ini/ini) [![Sourcegraph](https://img.shields.io/badge/view%20on-Sourcegraph-brightgreen.svg)](https://sourcegraph.com/github.com/go-ini/ini) +=== + +![](https://avatars0.githubusercontent.com/u/10216035?v=3&s=200) + +Package ini provides INI file read and write functionality in Go. + +## Features + +- Load from multiple data sources(`[]byte`, file and `io.ReadCloser`) with overwrites. +- Read with recursion values. +- Read with parent-child sections. +- Read with auto-increment key names. +- Read with multiple-line values. +- Read with tons of helper methods. +- Read and convert values to Go types. +- Read and **WRITE** comments of sections and keys. +- Manipulate sections, keys and comments with ease. +- Keep sections and keys in order as you parse and save. + +## Installation + +The minimum requirement of Go is **1.6**. + +To use a tagged revision: + +```sh +$ go get gopkg.in/ini.v1 +``` + +To use with latest changes: + +```sh +$ go get github.com/go-ini/ini +``` + +Please add `-u` flag to update in the future. + +## Getting Help + +- [Getting Started](https://ini.unknwon.io/docs/intro/getting_started) +- [API Documentation](https://gowalker.org/gopkg.in/ini.v1) + +## License + +This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text. diff --git a/vendor/github.com/go-ini/ini/error.go b/vendor/github.com/go-ini/ini/error.go new file mode 100644 index 000000000..d88347c54 --- /dev/null +++ b/vendor/github.com/go-ini/ini/error.go @@ -0,0 +1,34 @@ +// Copyright 2016 Unknwon +// +// 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. + +package ini + +import ( + "fmt" +) + +// ErrDelimiterNotFound indicates the error type of no delimiter is found which there should be one. +type ErrDelimiterNotFound struct { + Line string +} + +// IsErrDelimiterNotFound returns true if the given error is an instance of ErrDelimiterNotFound. +func IsErrDelimiterNotFound(err error) bool { + _, ok := err.(ErrDelimiterNotFound) + return ok +} + +func (err ErrDelimiterNotFound) Error() string { + return fmt.Sprintf("key-value delimiter not found: %s", err.Line) +} diff --git a/vendor/github.com/go-ini/ini/file.go b/vendor/github.com/go-ini/ini/file.go new file mode 100644 index 000000000..b38aadd1f --- /dev/null +++ b/vendor/github.com/go-ini/ini/file.go @@ -0,0 +1,418 @@ +// Copyright 2017 Unknwon +// +// 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. + +package ini + +import ( + "bytes" + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "strings" + "sync" +) + +// File represents a combination of a or more INI file(s) in memory. +type File struct { + options LoadOptions + dataSources []dataSource + + // Should make things safe, but sometimes doesn't matter. + BlockMode bool + lock sync.RWMutex + + // To keep data in order. + sectionList []string + // Actual data is stored here. + sections map[string]*Section + + NameMapper + ValueMapper +} + +// newFile initializes File object with given data sources. +func newFile(dataSources []dataSource, opts LoadOptions) *File { + if len(opts.KeyValueDelimiters) == 0 { + opts.KeyValueDelimiters = "=:" + } + return &File{ + BlockMode: true, + dataSources: dataSources, + sections: make(map[string]*Section), + sectionList: make([]string, 0, 10), + options: opts, + } +} + +// Empty returns an empty file object. +func Empty() *File { + // Ignore error here, we sure our data is good. + f, _ := Load([]byte("")) + return f +} + +// NewSection creates a new section. +func (f *File) NewSection(name string) (*Section, error) { + if len(name) == 0 { + return nil, errors.New("error creating new section: empty section name") + } else if f.options.Insensitive && name != DefaultSection { + name = strings.ToLower(name) + } + + if f.BlockMode { + f.lock.Lock() + defer f.lock.Unlock() + } + + if inSlice(name, f.sectionList) { + return f.sections[name], nil + } + + f.sectionList = append(f.sectionList, name) + f.sections[name] = newSection(f, name) + return f.sections[name], nil +} + +// NewRawSection creates a new section with an unparseable body. +func (f *File) NewRawSection(name, body string) (*Section, error) { + section, err := f.NewSection(name) + if err != nil { + return nil, err + } + + section.isRawSection = true + section.rawBody = body + return section, nil +} + +// NewSections creates a list of sections. +func (f *File) NewSections(names ...string) (err error) { + for _, name := range names { + if _, err = f.NewSection(name); err != nil { + return err + } + } + return nil +} + +// GetSection returns section by given name. +func (f *File) GetSection(name string) (*Section, error) { + if len(name) == 0 { + name = DefaultSection + } + if f.options.Insensitive { + name = strings.ToLower(name) + } + + if f.BlockMode { + f.lock.RLock() + defer f.lock.RUnlock() + } + + sec := f.sections[name] + if sec == nil { + return nil, fmt.Errorf("section '%s' does not exist", name) + } + return sec, nil +} + +// Section assumes named section exists and returns a zero-value when not. +func (f *File) Section(name string) *Section { + sec, err := f.GetSection(name) + if err != nil { + // Note: It's OK here because the only possible error is empty section name, + // but if it's empty, this piece of code won't be executed. + sec, _ = f.NewSection(name) + return sec + } + return sec +} + +// Sections returns a list of Section stored in the current instance. +func (f *File) Sections() []*Section { + if f.BlockMode { + f.lock.RLock() + defer f.lock.RUnlock() + } + + sections := make([]*Section, len(f.sectionList)) + for i, name := range f.sectionList { + sections[i] = f.sections[name] + } + return sections +} + +// ChildSections returns a list of child sections of given section name. +func (f *File) ChildSections(name string) []*Section { + return f.Section(name).ChildSections() +} + +// SectionStrings returns list of section names. +func (f *File) SectionStrings() []string { + list := make([]string, len(f.sectionList)) + copy(list, f.sectionList) + return list +} + +// DeleteSection deletes a section. +func (f *File) DeleteSection(name string) { + if f.BlockMode { + f.lock.Lock() + defer f.lock.Unlock() + } + + if len(name) == 0 { + name = DefaultSection + } + + for i, s := range f.sectionList { + if s == name { + f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...) + delete(f.sections, name) + return + } + } +} + +func (f *File) reload(s dataSource) error { + r, err := s.ReadCloser() + if err != nil { + return err + } + defer r.Close() + + return f.parse(r) +} + +// Reload reloads and parses all data sources. +func (f *File) Reload() (err error) { + for _, s := range f.dataSources { + if err = f.reload(s); err != nil { + // In loose mode, we create an empty default section for nonexistent files. + if os.IsNotExist(err) && f.options.Loose { + f.parse(bytes.NewBuffer(nil)) + continue + } + return err + } + } + return nil +} + +// Append appends one or more data sources and reloads automatically. +func (f *File) Append(source interface{}, others ...interface{}) error { + ds, err := parseDataSource(source) + if err != nil { + return err + } + f.dataSources = append(f.dataSources, ds) + for _, s := range others { + ds, err = parseDataSource(s) + if err != nil { + return err + } + f.dataSources = append(f.dataSources, ds) + } + return f.Reload() +} + +func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { + equalSign := DefaultFormatLeft + "=" + DefaultFormatRight + + if PrettyFormat || PrettyEqual { + equalSign = " = " + } + + // Use buffer to make sure target is safe until finish encoding. + buf := bytes.NewBuffer(nil) + for i, sname := range f.sectionList { + sec := f.Section(sname) + if len(sec.Comment) > 0 { + // Support multiline comments + lines := strings.Split(sec.Comment, LineBreak) + for i := range lines { + if lines[i][0] != '#' && lines[i][0] != ';' { + lines[i] = "; " + lines[i] + } else { + lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:]) + } + + if _, err := buf.WriteString(lines[i] + LineBreak); err != nil { + return nil, err + } + } + } + + if i > 0 || DefaultHeader { + if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil { + return nil, err + } + } else { + // Write nothing if default section is empty + if len(sec.keyList) == 0 { + continue + } + } + + if sec.isRawSection { + if _, err := buf.WriteString(sec.rawBody); err != nil { + return nil, err + } + + if PrettySection { + // Put a line between sections + if _, err := buf.WriteString(LineBreak); err != nil { + return nil, err + } + } + continue + } + + // Count and generate alignment length and buffer spaces using the + // longest key. Keys may be modifed if they contain certain characters so + // we need to take that into account in our calculation. + alignLength := 0 + if PrettyFormat { + for _, kname := range sec.keyList { + keyLength := len(kname) + // First case will surround key by ` and second by """ + if strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters) { + keyLength += 2 + } else if strings.Contains(kname, "`") { + keyLength += 6 + } + + if keyLength > alignLength { + alignLength = keyLength + } + } + } + alignSpaces := bytes.Repeat([]byte(" "), alignLength) + + KEY_LIST: + for _, kname := range sec.keyList { + key := sec.Key(kname) + if len(key.Comment) > 0 { + if len(indent) > 0 && sname != DefaultSection { + buf.WriteString(indent) + } + + // Support multiline comments + lines := strings.Split(key.Comment, LineBreak) + for i := range lines { + if lines[i][0] != '#' && lines[i][0] != ';' { + lines[i] = "; " + strings.TrimSpace(lines[i]) + } else { + lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:]) + } + + if _, err := buf.WriteString(lines[i] + LineBreak); err != nil { + return nil, err + } + } + } + + if len(indent) > 0 && sname != DefaultSection { + buf.WriteString(indent) + } + + switch { + case key.isAutoIncrement: + kname = "-" + case strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters): + kname = "`" + kname + "`" + case strings.Contains(kname, "`"): + kname = `"""` + kname + `"""` + } + + for _, val := range key.ValueWithShadows() { + if _, err := buf.WriteString(kname); err != nil { + return nil, err + } + + if key.isBooleanType { + if kname != sec.keyList[len(sec.keyList)-1] { + buf.WriteString(LineBreak) + } + continue KEY_LIST + } + + // Write out alignment spaces before "=" sign + if PrettyFormat { + buf.Write(alignSpaces[:alignLength-len(kname)]) + } + + // In case key value contains "\n", "`", "\"", "#" or ";" + if strings.ContainsAny(val, "\n`") { + val = `"""` + val + `"""` + } else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") { + val = "`" + val + "`" + } + if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil { + return nil, err + } + } + + for _, val := range key.nestedValues { + if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil { + return nil, err + } + } + } + + if PrettySection { + // Put a line between sections + if _, err := buf.WriteString(LineBreak); err != nil { + return nil, err + } + } + } + + return buf, nil +} + +// WriteToIndent writes content into io.Writer with given indention. +// If PrettyFormat has been set to be true, +// it will align "=" sign with spaces under each section. +func (f *File) WriteToIndent(w io.Writer, indent string) (int64, error) { + buf, err := f.writeToBuffer(indent) + if err != nil { + return 0, err + } + return buf.WriteTo(w) +} + +// WriteTo writes file content into io.Writer. +func (f *File) WriteTo(w io.Writer) (int64, error) { + return f.WriteToIndent(w, "") +} + +// SaveToIndent writes content to file system with given value indention. +func (f *File) SaveToIndent(filename, indent string) error { + // Note: Because we are truncating with os.Create, + // so it's safer to save to a temporary file location and rename afte done. + buf, err := f.writeToBuffer(indent) + if err != nil { + return err + } + + return ioutil.WriteFile(filename, buf.Bytes(), 0666) +} + +// SaveTo writes content to file system. +func (f *File) SaveTo(filename string) error { + return f.SaveToIndent(filename, "") +} diff --git a/vendor/github.com/go-ini/ini/ini.go b/vendor/github.com/go-ini/ini/ini.go new file mode 100644 index 000000000..03cd57ff9 --- /dev/null +++ b/vendor/github.com/go-ini/ini/ini.go @@ -0,0 +1,223 @@ +// +build go1.6 + +// Copyright 2014 Unknwon +// +// 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. + +// Package ini provides INI file read and write functionality in Go. +package ini + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "os" + "regexp" + "runtime" +) + +const ( + // DefaultSection is the name of default section. You can use this constant or the string literal. + // In most of cases, an empty string is all you need to access the section. + DefaultSection = "DEFAULT" + // Deprecated: Use "DefaultSection" instead. + DEFAULT_SECTION = DefaultSection + + // Maximum allowed depth when recursively substituing variable names. + depthValues = 99 + version = "1.44.0" +) + +// Version returns current package version literal. +func Version() string { + return version +} + +var ( + // LineBreak is the delimiter to determine or compose a new line. + // This variable will be changed to "\r\n" automatically on Windows at package init time. + LineBreak = "\n" + + // DefaultFormatLeft places custom spaces on the left when PrettyFormat and PrettyEqual are both disabled. + DefaultFormatLeft = "" + // DefaultFormatRight places custom spaces on the right when PrettyFormat and PrettyEqual are both disabled. + DefaultFormatRight = "" + + // Variable regexp pattern: %(variable)s + varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`) + + // PrettyFormat indicates whether to align "=" sign with spaces to produce pretty output + // or reduce all possible spaces for compact format. + PrettyFormat = true + + // PrettyEqual places spaces around "=" sign even when PrettyFormat is false. + PrettyEqual = false + + // DefaultHeader explicitly writes default section header. + DefaultHeader = false + + // PrettySection indicates whether to put a line between sections. + PrettySection = true +) + +func init() { + if runtime.GOOS == "windows" { + LineBreak = "\r\n" + } +} + +func inSlice(str string, s []string) bool { + for _, v := range s { + if str == v { + return true + } + } + return false +} + +// dataSource is an interface that returns object which can be read and closed. +type dataSource interface { + ReadCloser() (io.ReadCloser, error) +} + +// sourceFile represents an object that contains content on the local file system. +type sourceFile struct { + name string +} + +func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) { + return os.Open(s.name) +} + +// sourceData represents an object that contains content in memory. +type sourceData struct { + data []byte +} + +func (s *sourceData) ReadCloser() (io.ReadCloser, error) { + return ioutil.NopCloser(bytes.NewReader(s.data)), nil +} + +// sourceReadCloser represents an input stream with Close method. +type sourceReadCloser struct { + reader io.ReadCloser +} + +func (s *sourceReadCloser) ReadCloser() (io.ReadCloser, error) { + return s.reader, nil +} + +func parseDataSource(source interface{}) (dataSource, error) { + switch s := source.(type) { + case string: + return sourceFile{s}, nil + case []byte: + return &sourceData{s}, nil + case io.ReadCloser: + return &sourceReadCloser{s}, nil + default: + return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s) + } +} + +// LoadOptions contains all customized options used for load data source(s). +type LoadOptions struct { + // Loose indicates whether the parser should ignore nonexistent files or return error. + Loose bool + // Insensitive indicates whether the parser forces all section and key names to lowercase. + Insensitive bool + // IgnoreContinuation indicates whether to ignore continuation lines while parsing. + IgnoreContinuation bool + // IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value. + IgnoreInlineComment bool + // SkipUnrecognizableLines indicates whether to skip unrecognizable lines that do not conform to key/value pairs. + SkipUnrecognizableLines bool + // AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing. + // This type of keys are mostly used in my.cnf. + AllowBooleanKeys bool + // AllowShadows indicates whether to keep track of keys with same name under same section. + AllowShadows bool + // AllowNestedValues indicates whether to allow AWS-like nested values. + // Docs: http://docs.aws.amazon.com/cli/latest/topic/config-vars.html#nested-values + AllowNestedValues bool + // AllowPythonMultilineValues indicates whether to allow Python-like multi-line values. + // Docs: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure + // Relevant quote: Values can also span multiple lines, as long as they are indented deeper + // than the first line of the value. + AllowPythonMultilineValues bool + // SpaceBeforeInlineComment indicates whether to allow comment symbols (\# and \;) inside value. + // Docs: https://docs.python.org/2/library/configparser.html + // Quote: Comments may appear on their own in an otherwise empty line, or may be entered in lines holding values or section names. + // In the latter case, they need to be preceded by a whitespace character to be recognized as a comment. + SpaceBeforeInlineComment bool + // UnescapeValueDoubleQuotes indicates whether to unescape double quotes inside value to regular format + // when value is surrounded by double quotes, e.g. key="a \"value\"" => key=a "value" + UnescapeValueDoubleQuotes bool + // UnescapeValueCommentSymbols indicates to unescape comment symbols (\# and \;) inside value to regular format + // when value is NOT surrounded by any quotes. + // Note: UNSTABLE, behavior might change to only unescape inside double quotes but may noy necessary at all. + UnescapeValueCommentSymbols bool + // UnparseableSections stores a list of blocks that are allowed with raw content which do not otherwise + // conform to key/value pairs. Specify the names of those blocks here. + UnparseableSections []string + // KeyValueDelimiters is the sequence of delimiters that are used to separate key and value. By default, it is "=:". + KeyValueDelimiters string + // PreserveSurroundedQuote indicates whether to preserve surrounded quote (single and double quotes). + PreserveSurroundedQuote bool +} + +// LoadSources allows caller to apply customized options for loading from data source(s). +func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) { + sources := make([]dataSource, len(others)+1) + sources[0], err = parseDataSource(source) + if err != nil { + return nil, err + } + for i := range others { + sources[i+1], err = parseDataSource(others[i]) + if err != nil { + return nil, err + } + } + f := newFile(sources, opts) + if err = f.Reload(); err != nil { + return nil, err + } + return f, nil +} + +// Load loads and parses from INI data sources. +// Arguments can be mixed of file name with string type, or raw data in []byte. +// It will return error if list contains nonexistent files. +func Load(source interface{}, others ...interface{}) (*File, error) { + return LoadSources(LoadOptions{}, source, others...) +} + +// LooseLoad has exactly same functionality as Load function +// except it ignores nonexistent files instead of returning error. +func LooseLoad(source interface{}, others ...interface{}) (*File, error) { + return LoadSources(LoadOptions{Loose: true}, source, others...) +} + +// InsensitiveLoad has exactly same functionality as Load function +// except it forces all section and key names to be lowercased. +func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) { + return LoadSources(LoadOptions{Insensitive: true}, source, others...) +} + +// ShadowLoad has exactly same functionality as Load function +// except it allows have shadow keys. +func ShadowLoad(source interface{}, others ...interface{}) (*File, error) { + return LoadSources(LoadOptions{AllowShadows: true}, source, others...) +} diff --git a/vendor/github.com/go-ini/ini/key.go b/vendor/github.com/go-ini/ini/key.go new file mode 100644 index 000000000..38860ff4b --- /dev/null +++ b/vendor/github.com/go-ini/ini/key.go @@ -0,0 +1,753 @@ +// Copyright 2014 Unknwon +// +// 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. + +package ini + +import ( + "bytes" + "errors" + "fmt" + "strconv" + "strings" + "time" +) + +// Key represents a key under a section. +type Key struct { + s *Section + Comment string + name string + value string + isAutoIncrement bool + isBooleanType bool + + isShadow bool + shadows []*Key + + nestedValues []string +} + +// newKey simply return a key object with given values. +func newKey(s *Section, name, val string) *Key { + return &Key{ + s: s, + name: name, + value: val, + } +} + +func (k *Key) addShadow(val string) error { + if k.isShadow { + return errors.New("cannot add shadow to another shadow key") + } else if k.isAutoIncrement || k.isBooleanType { + return errors.New("cannot add shadow to auto-increment or boolean key") + } + + shadow := newKey(k.s, k.name, val) + shadow.isShadow = true + k.shadows = append(k.shadows, shadow) + return nil +} + +// AddShadow adds a new shadow key to itself. +func (k *Key) AddShadow(val string) error { + if !k.s.f.options.AllowShadows { + return errors.New("shadow key is not allowed") + } + return k.addShadow(val) +} + +func (k *Key) addNestedValue(val string) error { + if k.isAutoIncrement || k.isBooleanType { + return errors.New("cannot add nested value to auto-increment or boolean key") + } + + k.nestedValues = append(k.nestedValues, val) + return nil +} + +// AddNestedValue adds a nested value to the key. +func (k *Key) AddNestedValue(val string) error { + if !k.s.f.options.AllowNestedValues { + return errors.New("nested value is not allowed") + } + return k.addNestedValue(val) +} + +// ValueMapper represents a mapping function for values, e.g. os.ExpandEnv +type ValueMapper func(string) string + +// Name returns name of key. +func (k *Key) Name() string { + return k.name +} + +// Value returns raw value of key for performance purpose. +func (k *Key) Value() string { + return k.value +} + +// ValueWithShadows returns raw values of key and its shadows if any. +func (k *Key) ValueWithShadows() []string { + if len(k.shadows) == 0 { + return []string{k.value} + } + vals := make([]string, len(k.shadows)+1) + vals[0] = k.value + for i := range k.shadows { + vals[i+1] = k.shadows[i].value + } + return vals +} + +// NestedValues returns nested values stored in the key. +// It is possible returned value is nil if no nested values stored in the key. +func (k *Key) NestedValues() []string { + return k.nestedValues +} + +// transformValue takes a raw value and transforms to its final string. +func (k *Key) transformValue(val string) string { + if k.s.f.ValueMapper != nil { + val = k.s.f.ValueMapper(val) + } + + // Fail-fast if no indicate char found for recursive value + if !strings.Contains(val, "%") { + return val + } + for i := 0; i < depthValues; i++ { + vr := varPattern.FindString(val) + if len(vr) == 0 { + break + } + + // Take off leading '%(' and trailing ')s'. + noption := vr[2 : len(vr)-2] + + // Search in the same section. + nk, err := k.s.GetKey(noption) + if err != nil || k == nk { + // Search again in default section. + nk, _ = k.s.f.Section("").GetKey(noption) + } + + // Substitute by new value and take off leading '%(' and trailing ')s'. + val = strings.Replace(val, vr, nk.value, -1) + } + return val +} + +// String returns string representation of value. +func (k *Key) String() string { + return k.transformValue(k.value) +} + +// Validate accepts a validate function which can +// return modifed result as key value. +func (k *Key) Validate(fn func(string) string) string { + return fn(k.String()) +} + +// parseBool returns the boolean value represented by the string. +// +// It accepts 1, t, T, TRUE, true, True, YES, yes, Yes, y, ON, on, On, +// 0, f, F, FALSE, false, False, NO, no, No, n, OFF, off, Off. +// Any other value returns an error. +func parseBool(str string) (value bool, err error) { + switch str { + case "1", "t", "T", "true", "TRUE", "True", "YES", "yes", "Yes", "y", "ON", "on", "On": + return true, nil + case "0", "f", "F", "false", "FALSE", "False", "NO", "no", "No", "n", "OFF", "off", "Off": + return false, nil + } + return false, fmt.Errorf("parsing \"%s\": invalid syntax", str) +} + +// Bool returns bool type value. +func (k *Key) Bool() (bool, error) { + return parseBool(k.String()) +} + +// Float64 returns float64 type value. +func (k *Key) Float64() (float64, error) { + return strconv.ParseFloat(k.String(), 64) +} + +// Int returns int type value. +func (k *Key) Int() (int, error) { + v, err := strconv.ParseInt(k.String(), 0, 64) + return int(v), err +} + +// Int64 returns int64 type value. +func (k *Key) Int64() (int64, error) { + return strconv.ParseInt(k.String(), 0, 64) +} + +// Uint returns uint type valued. +func (k *Key) Uint() (uint, error) { + u, e := strconv.ParseUint(k.String(), 0, 64) + return uint(u), e +} + +// Uint64 returns uint64 type value. +func (k *Key) Uint64() (uint64, error) { + return strconv.ParseUint(k.String(), 0, 64) +} + +// Duration returns time.Duration type value. +func (k *Key) Duration() (time.Duration, error) { + return time.ParseDuration(k.String()) +} + +// TimeFormat parses with given format and returns time.Time type value. +func (k *Key) TimeFormat(format string) (time.Time, error) { + return time.Parse(format, k.String()) +} + +// Time parses with RFC3339 format and returns time.Time type value. +func (k *Key) Time() (time.Time, error) { + return k.TimeFormat(time.RFC3339) +} + +// MustString returns default value if key value is empty. +func (k *Key) MustString(defaultVal string) string { + val := k.String() + if len(val) == 0 { + k.value = defaultVal + return defaultVal + } + return val +} + +// MustBool always returns value without error, +// it returns false if error occurs. +func (k *Key) MustBool(defaultVal ...bool) bool { + val, err := k.Bool() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatBool(defaultVal[0]) + return defaultVal[0] + } + return val +} + +// MustFloat64 always returns value without error, +// it returns 0.0 if error occurs. +func (k *Key) MustFloat64(defaultVal ...float64) float64 { + val, err := k.Float64() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatFloat(defaultVal[0], 'f', -1, 64) + return defaultVal[0] + } + return val +} + +// MustInt always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustInt(defaultVal ...int) int { + val, err := k.Int() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatInt(int64(defaultVal[0]), 10) + return defaultVal[0] + } + return val +} + +// MustInt64 always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustInt64(defaultVal ...int64) int64 { + val, err := k.Int64() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatInt(defaultVal[0], 10) + return defaultVal[0] + } + return val +} + +// MustUint always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustUint(defaultVal ...uint) uint { + val, err := k.Uint() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatUint(uint64(defaultVal[0]), 10) + return defaultVal[0] + } + return val +} + +// MustUint64 always returns value without error, +// it returns 0 if error occurs. +func (k *Key) MustUint64(defaultVal ...uint64) uint64 { + val, err := k.Uint64() + if len(defaultVal) > 0 && err != nil { + k.value = strconv.FormatUint(defaultVal[0], 10) + return defaultVal[0] + } + return val +} + +// MustDuration always returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustDuration(defaultVal ...time.Duration) time.Duration { + val, err := k.Duration() + if len(defaultVal) > 0 && err != nil { + k.value = defaultVal[0].String() + return defaultVal[0] + } + return val +} + +// MustTimeFormat always parses with given format and returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustTimeFormat(format string, defaultVal ...time.Time) time.Time { + val, err := k.TimeFormat(format) + if len(defaultVal) > 0 && err != nil { + k.value = defaultVal[0].Format(format) + return defaultVal[0] + } + return val +} + +// MustTime always parses with RFC3339 format and returns value without error, +// it returns zero value if error occurs. +func (k *Key) MustTime(defaultVal ...time.Time) time.Time { + return k.MustTimeFormat(time.RFC3339, defaultVal...) +} + +// In always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) In(defaultVal string, candidates []string) string { + val := k.String() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InFloat64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InFloat64(defaultVal float64, candidates []float64) float64 { + val := k.MustFloat64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InInt always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InInt(defaultVal int, candidates []int) int { + val := k.MustInt() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InInt64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InInt64(defaultVal int64, candidates []int64) int64 { + val := k.MustInt64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InUint always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InUint(defaultVal uint, candidates []uint) uint { + val := k.MustUint() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InUint64 always returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InUint64(defaultVal uint64, candidates []uint64) uint64 { + val := k.MustUint64() + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InTimeFormat always parses with given format and returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InTimeFormat(format string, defaultVal time.Time, candidates []time.Time) time.Time { + val := k.MustTimeFormat(format) + for _, cand := range candidates { + if val == cand { + return val + } + } + return defaultVal +} + +// InTime always parses with RFC3339 format and returns value without error, +// it returns default value if error occurs or doesn't fit into candidates. +func (k *Key) InTime(defaultVal time.Time, candidates []time.Time) time.Time { + return k.InTimeFormat(time.RFC3339, defaultVal, candidates) +} + +// RangeFloat64 checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeFloat64(defaultVal, min, max float64) float64 { + val := k.MustFloat64() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeInt checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeInt(defaultVal, min, max int) int { + val := k.MustInt() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeInt64 checks if value is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeInt64(defaultVal, min, max int64) int64 { + val := k.MustInt64() + if val < min || val > max { + return defaultVal + } + return val +} + +// RangeTimeFormat checks if value with given format is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeTimeFormat(format string, defaultVal, min, max time.Time) time.Time { + val := k.MustTimeFormat(format) + if val.Unix() < min.Unix() || val.Unix() > max.Unix() { + return defaultVal + } + return val +} + +// RangeTime checks if value with RFC3339 format is in given range inclusively, +// and returns default value if it's not. +func (k *Key) RangeTime(defaultVal, min, max time.Time) time.Time { + return k.RangeTimeFormat(time.RFC3339, defaultVal, min, max) +} + +// Strings returns list of string divided by given delimiter. +func (k *Key) Strings(delim string) []string { + str := k.String() + if len(str) == 0 { + return []string{} + } + + runes := []rune(str) + vals := make([]string, 0, 2) + var buf bytes.Buffer + escape := false + idx := 0 + for { + if escape { + escape = false + if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) { + buf.WriteRune('\\') + } + buf.WriteRune(runes[idx]) + } else { + if runes[idx] == '\\' { + escape = true + } else if strings.HasPrefix(string(runes[idx:]), delim) { + idx += len(delim) - 1 + vals = append(vals, strings.TrimSpace(buf.String())) + buf.Reset() + } else { + buf.WriteRune(runes[idx]) + } + } + idx++ + if idx == len(runes) { + break + } + } + + if buf.Len() > 0 { + vals = append(vals, strings.TrimSpace(buf.String())) + } + + return vals +} + +// StringsWithShadows returns list of string divided by given delimiter. +// Shadows will also be appended if any. +func (k *Key) StringsWithShadows(delim string) []string { + vals := k.ValueWithShadows() + results := make([]string, 0, len(vals)*2) + for i := range vals { + if len(vals) == 0 { + continue + } + + results = append(results, strings.Split(vals[i], delim)...) + } + + for i := range results { + results[i] = k.transformValue(strings.TrimSpace(results[i])) + } + return results +} + +// Float64s returns list of float64 divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Float64s(delim string) []float64 { + vals, _ := k.parseFloat64s(k.Strings(delim), true, false) + return vals +} + +// Ints returns list of int divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Ints(delim string) []int { + vals, _ := k.parseInts(k.Strings(delim), true, false) + return vals +} + +// Int64s returns list of int64 divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Int64s(delim string) []int64 { + vals, _ := k.parseInt64s(k.Strings(delim), true, false) + return vals +} + +// Uints returns list of uint divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Uints(delim string) []uint { + vals, _ := k.parseUints(k.Strings(delim), true, false) + return vals +} + +// Uint64s returns list of uint64 divided by given delimiter. Any invalid input will be treated as zero value. +func (k *Key) Uint64s(delim string) []uint64 { + vals, _ := k.parseUint64s(k.Strings(delim), true, false) + return vals +} + +// TimesFormat parses with given format and returns list of time.Time divided by given delimiter. +// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC). +func (k *Key) TimesFormat(format, delim string) []time.Time { + vals, _ := k.parseTimesFormat(format, k.Strings(delim), true, false) + return vals +} + +// Times parses with RFC3339 format and returns list of time.Time divided by given delimiter. +// Any invalid input will be treated as zero value (0001-01-01 00:00:00 +0000 UTC). +func (k *Key) Times(delim string) []time.Time { + return k.TimesFormat(time.RFC3339, delim) +} + +// ValidFloat64s returns list of float64 divided by given delimiter. If some value is not float, then +// it will not be included to result list. +func (k *Key) ValidFloat64s(delim string) []float64 { + vals, _ := k.parseFloat64s(k.Strings(delim), false, false) + return vals +} + +// ValidInts returns list of int divided by given delimiter. If some value is not integer, then it will +// not be included to result list. +func (k *Key) ValidInts(delim string) []int { + vals, _ := k.parseInts(k.Strings(delim), false, false) + return vals +} + +// ValidInt64s returns list of int64 divided by given delimiter. If some value is not 64-bit integer, +// then it will not be included to result list. +func (k *Key) ValidInt64s(delim string) []int64 { + vals, _ := k.parseInt64s(k.Strings(delim), false, false) + return vals +} + +// ValidUints returns list of uint divided by given delimiter. If some value is not unsigned integer, +// then it will not be included to result list. +func (k *Key) ValidUints(delim string) []uint { + vals, _ := k.parseUints(k.Strings(delim), false, false) + return vals +} + +// ValidUint64s returns list of uint64 divided by given delimiter. If some value is not 64-bit unsigned +// integer, then it will not be included to result list. +func (k *Key) ValidUint64s(delim string) []uint64 { + vals, _ := k.parseUint64s(k.Strings(delim), false, false) + return vals +} + +// ValidTimesFormat parses with given format and returns list of time.Time divided by given delimiter. +func (k *Key) ValidTimesFormat(format, delim string) []time.Time { + vals, _ := k.parseTimesFormat(format, k.Strings(delim), false, false) + return vals +} + +// ValidTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter. +func (k *Key) ValidTimes(delim string) []time.Time { + return k.ValidTimesFormat(time.RFC3339, delim) +} + +// StrictFloat64s returns list of float64 divided by given delimiter or error on first invalid input. +func (k *Key) StrictFloat64s(delim string) ([]float64, error) { + return k.parseFloat64s(k.Strings(delim), false, true) +} + +// StrictInts returns list of int divided by given delimiter or error on first invalid input. +func (k *Key) StrictInts(delim string) ([]int, error) { + return k.parseInts(k.Strings(delim), false, true) +} + +// StrictInt64s returns list of int64 divided by given delimiter or error on first invalid input. +func (k *Key) StrictInt64s(delim string) ([]int64, error) { + return k.parseInt64s(k.Strings(delim), false, true) +} + +// StrictUints returns list of uint divided by given delimiter or error on first invalid input. +func (k *Key) StrictUints(delim string) ([]uint, error) { + return k.parseUints(k.Strings(delim), false, true) +} + +// StrictUint64s returns list of uint64 divided by given delimiter or error on first invalid input. +func (k *Key) StrictUint64s(delim string) ([]uint64, error) { + return k.parseUint64s(k.Strings(delim), false, true) +} + +// StrictTimesFormat parses with given format and returns list of time.Time divided by given delimiter +// or error on first invalid input. +func (k *Key) StrictTimesFormat(format, delim string) ([]time.Time, error) { + return k.parseTimesFormat(format, k.Strings(delim), false, true) +} + +// StrictTimes parses with RFC3339 format and returns list of time.Time divided by given delimiter +// or error on first invalid input. +func (k *Key) StrictTimes(delim string) ([]time.Time, error) { + return k.StrictTimesFormat(time.RFC3339, delim) +} + +// parseFloat64s transforms strings to float64s. +func (k *Key) parseFloat64s(strs []string, addInvalid, returnOnInvalid bool) ([]float64, error) { + vals := make([]float64, 0, len(strs)) + for _, str := range strs { + val, err := strconv.ParseFloat(str, 64) + if err != nil && returnOnInvalid { + return nil, err + } + if err == nil || addInvalid { + vals = append(vals, val) + } + } + return vals, nil +} + +// parseInts transforms strings to ints. +func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) { + vals := make([]int, 0, len(strs)) + for _, str := range strs { + valInt64, err := strconv.ParseInt(str, 0, 64) + val := int(valInt64) + if err != nil && returnOnInvalid { + return nil, err + } + if err == nil || addInvalid { + vals = append(vals, val) + } + } + return vals, nil +} + +// parseInt64s transforms strings to int64s. +func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) { + vals := make([]int64, 0, len(strs)) + for _, str := range strs { + val, err := strconv.ParseInt(str, 0, 64) + if err != nil && returnOnInvalid { + return nil, err + } + if err == nil || addInvalid { + vals = append(vals, val) + } + } + return vals, nil +} + +// parseUints transforms strings to uints. +func (k *Key) parseUints(strs []string, addInvalid, returnOnInvalid bool) ([]uint, error) { + vals := make([]uint, 0, len(strs)) + for _, str := range strs { + val, err := strconv.ParseUint(str, 0, 0) + if err != nil && returnOnInvalid { + return nil, err + } + if err == nil || addInvalid { + vals = append(vals, uint(val)) + } + } + return vals, nil +} + +// parseUint64s transforms strings to uint64s. +func (k *Key) parseUint64s(strs []string, addInvalid, returnOnInvalid bool) ([]uint64, error) { + vals := make([]uint64, 0, len(strs)) + for _, str := range strs { + val, err := strconv.ParseUint(str, 0, 64) + if err != nil && returnOnInvalid { + return nil, err + } + if err == nil || addInvalid { + vals = append(vals, val) + } + } + return vals, nil +} + +// parseTimesFormat transforms strings to times in given format. +func (k *Key) parseTimesFormat(format string, strs []string, addInvalid, returnOnInvalid bool) ([]time.Time, error) { + vals := make([]time.Time, 0, len(strs)) + for _, str := range strs { + val, err := time.Parse(format, str) + if err != nil && returnOnInvalid { + return nil, err + } + if err == nil || addInvalid { + vals = append(vals, val) + } + } + return vals, nil +} + +// SetValue changes key value. +func (k *Key) SetValue(v string) { + if k.s.f.BlockMode { + k.s.f.lock.Lock() + defer k.s.f.lock.Unlock() + } + + k.value = v + k.s.keysHash[k.name] = v +} diff --git a/vendor/github.com/go-ini/ini/parser.go b/vendor/github.com/go-ini/ini/parser.go new file mode 100644 index 000000000..7c22a25c1 --- /dev/null +++ b/vendor/github.com/go-ini/ini/parser.go @@ -0,0 +1,487 @@ +// Copyright 2015 Unknwon +// +// 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. + +package ini + +import ( + "bufio" + "bytes" + "fmt" + "io" + "regexp" + "strconv" + "strings" + "unicode" +) + +var pythonMultiline = regexp.MustCompile("^(\\s+)([^\n]+)") + +type parserOptions struct { + IgnoreContinuation bool + IgnoreInlineComment bool + AllowPythonMultilineValues bool + SpaceBeforeInlineComment bool + UnescapeValueDoubleQuotes bool + UnescapeValueCommentSymbols bool + PreserveSurroundedQuote bool +} + +type parser struct { + buf *bufio.Reader + options parserOptions + + isEOF bool + count int + comment *bytes.Buffer +} + +func newParser(r io.Reader, opts parserOptions) *parser { + return &parser{ + buf: bufio.NewReader(r), + options: opts, + count: 1, + comment: &bytes.Buffer{}, + } +} + +// BOM handles header of UTF-8, UTF-16 LE and UTF-16 BE's BOM format. +// http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding +func (p *parser) BOM() error { + mask, err := p.buf.Peek(2) + if err != nil && err != io.EOF { + return err + } else if len(mask) < 2 { + return nil + } + + switch { + case mask[0] == 254 && mask[1] == 255: + fallthrough + case mask[0] == 255 && mask[1] == 254: + p.buf.Read(mask) + case mask[0] == 239 && mask[1] == 187: + mask, err := p.buf.Peek(3) + if err != nil && err != io.EOF { + return err + } else if len(mask) < 3 { + return nil + } + if mask[2] == 191 { + p.buf.Read(mask) + } + } + return nil +} + +func (p *parser) readUntil(delim byte) ([]byte, error) { + data, err := p.buf.ReadBytes(delim) + if err != nil { + if err == io.EOF { + p.isEOF = true + } else { + return nil, err + } + } + return data, nil +} + +func cleanComment(in []byte) ([]byte, bool) { + i := bytes.IndexAny(in, "#;") + if i == -1 { + return nil, false + } + return in[i:], true +} + +func readKeyName(delimiters string, in []byte) (string, int, error) { + line := string(in) + + // Check if key name surrounded by quotes. + var keyQuote string + if line[0] == '"' { + if len(line) > 6 && string(line[0:3]) == `"""` { + keyQuote = `"""` + } else { + keyQuote = `"` + } + } else if line[0] == '`' { + keyQuote = "`" + } + + // Get out key name + endIdx := -1 + if len(keyQuote) > 0 { + startIdx := len(keyQuote) + // FIXME: fail case -> """"""name"""=value + pos := strings.Index(line[startIdx:], keyQuote) + if pos == -1 { + return "", -1, fmt.Errorf("missing closing key quote: %s", line) + } + pos += startIdx + + // Find key-value delimiter + i := strings.IndexAny(line[pos+startIdx:], delimiters) + if i < 0 { + return "", -1, ErrDelimiterNotFound{line} + } + endIdx = pos + i + return strings.TrimSpace(line[startIdx:pos]), endIdx + startIdx + 1, nil + } + + endIdx = strings.IndexAny(line, delimiters) + if endIdx < 0 { + return "", -1, ErrDelimiterNotFound{line} + } + return strings.TrimSpace(line[0:endIdx]), endIdx + 1, nil +} + +func (p *parser) readMultilines(line, val, valQuote string) (string, error) { + for { + data, err := p.readUntil('\n') + if err != nil { + return "", err + } + next := string(data) + + pos := strings.LastIndex(next, valQuote) + if pos > -1 { + val += next[:pos] + + comment, has := cleanComment([]byte(next[pos:])) + if has { + p.comment.Write(bytes.TrimSpace(comment)) + } + break + } + val += next + if p.isEOF { + return "", fmt.Errorf("missing closing key quote from '%s' to '%s'", line, next) + } + } + return val, nil +} + +func (p *parser) readContinuationLines(val string) (string, error) { + for { + data, err := p.readUntil('\n') + if err != nil { + return "", err + } + next := strings.TrimSpace(string(data)) + + if len(next) == 0 { + break + } + val += next + if val[len(val)-1] != '\\' { + break + } + val = val[:len(val)-1] + } + return val, nil +} + +// hasSurroundedQuote check if and only if the first and last characters +// are quotes \" or \'. +// It returns false if any other parts also contain same kind of quotes. +func hasSurroundedQuote(in string, quote byte) bool { + return len(in) >= 2 && in[0] == quote && in[len(in)-1] == quote && + strings.IndexByte(in[1:], quote) == len(in)-2 +} + +func (p *parser) readValue(in []byte, bufferSize int) (string, error) { + + line := strings.TrimLeftFunc(string(in), unicode.IsSpace) + if len(line) == 0 { + if p.options.AllowPythonMultilineValues && len(in) > 0 && in[len(in)-1] == '\n' { + return p.readPythonMultilines(line, bufferSize) + } + return "", nil + } + + var valQuote string + if len(line) > 3 && string(line[0:3]) == `"""` { + valQuote = `"""` + } else if line[0] == '`' { + valQuote = "`" + } else if p.options.UnescapeValueDoubleQuotes && line[0] == '"' { + valQuote = `"` + } + + if len(valQuote) > 0 { + startIdx := len(valQuote) + pos := strings.LastIndex(line[startIdx:], valQuote) + // Check for multi-line value + if pos == -1 { + return p.readMultilines(line, line[startIdx:], valQuote) + } + + if p.options.UnescapeValueDoubleQuotes && valQuote == `"` { + return strings.Replace(line[startIdx:pos+startIdx], `\"`, `"`, -1), nil + } + return line[startIdx : pos+startIdx], nil + } + + lastChar := line[len(line)-1] + // Won't be able to reach here if value only contains whitespace + line = strings.TrimSpace(line) + trimmedLastChar := line[len(line)-1] + + // Check continuation lines when desired + if !p.options.IgnoreContinuation && trimmedLastChar == '\\' { + return p.readContinuationLines(line[:len(line)-1]) + } + + // Check if ignore inline comment + if !p.options.IgnoreInlineComment { + var i int + if p.options.SpaceBeforeInlineComment { + i = strings.Index(line, " #") + if i == -1 { + i = strings.Index(line, " ;") + } + + } else { + i = strings.IndexAny(line, "#;") + } + + if i > -1 { + p.comment.WriteString(line[i:]) + line = strings.TrimSpace(line[:i]) + } + + } + + // Trim single and double quotes + if (hasSurroundedQuote(line, '\'') || + hasSurroundedQuote(line, '"')) && !p.options.PreserveSurroundedQuote { + line = line[1 : len(line)-1] + } else if len(valQuote) == 0 && p.options.UnescapeValueCommentSymbols { + if strings.Contains(line, `\;`) { + line = strings.Replace(line, `\;`, ";", -1) + } + if strings.Contains(line, `\#`) { + line = strings.Replace(line, `\#`, "#", -1) + } + } else if p.options.AllowPythonMultilineValues && lastChar == '\n' { + return p.readPythonMultilines(line, bufferSize) + } + + return line, nil +} + +func (p *parser) readPythonMultilines(line string, bufferSize int) (string, error) { + parserBufferPeekResult, _ := p.buf.Peek(bufferSize) + peekBuffer := bytes.NewBuffer(parserBufferPeekResult) + + for { + peekData, peekErr := peekBuffer.ReadBytes('\n') + if peekErr != nil { + if peekErr == io.EOF { + return line, nil + } + return "", peekErr + } + + peekMatches := pythonMultiline.FindStringSubmatch(string(peekData)) + if len(peekMatches) != 3 { + return line, nil + } + + // NOTE: Return if not a python-ini multi-line value. + currentIdentSize := len(peekMatches[1]) + if currentIdentSize <= 0 { + return line, nil + } + + // NOTE: Just advance the parser reader (buffer) in-sync with the peek buffer. + _, err := p.readUntil('\n') + if err != nil { + return "", err + } + + line += fmt.Sprintf("\n%s", peekMatches[2]) + } +} + +// parse parses data through an io.Reader. +func (f *File) parse(reader io.Reader) (err error) { + p := newParser(reader, parserOptions{ + IgnoreContinuation: f.options.IgnoreContinuation, + IgnoreInlineComment: f.options.IgnoreInlineComment, + AllowPythonMultilineValues: f.options.AllowPythonMultilineValues, + SpaceBeforeInlineComment: f.options.SpaceBeforeInlineComment, + UnescapeValueDoubleQuotes: f.options.UnescapeValueDoubleQuotes, + UnescapeValueCommentSymbols: f.options.UnescapeValueCommentSymbols, + PreserveSurroundedQuote: f.options.PreserveSurroundedQuote, + }) + if err = p.BOM(); err != nil { + return fmt.Errorf("BOM: %v", err) + } + + // Ignore error because default section name is never empty string. + name := DefaultSection + if f.options.Insensitive { + name = strings.ToLower(DefaultSection) + } + section, _ := f.NewSection(name) + + // This "last" is not strictly equivalent to "previous one" if current key is not the first nested key + var isLastValueEmpty bool + var lastRegularKey *Key + + var line []byte + var inUnparseableSection bool + + // NOTE: Iterate and increase `currentPeekSize` until + // the size of the parser buffer is found. + // TODO(unknwon): When Golang 1.10 is the lowest version supported, replace with `parserBufferSize := p.buf.Size()`. + parserBufferSize := 0 + // NOTE: Peek 1kb at a time. + currentPeekSize := 1024 + + if f.options.AllowPythonMultilineValues { + for { + peekBytes, _ := p.buf.Peek(currentPeekSize) + peekBytesLength := len(peekBytes) + + if parserBufferSize >= peekBytesLength { + break + } + + currentPeekSize *= 2 + parserBufferSize = peekBytesLength + } + } + + for !p.isEOF { + line, err = p.readUntil('\n') + if err != nil { + return err + } + + if f.options.AllowNestedValues && + isLastValueEmpty && len(line) > 0 { + if line[0] == ' ' || line[0] == '\t' { + lastRegularKey.addNestedValue(string(bytes.TrimSpace(line))) + continue + } + } + + line = bytes.TrimLeftFunc(line, unicode.IsSpace) + if len(line) == 0 { + continue + } + + // Comments + if line[0] == '#' || line[0] == ';' { + // Note: we do not care ending line break, + // it is needed for adding second line, + // so just clean it once at the end when set to value. + p.comment.Write(line) + continue + } + + // Section + if line[0] == '[' { + // Read to the next ']' (TODO: support quoted strings) + closeIdx := bytes.LastIndexByte(line, ']') + if closeIdx == -1 { + return fmt.Errorf("unclosed section: %s", line) + } + + name := string(line[1:closeIdx]) + section, err = f.NewSection(name) + if err != nil { + return err + } + + comment, has := cleanComment(line[closeIdx+1:]) + if has { + p.comment.Write(comment) + } + + section.Comment = strings.TrimSpace(p.comment.String()) + + // Reset aotu-counter and comments + p.comment.Reset() + p.count = 1 + + inUnparseableSection = false + for i := range f.options.UnparseableSections { + if f.options.UnparseableSections[i] == name || + (f.options.Insensitive && strings.ToLower(f.options.UnparseableSections[i]) == strings.ToLower(name)) { + inUnparseableSection = true + continue + } + } + continue + } + + if inUnparseableSection { + section.isRawSection = true + section.rawBody += string(line) + continue + } + + kname, offset, err := readKeyName(f.options.KeyValueDelimiters, line) + if err != nil { + // Treat as boolean key when desired, and whole line is key name. + if IsErrDelimiterNotFound(err) { + switch { + case f.options.AllowBooleanKeys: + kname, err := p.readValue(line, parserBufferSize) + if err != nil { + return err + } + key, err := section.NewBooleanKey(kname) + if err != nil { + return err + } + key.Comment = strings.TrimSpace(p.comment.String()) + p.comment.Reset() + continue + + case f.options.SkipUnrecognizableLines: + continue + } + } + return err + } + + // Auto increment. + isAutoIncr := false + if kname == "-" { + isAutoIncr = true + kname = "#" + strconv.Itoa(p.count) + p.count++ + } + + value, err := p.readValue(line[offset:], parserBufferSize) + if err != nil { + return err + } + isLastValueEmpty = len(value) == 0 + + key, err := section.NewKey(kname, value) + if err != nil { + return err + } + key.isAutoIncrement = isAutoIncr + key.Comment = strings.TrimSpace(p.comment.String()) + p.comment.Reset() + lastRegularKey = key + } + return nil +} diff --git a/vendor/github.com/go-ini/ini/section.go b/vendor/github.com/go-ini/ini/section.go new file mode 100644 index 000000000..0bd3e1301 --- /dev/null +++ b/vendor/github.com/go-ini/ini/section.go @@ -0,0 +1,256 @@ +// Copyright 2014 Unknwon +// +// 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. + +package ini + +import ( + "errors" + "fmt" + "strings" +) + +// Section represents a config section. +type Section struct { + f *File + Comment string + name string + keys map[string]*Key + keyList []string + keysHash map[string]string + + isRawSection bool + rawBody string +} + +func newSection(f *File, name string) *Section { + return &Section{ + f: f, + name: name, + keys: make(map[string]*Key), + keyList: make([]string, 0, 10), + keysHash: make(map[string]string), + } +} + +// Name returns name of Section. +func (s *Section) Name() string { + return s.name +} + +// Body returns rawBody of Section if the section was marked as unparseable. +// It still follows the other rules of the INI format surrounding leading/trailing whitespace. +func (s *Section) Body() string { + return strings.TrimSpace(s.rawBody) +} + +// SetBody updates body content only if section is raw. +func (s *Section) SetBody(body string) { + if !s.isRawSection { + return + } + s.rawBody = body +} + +// NewKey creates a new key to given section. +func (s *Section) NewKey(name, val string) (*Key, error) { + if len(name) == 0 { + return nil, errors.New("error creating new key: empty key name") + } else if s.f.options.Insensitive { + name = strings.ToLower(name) + } + + if s.f.BlockMode { + s.f.lock.Lock() + defer s.f.lock.Unlock() + } + + if inSlice(name, s.keyList) { + if s.f.options.AllowShadows { + if err := s.keys[name].addShadow(val); err != nil { + return nil, err + } + } else { + s.keys[name].value = val + s.keysHash[name] = val + } + return s.keys[name], nil + } + + s.keyList = append(s.keyList, name) + s.keys[name] = newKey(s, name, val) + s.keysHash[name] = val + return s.keys[name], nil +} + +// NewBooleanKey creates a new boolean type key to given section. +func (s *Section) NewBooleanKey(name string) (*Key, error) { + key, err := s.NewKey(name, "true") + if err != nil { + return nil, err + } + + key.isBooleanType = true + return key, nil +} + +// GetKey returns key in section by given name. +func (s *Section) GetKey(name string) (*Key, error) { + if s.f.BlockMode { + s.f.lock.RLock() + } + if s.f.options.Insensitive { + name = strings.ToLower(name) + } + key := s.keys[name] + if s.f.BlockMode { + s.f.lock.RUnlock() + } + + if key == nil { + // Check if it is a child-section. + sname := s.name + for { + if i := strings.LastIndex(sname, "."); i > -1 { + sname = sname[:i] + sec, err := s.f.GetSection(sname) + if err != nil { + continue + } + return sec.GetKey(name) + } + break + } + return nil, fmt.Errorf("error when getting key of section '%s': key '%s' not exists", s.name, name) + } + return key, nil +} + +// HasKey returns true if section contains a key with given name. +func (s *Section) HasKey(name string) bool { + key, _ := s.GetKey(name) + return key != nil +} + +// Deprecated: Use "HasKey" instead. +func (s *Section) Haskey(name string) bool { + return s.HasKey(name) +} + +// HasValue returns true if section contains given raw value. +func (s *Section) HasValue(value string) bool { + if s.f.BlockMode { + s.f.lock.RLock() + defer s.f.lock.RUnlock() + } + + for _, k := range s.keys { + if value == k.value { + return true + } + } + return false +} + +// Key assumes named Key exists in section and returns a zero-value when not. +func (s *Section) Key(name string) *Key { + key, err := s.GetKey(name) + if err != nil { + // It's OK here because the only possible error is empty key name, + // but if it's empty, this piece of code won't be executed. + key, _ = s.NewKey(name, "") + return key + } + return key +} + +// Keys returns list of keys of section. +func (s *Section) Keys() []*Key { + keys := make([]*Key, len(s.keyList)) + for i := range s.keyList { + keys[i] = s.Key(s.keyList[i]) + } + return keys +} + +// ParentKeys returns list of keys of parent section. +func (s *Section) ParentKeys() []*Key { + var parentKeys []*Key + sname := s.name + for { + if i := strings.LastIndex(sname, "."); i > -1 { + sname = sname[:i] + sec, err := s.f.GetSection(sname) + if err != nil { + continue + } + parentKeys = append(parentKeys, sec.Keys()...) + } else { + break + } + + } + return parentKeys +} + +// KeyStrings returns list of key names of section. +func (s *Section) KeyStrings() []string { + list := make([]string, len(s.keyList)) + copy(list, s.keyList) + return list +} + +// KeysHash returns keys hash consisting of names and values. +func (s *Section) KeysHash() map[string]string { + if s.f.BlockMode { + s.f.lock.RLock() + defer s.f.lock.RUnlock() + } + + hash := map[string]string{} + for key, value := range s.keysHash { + hash[key] = value + } + return hash +} + +// DeleteKey deletes a key from section. +func (s *Section) DeleteKey(name string) { + if s.f.BlockMode { + s.f.lock.Lock() + defer s.f.lock.Unlock() + } + + for i, k := range s.keyList { + if k == name { + s.keyList = append(s.keyList[:i], s.keyList[i+1:]...) + delete(s.keys, name) + delete(s.keysHash, name) + return + } + } +} + +// ChildSections returns a list of child sections of current section. +// For example, "[parent.child1]" and "[parent.child12]" are child sections +// of section "[parent]". +func (s *Section) ChildSections() []*Section { + prefix := s.name + "." + children := make([]*Section, 0, 3) + for _, name := range s.f.sectionList { + if strings.HasPrefix(name, prefix) { + children = append(children, s.f.sections[name]) + } + } + return children +} diff --git a/vendor/github.com/go-ini/ini/struct.go b/vendor/github.com/go-ini/ini/struct.go new file mode 100644 index 000000000..4cdcb6b41 --- /dev/null +++ b/vendor/github.com/go-ini/ini/struct.go @@ -0,0 +1,548 @@ +// Copyright 2014 Unknwon +// +// 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. + +package ini + +import ( + "bytes" + "errors" + "fmt" + "reflect" + "strings" + "time" + "unicode" +) + +// NameMapper represents a ini tag name mapper. +type NameMapper func(string) string + +// Built-in name getters. +var ( + // AllCapsUnderscore converts to format ALL_CAPS_UNDERSCORE. + AllCapsUnderscore NameMapper = func(raw string) string { + newstr := make([]rune, 0, len(raw)) + for i, chr := range raw { + if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { + if i > 0 { + newstr = append(newstr, '_') + } + } + newstr = append(newstr, unicode.ToUpper(chr)) + } + return string(newstr) + } + // TitleUnderscore converts to format title_underscore. + TitleUnderscore NameMapper = func(raw string) string { + newstr := make([]rune, 0, len(raw)) + for i, chr := range raw { + if isUpper := 'A' <= chr && chr <= 'Z'; isUpper { + if i > 0 { + newstr = append(newstr, '_') + } + chr -= ('A' - 'a') + } + newstr = append(newstr, chr) + } + return string(newstr) + } +) + +func (s *Section) parseFieldName(raw, actual string) string { + if len(actual) > 0 { + return actual + } + if s.f.NameMapper != nil { + return s.f.NameMapper(raw) + } + return raw +} + +func parseDelim(actual string) string { + if len(actual) > 0 { + return actual + } + return "," +} + +var reflectTime = reflect.TypeOf(time.Now()).Kind() + +// setSliceWithProperType sets proper values to slice based on its type. +func setSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error { + var strs []string + if allowShadow { + strs = key.StringsWithShadows(delim) + } else { + strs = key.Strings(delim) + } + + numVals := len(strs) + if numVals == 0 { + return nil + } + + var vals interface{} + var err error + + sliceOf := field.Type().Elem().Kind() + switch sliceOf { + case reflect.String: + vals = strs + case reflect.Int: + vals, err = key.parseInts(strs, true, false) + case reflect.Int64: + vals, err = key.parseInt64s(strs, true, false) + case reflect.Uint: + vals, err = key.parseUints(strs, true, false) + case reflect.Uint64: + vals, err = key.parseUint64s(strs, true, false) + case reflect.Float64: + vals, err = key.parseFloat64s(strs, true, false) + case reflectTime: + vals, err = key.parseTimesFormat(time.RFC3339, strs, true, false) + default: + return fmt.Errorf("unsupported type '[]%s'", sliceOf) + } + if err != nil && isStrict { + return err + } + + slice := reflect.MakeSlice(field.Type(), numVals, numVals) + for i := 0; i < numVals; i++ { + switch sliceOf { + case reflect.String: + slice.Index(i).Set(reflect.ValueOf(vals.([]string)[i])) + case reflect.Int: + slice.Index(i).Set(reflect.ValueOf(vals.([]int)[i])) + case reflect.Int64: + slice.Index(i).Set(reflect.ValueOf(vals.([]int64)[i])) + case reflect.Uint: + slice.Index(i).Set(reflect.ValueOf(vals.([]uint)[i])) + case reflect.Uint64: + slice.Index(i).Set(reflect.ValueOf(vals.([]uint64)[i])) + case reflect.Float64: + slice.Index(i).Set(reflect.ValueOf(vals.([]float64)[i])) + case reflectTime: + slice.Index(i).Set(reflect.ValueOf(vals.([]time.Time)[i])) + } + } + field.Set(slice) + return nil +} + +func wrapStrictError(err error, isStrict bool) error { + if isStrict { + return err + } + return nil +} + +// setWithProperType sets proper value to field based on its type, +// but it does not return error for failing parsing, +// because we want to use default value that is already assigned to struct. +func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow, isStrict bool) error { + switch t.Kind() { + case reflect.String: + if len(key.String()) == 0 { + return nil + } + field.SetString(key.String()) + case reflect.Bool: + boolVal, err := key.Bool() + if err != nil { + return wrapStrictError(err, isStrict) + } + field.SetBool(boolVal) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + durationVal, err := key.Duration() + // Skip zero value + if err == nil && int64(durationVal) > 0 { + field.Set(reflect.ValueOf(durationVal)) + return nil + } + + intVal, err := key.Int64() + if err != nil { + return wrapStrictError(err, isStrict) + } + field.SetInt(intVal) + // byte is an alias for uint8, so supporting uint8 breaks support for byte + case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64: + durationVal, err := key.Duration() + // Skip zero value + if err == nil && uint64(durationVal) > 0 { + field.Set(reflect.ValueOf(durationVal)) + return nil + } + + uintVal, err := key.Uint64() + if err != nil { + return wrapStrictError(err, isStrict) + } + field.SetUint(uintVal) + + case reflect.Float32, reflect.Float64: + floatVal, err := key.Float64() + if err != nil { + return wrapStrictError(err, isStrict) + } + field.SetFloat(floatVal) + case reflectTime: + timeVal, err := key.Time() + if err != nil { + return wrapStrictError(err, isStrict) + } + field.Set(reflect.ValueOf(timeVal)) + case reflect.Slice: + return setSliceWithProperType(key, field, delim, allowShadow, isStrict) + default: + return fmt.Errorf("unsupported type '%s'", t) + } + return nil +} + +func parseTagOptions(tag string) (rawName string, omitEmpty bool, allowShadow bool) { + opts := strings.SplitN(tag, ",", 3) + rawName = opts[0] + if len(opts) > 1 { + omitEmpty = opts[1] == "omitempty" + } + if len(opts) > 2 { + allowShadow = opts[2] == "allowshadow" + } + return rawName, omitEmpty, allowShadow +} + +func (s *Section) mapTo(val reflect.Value, isStrict bool) error { + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + typ := val.Type() + + for i := 0; i < typ.NumField(); i++ { + field := val.Field(i) + tpField := typ.Field(i) + + tag := tpField.Tag.Get("ini") + if tag == "-" { + continue + } + + rawName, _, allowShadow := parseTagOptions(tag) + fieldName := s.parseFieldName(tpField.Name, rawName) + if len(fieldName) == 0 || !field.CanSet() { + continue + } + + isStruct := tpField.Type.Kind() == reflect.Struct + isStructPtr := tpField.Type.Kind() == reflect.Ptr && tpField.Type.Elem().Kind() == reflect.Struct + isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous + if isAnonymous { + field.Set(reflect.New(tpField.Type.Elem())) + } + + if isAnonymous || isStruct || isStructPtr { + if sec, err := s.f.GetSection(fieldName); err == nil { + // Only set the field to non-nil struct value if we have + // a section for it. Otherwise, we end up with a non-nil + // struct ptr even though there is no data. + if isStructPtr && field.IsNil() { + field.Set(reflect.New(tpField.Type.Elem())) + } + if err = sec.mapTo(field, isStrict); err != nil { + return fmt.Errorf("error mapping field(%s): %v", fieldName, err) + } + continue + } + } + + if key, err := s.GetKey(fieldName); err == nil { + delim := parseDelim(tpField.Tag.Get("delim")) + if err = setWithProperType(tpField.Type, key, field, delim, allowShadow, isStrict); err != nil { + return fmt.Errorf("error mapping field(%s): %v", fieldName, err) + } + } + } + return nil +} + +// MapTo maps section to given struct. +func (s *Section) MapTo(v interface{}) error { + typ := reflect.TypeOf(v) + val := reflect.ValueOf(v) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } else { + return errors.New("cannot map to non-pointer struct") + } + + return s.mapTo(val, false) +} + +// StrictMapTo maps section to given struct in strict mode, +// which returns all possible error including value parsing error. +func (s *Section) StrictMapTo(v interface{}) error { + typ := reflect.TypeOf(v) + val := reflect.ValueOf(v) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } else { + return errors.New("cannot map to non-pointer struct") + } + + return s.mapTo(val, true) +} + +// MapTo maps file to given struct. +func (f *File) MapTo(v interface{}) error { + return f.Section("").MapTo(v) +} + +// StrictMapTo maps file to given struct in strict mode, +// which returns all possible error including value parsing error. +func (f *File) StrictMapTo(v interface{}) error { + return f.Section("").StrictMapTo(v) +} + +// MapToWithMapper maps data sources to given struct with name mapper. +func MapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error { + cfg, err := Load(source, others...) + if err != nil { + return err + } + cfg.NameMapper = mapper + return cfg.MapTo(v) +} + +// StrictMapToWithMapper maps data sources to given struct with name mapper in strict mode, +// which returns all possible error including value parsing error. +func StrictMapToWithMapper(v interface{}, mapper NameMapper, source interface{}, others ...interface{}) error { + cfg, err := Load(source, others...) + if err != nil { + return err + } + cfg.NameMapper = mapper + return cfg.StrictMapTo(v) +} + +// MapTo maps data sources to given struct. +func MapTo(v, source interface{}, others ...interface{}) error { + return MapToWithMapper(v, nil, source, others...) +} + +// StrictMapTo maps data sources to given struct in strict mode, +// which returns all possible error including value parsing error. +func StrictMapTo(v, source interface{}, others ...interface{}) error { + return StrictMapToWithMapper(v, nil, source, others...) +} + +// reflectSliceWithProperType does the opposite thing as setSliceWithProperType. +func reflectSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow bool) error { + slice := field.Slice(0, field.Len()) + if field.Len() == 0 { + return nil + } + sliceOf := field.Type().Elem().Kind() + + if allowShadow { + var keyWithShadows *Key + for i := 0; i < field.Len(); i++ { + var val string + switch sliceOf { + case reflect.String: + val = slice.Index(i).String() + case reflect.Int, reflect.Int64: + val = fmt.Sprint(slice.Index(i).Int()) + case reflect.Uint, reflect.Uint64: + val = fmt.Sprint(slice.Index(i).Uint()) + case reflect.Float64: + val = fmt.Sprint(slice.Index(i).Float()) + case reflectTime: + val = slice.Index(i).Interface().(time.Time).Format(time.RFC3339) + default: + return fmt.Errorf("unsupported type '[]%s'", sliceOf) + } + + if i == 0 { + keyWithShadows = newKey(key.s, key.name, val) + } else { + keyWithShadows.AddShadow(val) + } + } + key = keyWithShadows + return nil + } + + var buf bytes.Buffer + for i := 0; i < field.Len(); i++ { + switch sliceOf { + case reflect.String: + buf.WriteString(slice.Index(i).String()) + case reflect.Int, reflect.Int64: + buf.WriteString(fmt.Sprint(slice.Index(i).Int())) + case reflect.Uint, reflect.Uint64: + buf.WriteString(fmt.Sprint(slice.Index(i).Uint())) + case reflect.Float64: + buf.WriteString(fmt.Sprint(slice.Index(i).Float())) + case reflectTime: + buf.WriteString(slice.Index(i).Interface().(time.Time).Format(time.RFC3339)) + default: + return fmt.Errorf("unsupported type '[]%s'", sliceOf) + } + buf.WriteString(delim) + } + key.SetValue(buf.String()[:buf.Len()-len(delim)]) + return nil +} + +// reflectWithProperType does the opposite thing as setWithProperType. +func reflectWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow bool) error { + switch t.Kind() { + case reflect.String: + key.SetValue(field.String()) + case reflect.Bool: + key.SetValue(fmt.Sprint(field.Bool())) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + key.SetValue(fmt.Sprint(field.Int())) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + key.SetValue(fmt.Sprint(field.Uint())) + case reflect.Float32, reflect.Float64: + key.SetValue(fmt.Sprint(field.Float())) + case reflectTime: + key.SetValue(fmt.Sprint(field.Interface().(time.Time).Format(time.RFC3339))) + case reflect.Slice: + return reflectSliceWithProperType(key, field, delim, allowShadow) + default: + return fmt.Errorf("unsupported type '%s'", t) + } + return nil +} + +// CR: copied from encoding/json/encode.go with modifications of time.Time support. +// TODO: add more test coverage. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + case reflectTime: + t, ok := v.Interface().(time.Time) + return ok && t.IsZero() + } + return false +} + +func (s *Section) reflectFrom(val reflect.Value) error { + if val.Kind() == reflect.Ptr { + val = val.Elem() + } + typ := val.Type() + + for i := 0; i < typ.NumField(); i++ { + field := val.Field(i) + tpField := typ.Field(i) + + tag := tpField.Tag.Get("ini") + if tag == "-" { + continue + } + + rawName, omitEmpty, allowShadow := parseTagOptions(tag) + if omitEmpty && isEmptyValue(field) { + continue + } + + fieldName := s.parseFieldName(tpField.Name, rawName) + if len(fieldName) == 0 || !field.CanSet() { + continue + } + + if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) || + (tpField.Type.Kind() == reflect.Struct && tpField.Type.Name() != "Time") { + // Note: The only error here is section doesn't exist. + sec, err := s.f.GetSection(fieldName) + if err != nil { + // Note: fieldName can never be empty here, ignore error. + sec, _ = s.f.NewSection(fieldName) + } + + // Add comment from comment tag + if len(sec.Comment) == 0 { + sec.Comment = tpField.Tag.Get("comment") + } + + if err = sec.reflectFrom(field); err != nil { + return fmt.Errorf("error reflecting field (%s): %v", fieldName, err) + } + continue + } + + // Note: Same reason as secion. + key, err := s.GetKey(fieldName) + if err != nil { + key, _ = s.NewKey(fieldName, "") + } + + // Add comment from comment tag + if len(key.Comment) == 0 { + key.Comment = tpField.Tag.Get("comment") + } + + if err = reflectWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim")), allowShadow); err != nil { + return fmt.Errorf("error reflecting field (%s): %v", fieldName, err) + } + + } + return nil +} + +// ReflectFrom reflects secion from given struct. +func (s *Section) ReflectFrom(v interface{}) error { + typ := reflect.TypeOf(v) + val := reflect.ValueOf(v) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + val = val.Elem() + } else { + return errors.New("cannot reflect from non-pointer struct") + } + + return s.reflectFrom(val) +} + +// ReflectFrom reflects file from given struct. +func (f *File) ReflectFrom(v interface{}) error { + return f.Section("").ReflectFrom(v) +} + +// ReflectFromWithMapper reflects data sources from given struct with name mapper. +func ReflectFromWithMapper(cfg *File, v interface{}, mapper NameMapper) error { + cfg.NameMapper = mapper + return cfg.ReflectFrom(v) +} + +// ReflectFrom reflects data sources from given struct. +func ReflectFrom(cfg *File, v interface{}) error { + return ReflectFromWithMapper(cfg, v, nil) +} diff --git a/vendor/github.com/gofrs/uuid/.gitignore b/vendor/github.com/gofrs/uuid/.gitignore new file mode 100644 index 000000000..666dbbb5b --- /dev/null +++ b/vendor/github.com/gofrs/uuid/.gitignore @@ -0,0 +1,15 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# binary bundle generated by go-fuzz +uuid-fuzz.zip diff --git a/vendor/github.com/gofrs/uuid/.travis.yml b/vendor/github.com/gofrs/uuid/.travis.yml new file mode 100644 index 000000000..ee1e4fa00 --- /dev/null +++ b/vendor/github.com/gofrs/uuid/.travis.yml @@ -0,0 +1,23 @@ +language: go +sudo: false +go: + - 1.7.x + - 1.8.x + - 1.9.x + - 1.10.x + - 1.11.x + - tip +matrix: + allow_failures: + - go: tip + fast_finish: true +env: + - GO111MODULE=on +before_install: + - go get golang.org/x/tools/cmd/cover +script: + - go test ./... -race -coverprofile=coverage.txt -covermode=atomic +after_success: + - bash <(curl -s https://codecov.io/bash) +notifications: + email: false diff --git a/vendor/github.com/gofrs/uuid/LICENSE b/vendor/github.com/gofrs/uuid/LICENSE new file mode 100644 index 000000000..926d54987 --- /dev/null +++ b/vendor/github.com/gofrs/uuid/LICENSE @@ -0,0 +1,20 @@ +Copyright (C) 2013-2018 by Maxim Bublis + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/gofrs/uuid/README.md b/vendor/github.com/gofrs/uuid/README.md new file mode 100644 index 000000000..efc3204fc --- /dev/null +++ b/vendor/github.com/gofrs/uuid/README.md @@ -0,0 +1,109 @@ +# UUID + +[![License](https://img.shields.io/github/license/gofrs/uuid.svg)](https://github.com/gofrs/uuid/blob/master/LICENSE) +[![Build Status](https://travis-ci.org/gofrs/uuid.svg?branch=master)](https://travis-ci.org/gofrs/uuid) +[![GoDoc](http://godoc.org/github.com/gofrs/uuid?status.svg)](http://godoc.org/github.com/gofrs/uuid) +[![Coverage Status](https://codecov.io/gh/gofrs/uuid/branch/master/graphs/badge.svg?branch=master)](https://codecov.io/gh/gofrs/uuid/) +[![Go Report Card](https://goreportcard.com/badge/github.com/gofrs/uuid)](https://goreportcard.com/report/github.com/gofrs/uuid) + +Package uuid provides a pure Go implementation of Universally Unique Identifiers +(UUID) variant as defined in RFC-4122. This package supports both the creation +and parsing of UUIDs in different formats. + +This package supports the following UUID versions: +* Version 1, based on timestamp and MAC address (RFC-4122) +* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1) +* Version 3, based on MD5 hashing of a named value (RFC-4122) +* Version 4, based on random numbers (RFC-4122) +* Version 5, based on SHA-1 hashing of a named value (RFC-4122) + +## Project History + +This project was originally forked from the +[github.com/satori/go.uuid](https://github.com/satori/go.uuid) repository after +it appeared to be no longer maintained, while exhibiting [critical +flaws](https://github.com/satori/go.uuid/issues/73). We have decided to take +over this project to ensure it receives regular maintenance for the benefit of +the larger Go community. + +We'd like to thank Maxim Bublis for his hard work on the original iteration of +the package. + +## License + +This source code of this package is released under the MIT License. Please see +the [LICENSE](https://github.com/gofrs/uuid/blob/master/LICENSE) for the full +content of the license. + +## Recommended Package Version + +We recommend using v2.0.0+ of this package, as versions prior to 2.0.0 were +created before our fork of the original package and have some known +deficiencies. + +## Installation + +It is recommended to use a package manager like `dep` that understands tagged +releases of a package, as well as semantic versioning. + +If you are unable to make use of a dependency manager with your project, you can +use the `go get` command to download it directly: + +```Shell +$ go get github.com/gofrs/uuid +``` + +## Requirements + +Due to subtests not being supported in older versions of Go, this package is +only regularly tested against Go 1.7+. This package may work perfectly fine with +Go 1.2+, but support for these older versions is not actively maintained. + +## Go 1.11 Modules + +As of v3.2.0, this repository no longer adopts Go modules, and v3.2.0 no longer has a `go.mod` file. As a result, v3.2.0 also drops support for the `github.com/gofrs/uuid/v3` import path. Only module-based consumers are impacted. With the v3.2.0 release, _all_ gofrs/uuid consumers should use the `github.com/gofrs/uuid` import path. + +An existing module-based consumer will continue to be able to build using the `github.com/gofrs/uuid/v3` import path using any valid consumer `go.mod` that worked prior to the publishing of v3.2.0, but any module-based consumer should start using the `github.com/gofrs/uuid` import path when possible and _must_ use the `github.com/gofrs/uuid` import path prior to upgrading to v3.2.0. + +Please refer to [Issue #61](https://github.com/gofrs/uuid/issues/61) and [Issue #66](https://github.com/gofrs/uuid/issues/66) for more details. + +## Usage + +Here is a quick overview of how to use this package. For more detailed +documentation, please see the [GoDoc Page](http://godoc.org/github.com/gofrs/uuid). + +```go +package main + +import ( + "log" + + "github.com/gofrs/uuid" +) + +// Create a Version 4 UUID, panicking on error. +// Use this form to initialize package-level variables. +var u1 = uuid.Must(uuid.NewV4()) + +func main() { + // Create a Version 4 UUID. + u2, err := uuid.NewV4() + if err != nil { + log.Fatalf("failed to generate UUID: %v", err) + } + log.Printf("generated Version 4 UUID %v", u2) + + // Parse a UUID from a string. + s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" + u3, err := uuid.FromString(s) + if err != nil { + log.Fatalf("failed to parse UUID %q: %v", s, err) + } + log.Printf("successfully parsed UUID %v", u3) +} +``` + +## References + +* [RFC-4122](https://tools.ietf.org/html/rfc4122) +* [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01) diff --git a/vendor/github.com/gofrs/uuid/codec.go b/vendor/github.com/gofrs/uuid/codec.go new file mode 100644 index 000000000..e3d8cfb4d --- /dev/null +++ b/vendor/github.com/gofrs/uuid/codec.go @@ -0,0 +1,212 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package uuid + +import ( + "bytes" + "encoding/hex" + "fmt" +) + +// FromBytes returns a UUID generated from the raw byte slice input. +// It will return an error if the slice isn't 16 bytes long. +func FromBytes(input []byte) (UUID, error) { + u := UUID{} + err := u.UnmarshalBinary(input) + return u, err +} + +// FromBytesOrNil returns a UUID generated from the raw byte slice input. +// Same behavior as FromBytes(), but returns uuid.Nil instead of an error. +func FromBytesOrNil(input []byte) UUID { + uuid, err := FromBytes(input) + if err != nil { + return Nil + } + return uuid +} + +// FromString returns a UUID parsed from the input string. +// Input is expected in a form accepted by UnmarshalText. +func FromString(input string) (UUID, error) { + u := UUID{} + err := u.UnmarshalText([]byte(input)) + return u, err +} + +// FromStringOrNil returns a UUID parsed from the input string. +// Same behavior as FromString(), but returns uuid.Nil instead of an error. +func FromStringOrNil(input string) UUID { + uuid, err := FromString(input) + if err != nil { + return Nil + } + return uuid +} + +// MarshalText implements the encoding.TextMarshaler interface. +// The encoding is the same as returned by the String() method. +func (u UUID) MarshalText() ([]byte, error) { + return []byte(u.String()), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +// Following formats are supported: +// +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", +// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", +// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" +// "6ba7b8109dad11d180b400c04fd430c8" +// "{6ba7b8109dad11d180b400c04fd430c8}", +// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8" +// +// ABNF for supported UUID text representation follows: +// +// URN := 'urn' +// UUID-NID := 'uuid' +// +// hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | +// 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | +// 'A' | 'B' | 'C' | 'D' | 'E' | 'F' +// +// hexoct := hexdig hexdig +// 2hexoct := hexoct hexoct +// 4hexoct := 2hexoct 2hexoct +// 6hexoct := 4hexoct 2hexoct +// 12hexoct := 6hexoct 6hexoct +// +// hashlike := 12hexoct +// canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct +// +// plain := canonical | hashlike +// uuid := canonical | hashlike | braced | urn +// +// braced := '{' plain '}' | '{' hashlike '}' +// urn := URN ':' UUID-NID ':' plain +// +func (u *UUID) UnmarshalText(text []byte) error { + switch len(text) { + case 32: + return u.decodeHashLike(text) + case 34, 38: + return u.decodeBraced(text) + case 36: + return u.decodeCanonical(text) + case 41, 45: + return u.decodeURN(text) + default: + return fmt.Errorf("uuid: incorrect UUID length: %s", text) + } +} + +// decodeCanonical decodes UUID strings that are formatted as defined in RFC-4122 (section 3): +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8". +func (u *UUID) decodeCanonical(t []byte) error { + if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' { + return fmt.Errorf("uuid: incorrect UUID format %s", t) + } + + src := t + dst := u[:] + + for i, byteGroup := range byteGroups { + if i > 0 { + src = src[1:] // skip dash + } + _, err := hex.Decode(dst[:byteGroup/2], src[:byteGroup]) + if err != nil { + return err + } + src = src[byteGroup:] + dst = dst[byteGroup/2:] + } + + return nil +} + +// decodeHashLike decodes UUID strings that are using the following format: +// "6ba7b8109dad11d180b400c04fd430c8". +func (u *UUID) decodeHashLike(t []byte) error { + src := t[:] + dst := u[:] + + _, err := hex.Decode(dst, src) + return err +} + +// decodeBraced decodes UUID strings that are using the following formats: +// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" +// "{6ba7b8109dad11d180b400c04fd430c8}". +func (u *UUID) decodeBraced(t []byte) error { + l := len(t) + + if t[0] != '{' || t[l-1] != '}' { + return fmt.Errorf("uuid: incorrect UUID format %s", t) + } + + return u.decodePlain(t[1 : l-1]) +} + +// decodeURN decodes UUID strings that are using the following formats: +// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" +// "urn:uuid:6ba7b8109dad11d180b400c04fd430c8". +func (u *UUID) decodeURN(t []byte) error { + total := len(t) + + urnUUIDPrefix := t[:9] + + if !bytes.Equal(urnUUIDPrefix, urnPrefix) { + return fmt.Errorf("uuid: incorrect UUID format: %s", t) + } + + return u.decodePlain(t[9:total]) +} + +// decodePlain decodes UUID strings that are using the following formats: +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format +// "6ba7b8109dad11d180b400c04fd430c8". +func (u *UUID) decodePlain(t []byte) error { + switch len(t) { + case 32: + return u.decodeHashLike(t) + case 36: + return u.decodeCanonical(t) + default: + return fmt.Errorf("uuid: incorrect UUID length: %s", t) + } +} + +// MarshalBinary implements the encoding.BinaryMarshaler interface. +func (u UUID) MarshalBinary() ([]byte, error) { + return u.Bytes(), nil +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. +// It will return an error if the slice isn't 16 bytes long. +func (u *UUID) UnmarshalBinary(data []byte) error { + if len(data) != Size { + return fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) + } + copy(u[:], data) + + return nil +} diff --git a/vendor/github.com/gofrs/uuid/fuzz.go b/vendor/github.com/gofrs/uuid/fuzz.go new file mode 100644 index 000000000..afaefbc8e --- /dev/null +++ b/vendor/github.com/gofrs/uuid/fuzz.go @@ -0,0 +1,47 @@ +// Copyright (c) 2018 Andrei Tudor Călin +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// +build gofuzz + +package uuid + +// Fuzz implements a simple fuzz test for FromString / UnmarshalText. +// +// To run: +// +// $ go get github.com/dvyukov/go-fuzz/... +// $ cd $GOPATH/src/github.com/gofrs/uuid +// $ go-fuzz-build github.com/gofrs/uuid +// $ go-fuzz -bin=uuid-fuzz.zip -workdir=./testdata +// +// If you make significant changes to FromString / UnmarshalText and add +// new cases to fromStringTests (in codec_test.go), please run +// +// $ go test -seed_fuzz_corpus +// +// to seed the corpus with the new interesting inputs, then run the fuzzer. +func Fuzz(data []byte) int { + _, err := FromString(string(data)) + if err != nil { + return 0 + } + return 1 +} diff --git a/vendor/github.com/gofrs/uuid/generator.go b/vendor/github.com/gofrs/uuid/generator.go new file mode 100644 index 000000000..4257761f1 --- /dev/null +++ b/vendor/github.com/gofrs/uuid/generator.go @@ -0,0 +1,299 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package uuid + +import ( + "crypto/md5" + "crypto/rand" + "crypto/sha1" + "encoding/binary" + "fmt" + "hash" + "io" + "net" + "os" + "sync" + "time" +) + +// Difference in 100-nanosecond intervals between +// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). +const epochStart = 122192928000000000 + +type epochFunc func() time.Time + +// HWAddrFunc is the function type used to provide hardware (MAC) addresses. +type HWAddrFunc func() (net.HardwareAddr, error) + +// DefaultGenerator is the default UUID Generator used by this package. +var DefaultGenerator Generator = NewGen() + +var ( + posixUID = uint32(os.Getuid()) + posixGID = uint32(os.Getgid()) +) + +// NewV1 returns a UUID based on the current timestamp and MAC address. +func NewV1() (UUID, error) { + return DefaultGenerator.NewV1() +} + +// NewV2 returns a DCE Security UUID based on the POSIX UID/GID. +func NewV2(domain byte) (UUID, error) { + return DefaultGenerator.NewV2(domain) +} + +// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name. +func NewV3(ns UUID, name string) UUID { + return DefaultGenerator.NewV3(ns, name) +} + +// NewV4 returns a randomly generated UUID. +func NewV4() (UUID, error) { + return DefaultGenerator.NewV4() +} + +// NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name. +func NewV5(ns UUID, name string) UUID { + return DefaultGenerator.NewV5(ns, name) +} + +// Generator provides an interface for generating UUIDs. +type Generator interface { + NewV1() (UUID, error) + NewV2(domain byte) (UUID, error) + NewV3(ns UUID, name string) UUID + NewV4() (UUID, error) + NewV5(ns UUID, name string) UUID +} + +// Gen is a reference UUID generator based on the specifications laid out in +// RFC-4122 and DCE 1.1: Authentication and Security Services. This type +// satisfies the Generator interface as defined in this package. +// +// For consumers who are generating V1 UUIDs, but don't want to expose the MAC +// address of the node generating the UUIDs, the NewGenWithHWAF() function has been +// provided as a convenience. See the function's documentation for more info. +// +// The authors of this package do not feel that the majority of users will need +// to obfuscate their MAC address, and so we recommend using NewGen() to create +// a new generator. +type Gen struct { + clockSequenceOnce sync.Once + hardwareAddrOnce sync.Once + storageMutex sync.Mutex + + rand io.Reader + + epochFunc epochFunc + hwAddrFunc HWAddrFunc + lastTime uint64 + clockSequence uint16 + hardwareAddr [6]byte +} + +// interface check -- build will fail if *Gen doesn't satisfy Generator +var _ Generator = (*Gen)(nil) + +// NewGen returns a new instance of Gen with some default values set. Most +// people should use this. +func NewGen() *Gen { + return NewGenWithHWAF(defaultHWAddrFunc) +} + +// NewGenWithHWAF builds a new UUID generator with the HWAddrFunc provided. Most +// consumers should use NewGen() instead. +// +// This is used so that consumers can generate their own MAC addresses, for use +// in the generated UUIDs, if there is some concern about exposing the physical +// address of the machine generating the UUID. +// +// The Gen generator will only invoke the HWAddrFunc once, and cache that MAC +// address for all the future UUIDs generated by it. If you'd like to switch the +// MAC address being used, you'll need to create a new generator using this +// function. +func NewGenWithHWAF(hwaf HWAddrFunc) *Gen { + return &Gen{ + epochFunc: time.Now, + hwAddrFunc: hwaf, + rand: rand.Reader, + } +} + +// NewV1 returns a UUID based on the current timestamp and MAC address. +func (g *Gen) NewV1() (UUID, error) { + u := UUID{} + + timeNow, clockSeq, err := g.getClockSequence() + if err != nil { + return Nil, err + } + binary.BigEndian.PutUint32(u[0:], uint32(timeNow)) + binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) + binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) + binary.BigEndian.PutUint16(u[8:], clockSeq) + + hardwareAddr, err := g.getHardwareAddr() + if err != nil { + return Nil, err + } + copy(u[10:], hardwareAddr) + + u.SetVersion(V1) + u.SetVariant(VariantRFC4122) + + return u, nil +} + +// NewV2 returns a DCE Security UUID based on the POSIX UID/GID. +func (g *Gen) NewV2(domain byte) (UUID, error) { + u, err := g.NewV1() + if err != nil { + return Nil, err + } + + switch domain { + case DomainPerson: + binary.BigEndian.PutUint32(u[:], posixUID) + case DomainGroup: + binary.BigEndian.PutUint32(u[:], posixGID) + } + + u[9] = domain + + u.SetVersion(V2) + u.SetVariant(VariantRFC4122) + + return u, nil +} + +// NewV3 returns a UUID based on the MD5 hash of the namespace UUID and name. +func (g *Gen) NewV3(ns UUID, name string) UUID { + u := newFromHash(md5.New(), ns, name) + u.SetVersion(V3) + u.SetVariant(VariantRFC4122) + + return u +} + +// NewV4 returns a randomly generated UUID. +func (g *Gen) NewV4() (UUID, error) { + u := UUID{} + if _, err := io.ReadFull(g.rand, u[:]); err != nil { + return Nil, err + } + u.SetVersion(V4) + u.SetVariant(VariantRFC4122) + + return u, nil +} + +// NewV5 returns a UUID based on SHA-1 hash of the namespace UUID and name. +func (g *Gen) NewV5(ns UUID, name string) UUID { + u := newFromHash(sha1.New(), ns, name) + u.SetVersion(V5) + u.SetVariant(VariantRFC4122) + + return u +} + +// Returns the epoch and clock sequence. +func (g *Gen) getClockSequence() (uint64, uint16, error) { + var err error + g.clockSequenceOnce.Do(func() { + buf := make([]byte, 2) + if _, err = io.ReadFull(g.rand, buf); err != nil { + return + } + g.clockSequence = binary.BigEndian.Uint16(buf) + }) + if err != nil { + return 0, 0, err + } + + g.storageMutex.Lock() + defer g.storageMutex.Unlock() + + timeNow := g.getEpoch() + // Clock didn't change since last UUID generation. + // Should increase clock sequence. + if timeNow <= g.lastTime { + g.clockSequence++ + } + g.lastTime = timeNow + + return timeNow, g.clockSequence, nil +} + +// Returns the hardware address. +func (g *Gen) getHardwareAddr() ([]byte, error) { + var err error + g.hardwareAddrOnce.Do(func() { + var hwAddr net.HardwareAddr + if hwAddr, err = g.hwAddrFunc(); err == nil { + copy(g.hardwareAddr[:], hwAddr) + return + } + + // Initialize hardwareAddr randomly in case + // of real network interfaces absence. + if _, err = io.ReadFull(g.rand, g.hardwareAddr[:]); err != nil { + return + } + // Set multicast bit as recommended by RFC-4122 + g.hardwareAddr[0] |= 0x01 + }) + if err != nil { + return []byte{}, err + } + return g.hardwareAddr[:], nil +} + +// Returns the difference between UUID epoch (October 15, 1582) +// and current time in 100-nanosecond intervals. +func (g *Gen) getEpoch() uint64 { + return epochStart + uint64(g.epochFunc().UnixNano()/100) +} + +// Returns the UUID based on the hashing of the namespace UUID and name. +func newFromHash(h hash.Hash, ns UUID, name string) UUID { + u := UUID{} + h.Write(ns[:]) + h.Write([]byte(name)) + copy(u[:], h.Sum(nil)) + + return u +} + +// Returns the hardware address. +func defaultHWAddrFunc() (net.HardwareAddr, error) { + ifaces, err := net.Interfaces() + if err != nil { + return []byte{}, err + } + for _, iface := range ifaces { + if len(iface.HardwareAddr) >= 6 { + return iface.HardwareAddr, nil + } + } + return []byte{}, fmt.Errorf("uuid: no HW address found") +} diff --git a/vendor/github.com/gofrs/uuid/sql.go b/vendor/github.com/gofrs/uuid/sql.go new file mode 100644 index 000000000..6f254a4fd --- /dev/null +++ b/vendor/github.com/gofrs/uuid/sql.go @@ -0,0 +1,109 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package uuid + +import ( + "bytes" + "database/sql/driver" + "encoding/json" + "fmt" +) + +// Value implements the driver.Valuer interface. +func (u UUID) Value() (driver.Value, error) { + return u.String(), nil +} + +// Scan implements the sql.Scanner interface. +// A 16-byte slice will be handled by UnmarshalBinary, while +// a longer byte slice or a string will be handled by UnmarshalText. +func (u *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case UUID: // support gorm convert from UUID to NullUUID + *u = src + return nil + + case []byte: + if len(src) == Size { + return u.UnmarshalBinary(src) + } + return u.UnmarshalText(src) + + case string: + return u.UnmarshalText([]byte(src)) + } + + return fmt.Errorf("uuid: cannot convert %T to UUID", src) +} + +// NullUUID can be used with the standard sql package to represent a +// UUID value that can be NULL in the database. +type NullUUID struct { + UUID UUID + Valid bool +} + +// Value implements the driver.Valuer interface. +func (u NullUUID) Value() (driver.Value, error) { + if !u.Valid { + return nil, nil + } + // Delegate to UUID Value function + return u.UUID.Value() +} + +// Scan implements the sql.Scanner interface. +func (u *NullUUID) Scan(src interface{}) error { + if src == nil { + u.UUID, u.Valid = Nil, false + return nil + } + + // Delegate to UUID Scan function + u.Valid = true + return u.UUID.Scan(src) +} + +// MarshalJSON marshals the NullUUID as null or the nested UUID +func (u NullUUID) MarshalJSON() ([]byte, error) { + if !u.Valid { + return json.Marshal(nil) + } + + return json.Marshal(u.UUID) +} + +// UnmarshalJSON unmarshals a NullUUID +func (u *NullUUID) UnmarshalJSON(b []byte) error { + if bytes.Equal(b, []byte("null")) { + u.UUID, u.Valid = Nil, false + return nil + } + + if err := json.Unmarshal(b, &u.UUID); err != nil { + return err + } + + u.Valid = true + + return nil +} diff --git a/vendor/github.com/gofrs/uuid/uuid.go b/vendor/github.com/gofrs/uuid/uuid.go new file mode 100644 index 000000000..29ef44059 --- /dev/null +++ b/vendor/github.com/gofrs/uuid/uuid.go @@ -0,0 +1,189 @@ +// Copyright (C) 2013-2018 by Maxim Bublis +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Package uuid provides implementations of the Universally Unique Identifier (UUID), as specified in RFC-4122 and DCE 1.1. +// +// RFC-4122[1] provides the specification for versions 1, 3, 4, and 5. +// +// DCE 1.1[2] provides the specification for version 2. +// +// [1] https://tools.ietf.org/html/rfc4122 +// [2] http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 +package uuid + +import ( + "encoding/binary" + "encoding/hex" + "fmt" + "time" +) + +// Size of a UUID in bytes. +const Size = 16 + +// UUID is an array type to represent the value of a UUID, as defined in RFC-4122. +type UUID [Size]byte + +// UUID versions. +const ( + _ byte = iota + V1 // Version 1 (date-time and MAC address) + V2 // Version 2 (date-time and MAC address, DCE security version) + V3 // Version 3 (namespace name-based) + V4 // Version 4 (random) + V5 // Version 5 (namespace name-based) +) + +// UUID layout variants. +const ( + VariantNCS byte = iota + VariantRFC4122 + VariantMicrosoft + VariantFuture +) + +// UUID DCE domains. +const ( + DomainPerson = iota + DomainGroup + DomainOrg +) + +// Timestamp is the count of 100-nanosecond intervals since 00:00:00.00, +// 15 October 1582 within a V1 UUID. This type has no meaning for V2-V5 +// UUIDs since they don't have an embedded timestamp. +type Timestamp uint64 + +const _100nsPerSecond = 10000000 + +// Time returns the UTC time.Time representation of a Timestamp +func (t Timestamp) Time() (time.Time, error) { + secs := uint64(t) / _100nsPerSecond + nsecs := 100 * (uint64(t) % _100nsPerSecond) + return time.Unix(int64(secs)-(epochStart/_100nsPerSecond), int64(nsecs)), nil +} + +// TimestampFromV1 returns the Timestamp embedded within a V1 UUID. +// Returns an error if the UUID is any version other than 1. +func TimestampFromV1(u UUID) (Timestamp, error) { + if u.Version() != 1 { + err := fmt.Errorf("uuid: %s is version %d, not version 1", u, u.Version()) + return 0, err + } + low := binary.BigEndian.Uint32(u[0:4]) + mid := binary.BigEndian.Uint16(u[4:6]) + hi := binary.BigEndian.Uint16(u[6:8]) & 0xfff + return Timestamp(uint64(low) + (uint64(mid) << 32) + (uint64(hi) << 48)), nil +} + +// String parse helpers. +var ( + urnPrefix = []byte("urn:uuid:") + byteGroups = []int{8, 4, 4, 4, 12} +) + +// Nil is the nil UUID, as specified in RFC-4122, that has all 128 bits set to +// zero. +var Nil = UUID{} + +// Predefined namespace UUIDs. +var ( + NamespaceDNS = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) + NamespaceURL = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) + NamespaceOID = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) + NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) +) + +// Version returns the algorithm version used to generate the UUID. +func (u UUID) Version() byte { + return u[6] >> 4 +} + +// Variant returns the UUID layout variant. +func (u UUID) Variant() byte { + switch { + case (u[8] >> 7) == 0x00: + return VariantNCS + case (u[8] >> 6) == 0x02: + return VariantRFC4122 + case (u[8] >> 5) == 0x06: + return VariantMicrosoft + case (u[8] >> 5) == 0x07: + fallthrough + default: + return VariantFuture + } +} + +// Bytes returns a byte slice representation of the UUID. +func (u UUID) Bytes() []byte { + return u[:] +} + +// String returns a canonical RFC-4122 string representation of the UUID: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. +func (u UUID) String() string { + buf := make([]byte, 36) + + hex.Encode(buf[0:8], u[0:4]) + buf[8] = '-' + hex.Encode(buf[9:13], u[4:6]) + buf[13] = '-' + hex.Encode(buf[14:18], u[6:8]) + buf[18] = '-' + hex.Encode(buf[19:23], u[8:10]) + buf[23] = '-' + hex.Encode(buf[24:], u[10:]) + + return string(buf) +} + +// SetVersion sets the version bits. +func (u *UUID) SetVersion(v byte) { + u[6] = (u[6] & 0x0f) | (v << 4) +} + +// SetVariant sets the variant bits. +func (u *UUID) SetVariant(v byte) { + switch v { + case VariantNCS: + u[8] = (u[8]&(0xff>>1) | (0x00 << 7)) + case VariantRFC4122: + u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) + case VariantMicrosoft: + u[8] = (u[8]&(0xff>>3) | (0x06 << 5)) + case VariantFuture: + fallthrough + default: + u[8] = (u[8]&(0xff>>3) | (0x07 << 5)) + } +} + +// Must is a helper that wraps a call to a function returning (UUID, error) +// and panics if the error is non-nil. It is intended for use in variable +// initializations such as +// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000")) +func Must(u UUID, err error) UUID { + if err != nil { + panic(err) + } + return u +} diff --git a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go new file mode 100644 index 000000000..ada2b78e8 --- /dev/null +++ b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go @@ -0,0 +1,1271 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/* +Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON. +It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json. + +This package produces a different output than the standard "encoding/json" package, +which does not operate correctly on protocol buffers. +*/ +package jsonpb + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io" + "math" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + + stpb "github.com/golang/protobuf/ptypes/struct" +) + +const secondInNanos = int64(time.Second / time.Nanosecond) + +// Marshaler is a configurable object for converting between +// protocol buffer objects and a JSON representation for them. +type Marshaler struct { + // Whether to render enum values as integers, as opposed to string values. + EnumsAsInts bool + + // Whether to render fields with zero values. + EmitDefaults bool + + // A string to indent each level by. The presence of this field will + // also cause a space to appear between the field separator and + // value, and for newlines to be appear between fields and array + // elements. + Indent string + + // Whether to use the original (.proto) name for fields. + OrigName bool + + // A custom URL resolver to use when marshaling Any messages to JSON. + // If unset, the default resolution strategy is to extract the + // fully-qualified type name from the type URL and pass that to + // proto.MessageType(string). + AnyResolver AnyResolver +} + +// AnyResolver takes a type URL, present in an Any message, and resolves it into +// an instance of the associated message. +type AnyResolver interface { + Resolve(typeUrl string) (proto.Message, error) +} + +func defaultResolveAny(typeUrl string) (proto.Message, error) { + // Only the part of typeUrl after the last slash is relevant. + mname := typeUrl + if slash := strings.LastIndex(mname, "/"); slash >= 0 { + mname = mname[slash+1:] + } + mt := proto.MessageType(mname) + if mt == nil { + return nil, fmt.Errorf("unknown message type %q", mname) + } + return reflect.New(mt.Elem()).Interface().(proto.Message), nil +} + +// JSONPBMarshaler is implemented by protobuf messages that customize the +// way they are marshaled to JSON. Messages that implement this should +// also implement JSONPBUnmarshaler so that the custom format can be +// parsed. +// +// The JSON marshaling must follow the proto to JSON specification: +// https://developers.google.com/protocol-buffers/docs/proto3#json +type JSONPBMarshaler interface { + MarshalJSONPB(*Marshaler) ([]byte, error) +} + +// JSONPBUnmarshaler is implemented by protobuf messages that customize +// the way they are unmarshaled from JSON. Messages that implement this +// should also implement JSONPBMarshaler so that the custom format can be +// produced. +// +// The JSON unmarshaling must follow the JSON to proto specification: +// https://developers.google.com/protocol-buffers/docs/proto3#json +type JSONPBUnmarshaler interface { + UnmarshalJSONPB(*Unmarshaler, []byte) error +} + +// Marshal marshals a protocol buffer into JSON. +func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error { + v := reflect.ValueOf(pb) + if pb == nil || (v.Kind() == reflect.Ptr && v.IsNil()) { + return errors.New("Marshal called with nil") + } + // Check for unset required fields first. + if err := checkRequiredFields(pb); err != nil { + return err + } + writer := &errWriter{writer: out} + return m.marshalObject(writer, pb, "", "") +} + +// MarshalToString converts a protocol buffer object to JSON string. +func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) { + var buf bytes.Buffer + if err := m.Marshal(&buf, pb); err != nil { + return "", err + } + return buf.String(), nil +} + +type int32Slice []int32 + +var nonFinite = map[string]float64{ + `"NaN"`: math.NaN(), + `"Infinity"`: math.Inf(1), + `"-Infinity"`: math.Inf(-1), +} + +// For sorting extensions ids to ensure stable output. +func (s int32Slice) Len() int { return len(s) } +func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +type wkt interface { + XXX_WellKnownType() string +} + +// marshalObject writes a struct to the Writer. +func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error { + if jsm, ok := v.(JSONPBMarshaler); ok { + b, err := jsm.MarshalJSONPB(m) + if err != nil { + return err + } + if typeURL != "" { + // we are marshaling this object to an Any type + var js map[string]*json.RawMessage + if err = json.Unmarshal(b, &js); err != nil { + return fmt.Errorf("type %T produced invalid JSON: %v", v, err) + } + turl, err := json.Marshal(typeURL) + if err != nil { + return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) + } + js["@type"] = (*json.RawMessage)(&turl) + if b, err = json.Marshal(js); err != nil { + return err + } + } + + out.write(string(b)) + return out.err + } + + s := reflect.ValueOf(v).Elem() + + // Handle well-known types. + if wkt, ok := v.(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", + "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": + // "Wrappers use the same representation in JSON + // as the wrapped primitive type, ..." + sprop := proto.GetProperties(s.Type()) + return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent) + case "Any": + // Any is a bit more involved. + return m.marshalAny(out, v, indent) + case "Duration": + // "Generated output always contains 0, 3, 6, or 9 fractional digits, + // depending on required precision." + s, ns := s.Field(0).Int(), s.Field(1).Int() + if ns <= -secondInNanos || ns >= secondInNanos { + return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) + } + if (s > 0 && ns < 0) || (s < 0 && ns > 0) { + return errors.New("signs of seconds and nanos do not match") + } + if s < 0 { + ns = -ns + } + x := fmt.Sprintf("%d.%09d", s, ns) + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, ".000") + out.write(`"`) + out.write(x) + out.write(`s"`) + return out.err + case "Struct", "ListValue": + // Let marshalValue handle the `Struct.fields` map or the `ListValue.values` slice. + // TODO: pass the correct Properties if needed. + return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent) + case "Timestamp": + // "RFC 3339, where generated output will always be Z-normalized + // and uses 0, 3, 6 or 9 fractional digits." + s, ns := s.Field(0).Int(), s.Field(1).Int() + if ns < 0 || ns >= secondInNanos { + return fmt.Errorf("ns out of range [0, %v)", secondInNanos) + } + t := time.Unix(s, ns).UTC() + // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). + x := t.Format("2006-01-02T15:04:05.000000000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, ".000") + out.write(`"`) + out.write(x) + out.write(`Z"`) + return out.err + case "Value": + // Value has a single oneof. + kind := s.Field(0) + if kind.IsNil() { + // "absence of any variant indicates an error" + return errors.New("nil Value") + } + // oneof -> *T -> T -> T.F + x := kind.Elem().Elem().Field(0) + // TODO: pass the correct Properties if needed. + return m.marshalValue(out, &proto.Properties{}, x, indent) + } + } + + out.write("{") + if m.Indent != "" { + out.write("\n") + } + + firstField := true + + if typeURL != "" { + if err := m.marshalTypeURL(out, indent, typeURL); err != nil { + return err + } + firstField = false + } + + for i := 0; i < s.NumField(); i++ { + value := s.Field(i) + valueField := s.Type().Field(i) + if strings.HasPrefix(valueField.Name, "XXX_") { + continue + } + + // IsNil will panic on most value kinds. + switch value.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface: + if value.IsNil() { + continue + } + } + + if !m.EmitDefaults { + switch value.Kind() { + case reflect.Bool: + if !value.Bool() { + continue + } + case reflect.Int32, reflect.Int64: + if value.Int() == 0 { + continue + } + case reflect.Uint32, reflect.Uint64: + if value.Uint() == 0 { + continue + } + case reflect.Float32, reflect.Float64: + if value.Float() == 0 { + continue + } + case reflect.String: + if value.Len() == 0 { + continue + } + case reflect.Map, reflect.Ptr, reflect.Slice: + if value.IsNil() { + continue + } + } + } + + // Oneof fields need special handling. + if valueField.Tag.Get("protobuf_oneof") != "" { + // value is an interface containing &T{real_value}. + sv := value.Elem().Elem() // interface -> *T -> T + value = sv.Field(0) + valueField = sv.Type().Field(0) + } + prop := jsonProperties(valueField, m.OrigName) + if !firstField { + m.writeSep(out) + } + if err := m.marshalField(out, prop, value, indent); err != nil { + return err + } + firstField = false + } + + // Handle proto2 extensions. + if ep, ok := v.(proto.Message); ok { + extensions := proto.RegisteredExtensions(v) + // Sort extensions for stable output. + ids := make([]int32, 0, len(extensions)) + for id, desc := range extensions { + if !proto.HasExtension(ep, desc) { + continue + } + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) + for _, id := range ids { + desc := extensions[id] + if desc == nil { + // unknown extension + continue + } + ext, extErr := proto.GetExtension(ep, desc) + if extErr != nil { + return extErr + } + value := reflect.ValueOf(ext) + var prop proto.Properties + prop.Parse(desc.Tag) + prop.JSONName = fmt.Sprintf("[%s]", desc.Name) + if !firstField { + m.writeSep(out) + } + if err := m.marshalField(out, &prop, value, indent); err != nil { + return err + } + firstField = false + } + + } + + if m.Indent != "" { + out.write("\n") + out.write(indent) + } + out.write("}") + return out.err +} + +func (m *Marshaler) writeSep(out *errWriter) { + if m.Indent != "" { + out.write(",\n") + } else { + out.write(",") + } +} + +func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error { + // "If the Any contains a value that has a special JSON mapping, + // it will be converted as follows: {"@type": xxx, "value": yyy}. + // Otherwise, the value will be converted into a JSON object, + // and the "@type" field will be inserted to indicate the actual data type." + v := reflect.ValueOf(any).Elem() + turl := v.Field(0).String() + val := v.Field(1).Bytes() + + var msg proto.Message + var err error + if m.AnyResolver != nil { + msg, err = m.AnyResolver.Resolve(turl) + } else { + msg, err = defaultResolveAny(turl) + } + if err != nil { + return err + } + + if err := proto.Unmarshal(val, msg); err != nil { + return err + } + + if _, ok := msg.(wkt); ok { + out.write("{") + if m.Indent != "" { + out.write("\n") + } + if err := m.marshalTypeURL(out, indent, turl); err != nil { + return err + } + m.writeSep(out) + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + out.write(`"value": `) + } else { + out.write(`"value":`) + } + if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil { + return err + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + } + out.write("}") + return out.err + } + + return m.marshalObject(out, msg, indent, turl) +} + +func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error { + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + } + out.write(`"@type":`) + if m.Indent != "" { + out.write(" ") + } + b, err := json.Marshal(typeURL) + if err != nil { + return err + } + out.write(string(b)) + return out.err +} + +// marshalField writes field description and value to the Writer. +func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + } + out.write(`"`) + out.write(prop.JSONName) + out.write(`":`) + if m.Indent != "" { + out.write(" ") + } + if err := m.marshalValue(out, prop, v, indent); err != nil { + return err + } + return nil +} + +// marshalValue writes the value to the Writer. +func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { + var err error + v = reflect.Indirect(v) + + // Handle nil pointer + if v.Kind() == reflect.Invalid { + out.write("null") + return out.err + } + + // Handle repeated elements. + if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { + out.write("[") + comma := "" + for i := 0; i < v.Len(); i++ { + sliceVal := v.Index(i) + out.write(comma) + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + out.write(m.Indent) + } + if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil { + return err + } + comma = "," + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + } + out.write("]") + return out.err + } + + // Handle well-known types. + // Most are handled up in marshalObject (because 99% are messages). + if wkt, ok := v.Interface().(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "NullValue": + out.write("null") + return out.err + } + } + + // Handle enumerations. + if !m.EnumsAsInts && prop.Enum != "" { + // Unknown enum values will are stringified by the proto library as their + // value. Such values should _not_ be quoted or they will be interpreted + // as an enum string instead of their value. + enumStr := v.Interface().(fmt.Stringer).String() + var valStr string + if v.Kind() == reflect.Ptr { + valStr = strconv.Itoa(int(v.Elem().Int())) + } else { + valStr = strconv.Itoa(int(v.Int())) + } + isKnownEnum := enumStr != valStr + if isKnownEnum { + out.write(`"`) + } + out.write(enumStr) + if isKnownEnum { + out.write(`"`) + } + return out.err + } + + // Handle nested messages. + if v.Kind() == reflect.Struct { + return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "") + } + + // Handle maps. + // Since Go randomizes map iteration, we sort keys for stable output. + if v.Kind() == reflect.Map { + out.write(`{`) + keys := v.MapKeys() + sort.Sort(mapKeys(keys)) + for i, k := range keys { + if i > 0 { + out.write(`,`) + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + out.write(m.Indent) + } + + // TODO handle map key prop properly + b, err := json.Marshal(k.Interface()) + if err != nil { + return err + } + s := string(b) + + // If the JSON is not a string value, encode it again to make it one. + if !strings.HasPrefix(s, `"`) { + b, err := json.Marshal(s) + if err != nil { + return err + } + s = string(b) + } + + out.write(s) + out.write(`:`) + if m.Indent != "" { + out.write(` `) + } + + vprop := prop + if prop != nil && prop.MapValProp != nil { + vprop = prop.MapValProp + } + if err := m.marshalValue(out, vprop, v.MapIndex(k), indent+m.Indent); err != nil { + return err + } + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + } + out.write(`}`) + return out.err + } + + // Handle non-finite floats, e.g. NaN, Infinity and -Infinity. + if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { + f := v.Float() + var sval string + switch { + case math.IsInf(f, 1): + sval = `"Infinity"` + case math.IsInf(f, -1): + sval = `"-Infinity"` + case math.IsNaN(f): + sval = `"NaN"` + } + if sval != "" { + out.write(sval) + return out.err + } + } + + // Default handling defers to the encoding/json library. + b, err := json.Marshal(v.Interface()) + if err != nil { + return err + } + needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64) + if needToQuote { + out.write(`"`) + } + out.write(string(b)) + if needToQuote { + out.write(`"`) + } + return out.err +} + +// Unmarshaler is a configurable object for converting from a JSON +// representation to a protocol buffer object. +type Unmarshaler struct { + // Whether to allow messages to contain unknown fields, as opposed to + // failing to unmarshal. + AllowUnknownFields bool + + // A custom URL resolver to use when unmarshaling Any messages from JSON. + // If unset, the default resolution strategy is to extract the + // fully-qualified type name from the type URL and pass that to + // proto.MessageType(string). + AnyResolver AnyResolver +} + +// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. +// This function is lenient and will decode any options permutations of the +// related Marshaler. +func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error { + inputValue := json.RawMessage{} + if err := dec.Decode(&inputValue); err != nil { + return err + } + if err := u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil); err != nil { + return err + } + return checkRequiredFields(pb) +} + +// Unmarshal unmarshals a JSON object stream into a protocol +// buffer. This function is lenient and will decode any options +// permutations of the related Marshaler. +func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error { + dec := json.NewDecoder(r) + return u.UnmarshalNext(dec, pb) +} + +// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. +// This function is lenient and will decode any options permutations of the +// related Marshaler. +func UnmarshalNext(dec *json.Decoder, pb proto.Message) error { + return new(Unmarshaler).UnmarshalNext(dec, pb) +} + +// Unmarshal unmarshals a JSON object stream into a protocol +// buffer. This function is lenient and will decode any options +// permutations of the related Marshaler. +func Unmarshal(r io.Reader, pb proto.Message) error { + return new(Unmarshaler).Unmarshal(r, pb) +} + +// UnmarshalString will populate the fields of a protocol buffer based +// on a JSON string. This function is lenient and will decode any options +// permutations of the related Marshaler. +func UnmarshalString(str string, pb proto.Message) error { + return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb) +} + +// unmarshalValue converts/copies a value into the target. +// prop may be nil. +func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error { + targetType := target.Type() + + // Allocate memory for pointer fields. + if targetType.Kind() == reflect.Ptr { + // If input value is "null" and target is a pointer type, then the field should be treated as not set + // UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue. + _, isJSONPBUnmarshaler := target.Interface().(JSONPBUnmarshaler) + if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) && !isJSONPBUnmarshaler { + return nil + } + target.Set(reflect.New(targetType.Elem())) + + return u.unmarshalValue(target.Elem(), inputValue, prop) + } + + if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok { + return jsu.UnmarshalJSONPB(u, []byte(inputValue)) + } + + // Handle well-known types that are not pointers. + if w, ok := target.Addr().Interface().(wkt); ok { + switch w.XXX_WellKnownType() { + case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", + "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": + return u.unmarshalValue(target.Field(0), inputValue, prop) + case "Any": + // Use json.RawMessage pointer type instead of value to support pre-1.8 version. + // 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see + // https://github.com/golang/go/issues/14493 + var jsonFields map[string]*json.RawMessage + if err := json.Unmarshal(inputValue, &jsonFields); err != nil { + return err + } + + val, ok := jsonFields["@type"] + if !ok || val == nil { + return errors.New("Any JSON doesn't have '@type'") + } + + var turl string + if err := json.Unmarshal([]byte(*val), &turl); err != nil { + return fmt.Errorf("can't unmarshal Any's '@type': %q", *val) + } + target.Field(0).SetString(turl) + + var m proto.Message + var err error + if u.AnyResolver != nil { + m, err = u.AnyResolver.Resolve(turl) + } else { + m, err = defaultResolveAny(turl) + } + if err != nil { + return err + } + + if _, ok := m.(wkt); ok { + val, ok := jsonFields["value"] + if !ok { + return errors.New("Any JSON doesn't have 'value'") + } + + if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil { + return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) + } + } else { + delete(jsonFields, "@type") + nestedProto, err := json.Marshal(jsonFields) + if err != nil { + return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) + } + + if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil { + return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) + } + } + + b, err := proto.Marshal(m) + if err != nil { + return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err) + } + target.Field(1).SetBytes(b) + + return nil + case "Duration": + unq, err := unquote(string(inputValue)) + if err != nil { + return err + } + + d, err := time.ParseDuration(unq) + if err != nil { + return fmt.Errorf("bad Duration: %v", err) + } + + ns := d.Nanoseconds() + s := ns / 1e9 + ns %= 1e9 + target.Field(0).SetInt(s) + target.Field(1).SetInt(ns) + return nil + case "Timestamp": + unq, err := unquote(string(inputValue)) + if err != nil { + return err + } + + t, err := time.Parse(time.RFC3339Nano, unq) + if err != nil { + return fmt.Errorf("bad Timestamp: %v", err) + } + + target.Field(0).SetInt(t.Unix()) + target.Field(1).SetInt(int64(t.Nanosecond())) + return nil + case "Struct": + var m map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &m); err != nil { + return fmt.Errorf("bad StructValue: %v", err) + } + + target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{})) + for k, jv := range m { + pv := &stpb.Value{} + if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil { + return fmt.Errorf("bad value in StructValue for key %q: %v", k, err) + } + target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv)) + } + return nil + case "ListValue": + var s []json.RawMessage + if err := json.Unmarshal(inputValue, &s); err != nil { + return fmt.Errorf("bad ListValue: %v", err) + } + + target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s)))) + for i, sv := range s { + if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil { + return err + } + } + return nil + case "Value": + ivStr := string(inputValue) + if ivStr == "null" { + target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{})) + } else if v, err := strconv.ParseFloat(ivStr, 0); err == nil { + target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v})) + } else if v, err := unquote(ivStr); err == nil { + target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v})) + } else if v, err := strconv.ParseBool(ivStr); err == nil { + target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v})) + } else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil { + lv := &stpb.ListValue{} + target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv})) + return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop) + } else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil { + sv := &stpb.Struct{} + target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv})) + return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop) + } else { + return fmt.Errorf("unrecognized type for Value %q", ivStr) + } + return nil + } + } + + // Handle enums, which have an underlying type of int32, + // and may appear as strings. + // The case of an enum appearing as a number is handled + // at the bottom of this function. + if inputValue[0] == '"' && prop != nil && prop.Enum != "" { + vmap := proto.EnumValueMap(prop.Enum) + // Don't need to do unquoting; valid enum names + // are from a limited character set. + s := inputValue[1 : len(inputValue)-1] + n, ok := vmap[string(s)] + if !ok { + return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum) + } + if target.Kind() == reflect.Ptr { // proto2 + target.Set(reflect.New(targetType.Elem())) + target = target.Elem() + } + if targetType.Kind() != reflect.Int32 { + return fmt.Errorf("invalid target %q for enum %s", targetType.Kind(), prop.Enum) + } + target.SetInt(int64(n)) + return nil + } + + // Handle nested messages. + if targetType.Kind() == reflect.Struct { + var jsonFields map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &jsonFields); err != nil { + return err + } + + consumeField := func(prop *proto.Properties) (json.RawMessage, bool) { + // Be liberal in what names we accept; both orig_name and camelName are okay. + fieldNames := acceptedJSONFieldNames(prop) + + vOrig, okOrig := jsonFields[fieldNames.orig] + vCamel, okCamel := jsonFields[fieldNames.camel] + if !okOrig && !okCamel { + return nil, false + } + // If, for some reason, both are present in the data, favour the camelName. + var raw json.RawMessage + if okOrig { + raw = vOrig + delete(jsonFields, fieldNames.orig) + } + if okCamel { + raw = vCamel + delete(jsonFields, fieldNames.camel) + } + return raw, true + } + + sprops := proto.GetProperties(targetType) + for i := 0; i < target.NumField(); i++ { + ft := target.Type().Field(i) + if strings.HasPrefix(ft.Name, "XXX_") { + continue + } + + valueForField, ok := consumeField(sprops.Prop[i]) + if !ok { + continue + } + + if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil { + return err + } + } + // Check for any oneof fields. + if len(jsonFields) > 0 { + for _, oop := range sprops.OneofTypes { + raw, ok := consumeField(oop.Prop) + if !ok { + continue + } + nv := reflect.New(oop.Type.Elem()) + target.Field(oop.Field).Set(nv) + if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil { + return err + } + } + } + // Handle proto2 extensions. + if len(jsonFields) > 0 { + if ep, ok := target.Addr().Interface().(proto.Message); ok { + for _, ext := range proto.RegisteredExtensions(ep) { + name := fmt.Sprintf("[%s]", ext.Name) + raw, ok := jsonFields[name] + if !ok { + continue + } + delete(jsonFields, name) + nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem()) + if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil { + return err + } + if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil { + return err + } + } + } + } + if !u.AllowUnknownFields && len(jsonFields) > 0 { + // Pick any field to be the scapegoat. + var f string + for fname := range jsonFields { + f = fname + break + } + return fmt.Errorf("unknown field %q in %v", f, targetType) + } + return nil + } + + // Handle arrays (which aren't encoded bytes) + if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 { + var slc []json.RawMessage + if err := json.Unmarshal(inputValue, &slc); err != nil { + return err + } + if slc != nil { + l := len(slc) + target.Set(reflect.MakeSlice(targetType, l, l)) + for i := 0; i < l; i++ { + if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil { + return err + } + } + } + return nil + } + + // Handle maps (whose keys are always strings) + if targetType.Kind() == reflect.Map { + var mp map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &mp); err != nil { + return err + } + if mp != nil { + target.Set(reflect.MakeMap(targetType)) + for ks, raw := range mp { + // Unmarshal map key. The core json library already decoded the key into a + // string, so we handle that specially. Other types were quoted post-serialization. + var k reflect.Value + if targetType.Key().Kind() == reflect.String { + k = reflect.ValueOf(ks) + } else { + k = reflect.New(targetType.Key()).Elem() + var kprop *proto.Properties + if prop != nil && prop.MapKeyProp != nil { + kprop = prop.MapKeyProp + } + if err := u.unmarshalValue(k, json.RawMessage(ks), kprop); err != nil { + return err + } + } + + // Unmarshal map value. + v := reflect.New(targetType.Elem()).Elem() + var vprop *proto.Properties + if prop != nil && prop.MapValProp != nil { + vprop = prop.MapValProp + } + if err := u.unmarshalValue(v, raw, vprop); err != nil { + return err + } + target.SetMapIndex(k, v) + } + } + return nil + } + + // Non-finite numbers can be encoded as strings. + isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64 + if isFloat { + if num, ok := nonFinite[string(inputValue)]; ok { + target.SetFloat(num) + return nil + } + } + + // integers & floats can be encoded as strings. In this case we drop + // the quotes and proceed as normal. + isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 || + targetType.Kind() == reflect.Int32 || targetType.Kind() == reflect.Uint32 || + targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64 + if isNum && strings.HasPrefix(string(inputValue), `"`) { + inputValue = inputValue[1 : len(inputValue)-1] + } + + // Use the encoding/json for parsing other value types. + return json.Unmarshal(inputValue, target.Addr().Interface()) +} + +func unquote(s string) (string, error) { + var ret string + err := json.Unmarshal([]byte(s), &ret) + return ret, err +} + +// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute. +func jsonProperties(f reflect.StructField, origName bool) *proto.Properties { + var prop proto.Properties + prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f) + if origName || prop.JSONName == "" { + prop.JSONName = prop.OrigName + } + return &prop +} + +type fieldNames struct { + orig, camel string +} + +func acceptedJSONFieldNames(prop *proto.Properties) fieldNames { + opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName} + if prop.JSONName != "" { + opts.camel = prop.JSONName + } + return opts +} + +// Writer wrapper inspired by https://blog.golang.org/errors-are-values +type errWriter struct { + writer io.Writer + err error +} + +func (w *errWriter) write(str string) { + if w.err != nil { + return + } + _, w.err = w.writer.Write([]byte(str)) +} + +// Map fields may have key types of non-float scalars, strings and enums. +// The easiest way to sort them in some deterministic order is to use fmt. +// If this turns out to be inefficient we can always consider other options, +// such as doing a Schwartzian transform. +// +// Numeric keys are sorted in numeric order per +// https://developers.google.com/protocol-buffers/docs/proto#maps. +type mapKeys []reflect.Value + +func (s mapKeys) Len() int { return len(s) } +func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s mapKeys) Less(i, j int) bool { + if k := s[i].Kind(); k == s[j].Kind() { + switch k { + case reflect.String: + return s[i].String() < s[j].String() + case reflect.Int32, reflect.Int64: + return s[i].Int() < s[j].Int() + case reflect.Uint32, reflect.Uint64: + return s[i].Uint() < s[j].Uint() + } + } + return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) +} + +// checkRequiredFields returns an error if any required field in the given proto message is not set. +// This function is used by both Marshal and Unmarshal. While required fields only exist in a +// proto2 message, a proto3 message can contain proto2 message(s). +func checkRequiredFields(pb proto.Message) error { + // Most well-known type messages do not contain required fields. The "Any" type may contain + // a message that has required fields. + // + // When an Any message is being marshaled, the code will invoked proto.Unmarshal on Any.Value + // field in order to transform that into JSON, and that should have returned an error if a + // required field is not set in the embedded message. + // + // When an Any message is being unmarshaled, the code will have invoked proto.Marshal on the + // embedded message to store the serialized message in Any.Value field, and that should have + // returned an error if a required field is not set. + if _, ok := pb.(wkt); ok { + return nil + } + + v := reflect.ValueOf(pb) + // Skip message if it is not a struct pointer. + if v.Kind() != reflect.Ptr { + return nil + } + v = v.Elem() + if v.Kind() != reflect.Struct { + return nil + } + + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + sfield := v.Type().Field(i) + + if sfield.PkgPath != "" { + // blank PkgPath means the field is exported; skip if not exported + continue + } + + if strings.HasPrefix(sfield.Name, "XXX_") { + continue + } + + // Oneof field is an interface implemented by wrapper structs containing the actual oneof + // field, i.e. an interface containing &T{real_value}. + if sfield.Tag.Get("protobuf_oneof") != "" { + if field.Kind() != reflect.Interface { + continue + } + v := field.Elem() + if v.Kind() != reflect.Ptr || v.IsNil() { + continue + } + v = v.Elem() + if v.Kind() != reflect.Struct || v.NumField() < 1 { + continue + } + field = v.Field(0) + sfield = v.Type().Field(0) + } + + protoTag := sfield.Tag.Get("protobuf") + if protoTag == "" { + continue + } + var prop proto.Properties + prop.Init(sfield.Type, sfield.Name, protoTag, &sfield) + + switch field.Kind() { + case reflect.Map: + if field.IsNil() { + continue + } + // Check each map value. + keys := field.MapKeys() + for _, k := range keys { + v := field.MapIndex(k) + if err := checkRequiredFieldsInValue(v); err != nil { + return err + } + } + case reflect.Slice: + // Handle non-repeated type, e.g. bytes. + if !prop.Repeated { + if prop.Required && field.IsNil() { + return fmt.Errorf("required field %q is not set", prop.Name) + } + continue + } + + // Handle repeated type. + if field.IsNil() { + continue + } + // Check each slice item. + for i := 0; i < field.Len(); i++ { + v := field.Index(i) + if err := checkRequiredFieldsInValue(v); err != nil { + return err + } + } + case reflect.Ptr: + if field.IsNil() { + if prop.Required { + return fmt.Errorf("required field %q is not set", prop.Name) + } + continue + } + if err := checkRequiredFieldsInValue(field); err != nil { + return err + } + } + } + + // Handle proto2 extensions. + for _, ext := range proto.RegisteredExtensions(pb) { + if !proto.HasExtension(pb, ext) { + continue + } + ep, err := proto.GetExtension(pb, ext) + if err != nil { + return err + } + err = checkRequiredFieldsInValue(reflect.ValueOf(ep)) + if err != nil { + return err + } + } + + return nil +} + +func checkRequiredFieldsInValue(v reflect.Value) error { + if pm, ok := v.Interface().(proto.Message); ok { + return checkRequiredFields(pm) + } + return nil +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go new file mode 100644 index 000000000..1ded05bbe --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go @@ -0,0 +1,2887 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/descriptor.proto + +package descriptor + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type FieldDescriptorProto_Type int32 + +const ( + // 0 is reserved for errors. + // Order is weird for historical reasons. + FieldDescriptorProto_TYPE_DOUBLE FieldDescriptorProto_Type = 1 + FieldDescriptorProto_TYPE_FLOAT FieldDescriptorProto_Type = 2 + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + FieldDescriptorProto_TYPE_INT64 FieldDescriptorProto_Type = 3 + FieldDescriptorProto_TYPE_UINT64 FieldDescriptorProto_Type = 4 + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + FieldDescriptorProto_TYPE_INT32 FieldDescriptorProto_Type = 5 + FieldDescriptorProto_TYPE_FIXED64 FieldDescriptorProto_Type = 6 + FieldDescriptorProto_TYPE_FIXED32 FieldDescriptorProto_Type = 7 + FieldDescriptorProto_TYPE_BOOL FieldDescriptorProto_Type = 8 + FieldDescriptorProto_TYPE_STRING FieldDescriptorProto_Type = 9 + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + FieldDescriptorProto_TYPE_GROUP FieldDescriptorProto_Type = 10 + FieldDescriptorProto_TYPE_MESSAGE FieldDescriptorProto_Type = 11 + // New in version 2. + FieldDescriptorProto_TYPE_BYTES FieldDescriptorProto_Type = 12 + FieldDescriptorProto_TYPE_UINT32 FieldDescriptorProto_Type = 13 + FieldDescriptorProto_TYPE_ENUM FieldDescriptorProto_Type = 14 + FieldDescriptorProto_TYPE_SFIXED32 FieldDescriptorProto_Type = 15 + FieldDescriptorProto_TYPE_SFIXED64 FieldDescriptorProto_Type = 16 + FieldDescriptorProto_TYPE_SINT32 FieldDescriptorProto_Type = 17 + FieldDescriptorProto_TYPE_SINT64 FieldDescriptorProto_Type = 18 +) + +var FieldDescriptorProto_Type_name = map[int32]string{ + 1: "TYPE_DOUBLE", + 2: "TYPE_FLOAT", + 3: "TYPE_INT64", + 4: "TYPE_UINT64", + 5: "TYPE_INT32", + 6: "TYPE_FIXED64", + 7: "TYPE_FIXED32", + 8: "TYPE_BOOL", + 9: "TYPE_STRING", + 10: "TYPE_GROUP", + 11: "TYPE_MESSAGE", + 12: "TYPE_BYTES", + 13: "TYPE_UINT32", + 14: "TYPE_ENUM", + 15: "TYPE_SFIXED32", + 16: "TYPE_SFIXED64", + 17: "TYPE_SINT32", + 18: "TYPE_SINT64", +} + +var FieldDescriptorProto_Type_value = map[string]int32{ + "TYPE_DOUBLE": 1, + "TYPE_FLOAT": 2, + "TYPE_INT64": 3, + "TYPE_UINT64": 4, + "TYPE_INT32": 5, + "TYPE_FIXED64": 6, + "TYPE_FIXED32": 7, + "TYPE_BOOL": 8, + "TYPE_STRING": 9, + "TYPE_GROUP": 10, + "TYPE_MESSAGE": 11, + "TYPE_BYTES": 12, + "TYPE_UINT32": 13, + "TYPE_ENUM": 14, + "TYPE_SFIXED32": 15, + "TYPE_SFIXED64": 16, + "TYPE_SINT32": 17, + "TYPE_SINT64": 18, +} + +func (x FieldDescriptorProto_Type) Enum() *FieldDescriptorProto_Type { + p := new(FieldDescriptorProto_Type) + *p = x + return p +} + +func (x FieldDescriptorProto_Type) String() string { + return proto.EnumName(FieldDescriptorProto_Type_name, int32(x)) +} + +func (x *FieldDescriptorProto_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Type_value, data, "FieldDescriptorProto_Type") + if err != nil { + return err + } + *x = FieldDescriptorProto_Type(value) + return nil +} + +func (FieldDescriptorProto_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{4, 0} +} + +type FieldDescriptorProto_Label int32 + +const ( + // 0 is reserved for errors + FieldDescriptorProto_LABEL_OPTIONAL FieldDescriptorProto_Label = 1 + FieldDescriptorProto_LABEL_REQUIRED FieldDescriptorProto_Label = 2 + FieldDescriptorProto_LABEL_REPEATED FieldDescriptorProto_Label = 3 +) + +var FieldDescriptorProto_Label_name = map[int32]string{ + 1: "LABEL_OPTIONAL", + 2: "LABEL_REQUIRED", + 3: "LABEL_REPEATED", +} + +var FieldDescriptorProto_Label_value = map[string]int32{ + "LABEL_OPTIONAL": 1, + "LABEL_REQUIRED": 2, + "LABEL_REPEATED": 3, +} + +func (x FieldDescriptorProto_Label) Enum() *FieldDescriptorProto_Label { + p := new(FieldDescriptorProto_Label) + *p = x + return p +} + +func (x FieldDescriptorProto_Label) String() string { + return proto.EnumName(FieldDescriptorProto_Label_name, int32(x)) +} + +func (x *FieldDescriptorProto_Label) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Label_value, data, "FieldDescriptorProto_Label") + if err != nil { + return err + } + *x = FieldDescriptorProto_Label(value) + return nil +} + +func (FieldDescriptorProto_Label) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{4, 1} +} + +// Generated classes can be optimized for speed or code size. +type FileOptions_OptimizeMode int32 + +const ( + FileOptions_SPEED FileOptions_OptimizeMode = 1 + // etc. + FileOptions_CODE_SIZE FileOptions_OptimizeMode = 2 + FileOptions_LITE_RUNTIME FileOptions_OptimizeMode = 3 +) + +var FileOptions_OptimizeMode_name = map[int32]string{ + 1: "SPEED", + 2: "CODE_SIZE", + 3: "LITE_RUNTIME", +} + +var FileOptions_OptimizeMode_value = map[string]int32{ + "SPEED": 1, + "CODE_SIZE": 2, + "LITE_RUNTIME": 3, +} + +func (x FileOptions_OptimizeMode) Enum() *FileOptions_OptimizeMode { + p := new(FileOptions_OptimizeMode) + *p = x + return p +} + +func (x FileOptions_OptimizeMode) String() string { + return proto.EnumName(FileOptions_OptimizeMode_name, int32(x)) +} + +func (x *FileOptions_OptimizeMode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FileOptions_OptimizeMode_value, data, "FileOptions_OptimizeMode") + if err != nil { + return err + } + *x = FileOptions_OptimizeMode(value) + return nil +} + +func (FileOptions_OptimizeMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{10, 0} +} + +type FieldOptions_CType int32 + +const ( + // Default mode. + FieldOptions_STRING FieldOptions_CType = 0 + FieldOptions_CORD FieldOptions_CType = 1 + FieldOptions_STRING_PIECE FieldOptions_CType = 2 +) + +var FieldOptions_CType_name = map[int32]string{ + 0: "STRING", + 1: "CORD", + 2: "STRING_PIECE", +} + +var FieldOptions_CType_value = map[string]int32{ + "STRING": 0, + "CORD": 1, + "STRING_PIECE": 2, +} + +func (x FieldOptions_CType) Enum() *FieldOptions_CType { + p := new(FieldOptions_CType) + *p = x + return p +} + +func (x FieldOptions_CType) String() string { + return proto.EnumName(FieldOptions_CType_name, int32(x)) +} + +func (x *FieldOptions_CType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldOptions_CType_value, data, "FieldOptions_CType") + if err != nil { + return err + } + *x = FieldOptions_CType(value) + return nil +} + +func (FieldOptions_CType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{12, 0} +} + +type FieldOptions_JSType int32 + +const ( + // Use the default type. + FieldOptions_JS_NORMAL FieldOptions_JSType = 0 + // Use JavaScript strings. + FieldOptions_JS_STRING FieldOptions_JSType = 1 + // Use JavaScript numbers. + FieldOptions_JS_NUMBER FieldOptions_JSType = 2 +) + +var FieldOptions_JSType_name = map[int32]string{ + 0: "JS_NORMAL", + 1: "JS_STRING", + 2: "JS_NUMBER", +} + +var FieldOptions_JSType_value = map[string]int32{ + "JS_NORMAL": 0, + "JS_STRING": 1, + "JS_NUMBER": 2, +} + +func (x FieldOptions_JSType) Enum() *FieldOptions_JSType { + p := new(FieldOptions_JSType) + *p = x + return p +} + +func (x FieldOptions_JSType) String() string { + return proto.EnumName(FieldOptions_JSType_name, int32(x)) +} + +func (x *FieldOptions_JSType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldOptions_JSType_value, data, "FieldOptions_JSType") + if err != nil { + return err + } + *x = FieldOptions_JSType(value) + return nil +} + +func (FieldOptions_JSType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{12, 1} +} + +// Is this method side-effect-free (or safe in HTTP parlance), or idempotent, +// or neither? HTTP based RPC implementation may choose GET verb for safe +// methods, and PUT verb for idempotent methods instead of the default POST. +type MethodOptions_IdempotencyLevel int32 + +const ( + MethodOptions_IDEMPOTENCY_UNKNOWN MethodOptions_IdempotencyLevel = 0 + MethodOptions_NO_SIDE_EFFECTS MethodOptions_IdempotencyLevel = 1 + MethodOptions_IDEMPOTENT MethodOptions_IdempotencyLevel = 2 +) + +var MethodOptions_IdempotencyLevel_name = map[int32]string{ + 0: "IDEMPOTENCY_UNKNOWN", + 1: "NO_SIDE_EFFECTS", + 2: "IDEMPOTENT", +} + +var MethodOptions_IdempotencyLevel_value = map[string]int32{ + "IDEMPOTENCY_UNKNOWN": 0, + "NO_SIDE_EFFECTS": 1, + "IDEMPOTENT": 2, +} + +func (x MethodOptions_IdempotencyLevel) Enum() *MethodOptions_IdempotencyLevel { + p := new(MethodOptions_IdempotencyLevel) + *p = x + return p +} + +func (x MethodOptions_IdempotencyLevel) String() string { + return proto.EnumName(MethodOptions_IdempotencyLevel_name, int32(x)) +} + +func (x *MethodOptions_IdempotencyLevel) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MethodOptions_IdempotencyLevel_value, data, "MethodOptions_IdempotencyLevel") + if err != nil { + return err + } + *x = MethodOptions_IdempotencyLevel(value) + return nil +} + +func (MethodOptions_IdempotencyLevel) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{17, 0} +} + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +type FileDescriptorSet struct { + File []*FileDescriptorProto `protobuf:"bytes,1,rep,name=file" json:"file,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileDescriptorSet) Reset() { *m = FileDescriptorSet{} } +func (m *FileDescriptorSet) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorSet) ProtoMessage() {} +func (*FileDescriptorSet) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{0} +} + +func (m *FileDescriptorSet) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileDescriptorSet.Unmarshal(m, b) +} +func (m *FileDescriptorSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileDescriptorSet.Marshal(b, m, deterministic) +} +func (m *FileDescriptorSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileDescriptorSet.Merge(m, src) +} +func (m *FileDescriptorSet) XXX_Size() int { + return xxx_messageInfo_FileDescriptorSet.Size(m) +} +func (m *FileDescriptorSet) XXX_DiscardUnknown() { + xxx_messageInfo_FileDescriptorSet.DiscardUnknown(m) +} + +var xxx_messageInfo_FileDescriptorSet proto.InternalMessageInfo + +func (m *FileDescriptorSet) GetFile() []*FileDescriptorProto { + if m != nil { + return m.File + } + return nil +} + +// Describes a complete .proto file. +type FileDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Package *string `protobuf:"bytes,2,opt,name=package" json:"package,omitempty"` + // Names of files imported by this file. + Dependency []string `protobuf:"bytes,3,rep,name=dependency" json:"dependency,omitempty"` + // Indexes of the public imported files in the dependency list above. + PublicDependency []int32 `protobuf:"varint,10,rep,name=public_dependency,json=publicDependency" json:"public_dependency,omitempty"` + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency,json=weakDependency" json:"weak_dependency,omitempty"` + // All top-level definitions in this file. + MessageType []*DescriptorProto `protobuf:"bytes,4,rep,name=message_type,json=messageType" json:"message_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,5,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` + Service []*ServiceDescriptorProto `protobuf:"bytes,6,rep,name=service" json:"service,omitempty"` + Extension []*FieldDescriptorProto `protobuf:"bytes,7,rep,name=extension" json:"extension,omitempty"` + Options *FileOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info,json=sourceCodeInfo" json:"source_code_info,omitempty"` + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + Syntax *string `protobuf:"bytes,12,opt,name=syntax" json:"syntax,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileDescriptorProto) Reset() { *m = FileDescriptorProto{} } +func (m *FileDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorProto) ProtoMessage() {} +func (*FileDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{1} +} + +func (m *FileDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileDescriptorProto.Unmarshal(m, b) +} +func (m *FileDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileDescriptorProto.Marshal(b, m, deterministic) +} +func (m *FileDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileDescriptorProto.Merge(m, src) +} +func (m *FileDescriptorProto) XXX_Size() int { + return xxx_messageInfo_FileDescriptorProto.Size(m) +} +func (m *FileDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_FileDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_FileDescriptorProto proto.InternalMessageInfo + +func (m *FileDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FileDescriptorProto) GetPackage() string { + if m != nil && m.Package != nil { + return *m.Package + } + return "" +} + +func (m *FileDescriptorProto) GetDependency() []string { + if m != nil { + return m.Dependency + } + return nil +} + +func (m *FileDescriptorProto) GetPublicDependency() []int32 { + if m != nil { + return m.PublicDependency + } + return nil +} + +func (m *FileDescriptorProto) GetWeakDependency() []int32 { + if m != nil { + return m.WeakDependency + } + return nil +} + +func (m *FileDescriptorProto) GetMessageType() []*DescriptorProto { + if m != nil { + return m.MessageType + } + return nil +} + +func (m *FileDescriptorProto) GetEnumType() []*EnumDescriptorProto { + if m != nil { + return m.EnumType + } + return nil +} + +func (m *FileDescriptorProto) GetService() []*ServiceDescriptorProto { + if m != nil { + return m.Service + } + return nil +} + +func (m *FileDescriptorProto) GetExtension() []*FieldDescriptorProto { + if m != nil { + return m.Extension + } + return nil +} + +func (m *FileDescriptorProto) GetOptions() *FileOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *FileDescriptorProto) GetSourceCodeInfo() *SourceCodeInfo { + if m != nil { + return m.SourceCodeInfo + } + return nil +} + +func (m *FileDescriptorProto) GetSyntax() string { + if m != nil && m.Syntax != nil { + return *m.Syntax + } + return "" +} + +// Describes a message type. +type DescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Field []*FieldDescriptorProto `protobuf:"bytes,2,rep,name=field" json:"field,omitempty"` + Extension []*FieldDescriptorProto `protobuf:"bytes,6,rep,name=extension" json:"extension,omitempty"` + NestedType []*DescriptorProto `protobuf:"bytes,3,rep,name=nested_type,json=nestedType" json:"nested_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,4,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"` + ExtensionRange []*DescriptorProto_ExtensionRange `protobuf:"bytes,5,rep,name=extension_range,json=extensionRange" json:"extension_range,omitempty"` + OneofDecl []*OneofDescriptorProto `protobuf:"bytes,8,rep,name=oneof_decl,json=oneofDecl" json:"oneof_decl,omitempty"` + Options *MessageOptions `protobuf:"bytes,7,opt,name=options" json:"options,omitempty"` + ReservedRange []*DescriptorProto_ReservedRange `protobuf:"bytes,9,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto) Reset() { *m = DescriptorProto{} } +func (m *DescriptorProto) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto) ProtoMessage() {} +func (*DescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{2} +} + +func (m *DescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto.Unmarshal(m, b) +} +func (m *DescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto.Marshal(b, m, deterministic) +} +func (m *DescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto.Merge(m, src) +} +func (m *DescriptorProto) XXX_Size() int { + return xxx_messageInfo_DescriptorProto.Size(m) +} +func (m *DescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto proto.InternalMessageInfo + +func (m *DescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *DescriptorProto) GetField() []*FieldDescriptorProto { + if m != nil { + return m.Field + } + return nil +} + +func (m *DescriptorProto) GetExtension() []*FieldDescriptorProto { + if m != nil { + return m.Extension + } + return nil +} + +func (m *DescriptorProto) GetNestedType() []*DescriptorProto { + if m != nil { + return m.NestedType + } + return nil +} + +func (m *DescriptorProto) GetEnumType() []*EnumDescriptorProto { + if m != nil { + return m.EnumType + } + return nil +} + +func (m *DescriptorProto) GetExtensionRange() []*DescriptorProto_ExtensionRange { + if m != nil { + return m.ExtensionRange + } + return nil +} + +func (m *DescriptorProto) GetOneofDecl() []*OneofDescriptorProto { + if m != nil { + return m.OneofDecl + } + return nil +} + +func (m *DescriptorProto) GetOptions() *MessageOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *DescriptorProto) GetReservedRange() []*DescriptorProto_ReservedRange { + if m != nil { + return m.ReservedRange + } + return nil +} + +func (m *DescriptorProto) GetReservedName() []string { + if m != nil { + return m.ReservedName + } + return nil +} + +type DescriptorProto_ExtensionRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + Options *ExtensionRangeOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto_ExtensionRange) Reset() { *m = DescriptorProto_ExtensionRange{} } +func (m *DescriptorProto_ExtensionRange) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto_ExtensionRange) ProtoMessage() {} +func (*DescriptorProto_ExtensionRange) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{2, 0} +} + +func (m *DescriptorProto_ExtensionRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Unmarshal(m, b) +} +func (m *DescriptorProto_ExtensionRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Marshal(b, m, deterministic) +} +func (m *DescriptorProto_ExtensionRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto_ExtensionRange.Merge(m, src) +} +func (m *DescriptorProto_ExtensionRange) XXX_Size() int { + return xxx_messageInfo_DescriptorProto_ExtensionRange.Size(m) +} +func (m *DescriptorProto_ExtensionRange) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto_ExtensionRange.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto_ExtensionRange proto.InternalMessageInfo + +func (m *DescriptorProto_ExtensionRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *DescriptorProto_ExtensionRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +func (m *DescriptorProto_ExtensionRange) GetOptions() *ExtensionRangeOptions { + if m != nil { + return m.Options + } + return nil +} + +// Range of reserved tag numbers. Reserved tag numbers may not be used by +// fields or extension ranges in the same message. Reserved ranges may +// not overlap. +type DescriptorProto_ReservedRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DescriptorProto_ReservedRange) Reset() { *m = DescriptorProto_ReservedRange{} } +func (m *DescriptorProto_ReservedRange) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto_ReservedRange) ProtoMessage() {} +func (*DescriptorProto_ReservedRange) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{2, 1} +} + +func (m *DescriptorProto_ReservedRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DescriptorProto_ReservedRange.Unmarshal(m, b) +} +func (m *DescriptorProto_ReservedRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DescriptorProto_ReservedRange.Marshal(b, m, deterministic) +} +func (m *DescriptorProto_ReservedRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_DescriptorProto_ReservedRange.Merge(m, src) +} +func (m *DescriptorProto_ReservedRange) XXX_Size() int { + return xxx_messageInfo_DescriptorProto_ReservedRange.Size(m) +} +func (m *DescriptorProto_ReservedRange) XXX_DiscardUnknown() { + xxx_messageInfo_DescriptorProto_ReservedRange.DiscardUnknown(m) +} + +var xxx_messageInfo_DescriptorProto_ReservedRange proto.InternalMessageInfo + +func (m *DescriptorProto_ReservedRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *DescriptorProto_ReservedRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +type ExtensionRangeOptions struct { + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ExtensionRangeOptions) Reset() { *m = ExtensionRangeOptions{} } +func (m *ExtensionRangeOptions) String() string { return proto.CompactTextString(m) } +func (*ExtensionRangeOptions) ProtoMessage() {} +func (*ExtensionRangeOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{3} +} + +var extRange_ExtensionRangeOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*ExtensionRangeOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ExtensionRangeOptions +} + +func (m *ExtensionRangeOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ExtensionRangeOptions.Unmarshal(m, b) +} +func (m *ExtensionRangeOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ExtensionRangeOptions.Marshal(b, m, deterministic) +} +func (m *ExtensionRangeOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ExtensionRangeOptions.Merge(m, src) +} +func (m *ExtensionRangeOptions) XXX_Size() int { + return xxx_messageInfo_ExtensionRangeOptions.Size(m) +} +func (m *ExtensionRangeOptions) XXX_DiscardUnknown() { + xxx_messageInfo_ExtensionRangeOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_ExtensionRangeOptions proto.InternalMessageInfo + +func (m *ExtensionRangeOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +// Describes a field within a message. +type FieldDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,3,opt,name=number" json:"number,omitempty"` + Label *FieldDescriptorProto_Label `protobuf:"varint,4,opt,name=label,enum=google.protobuf.FieldDescriptorProto_Label" json:"label,omitempty"` + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + Type *FieldDescriptorProto_Type `protobuf:"varint,5,opt,name=type,enum=google.protobuf.FieldDescriptorProto_Type" json:"type,omitempty"` + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + TypeName *string `protobuf:"bytes,6,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + Extendee *string `protobuf:"bytes,2,opt,name=extendee" json:"extendee,omitempty"` + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + DefaultValue *string `protobuf:"bytes,7,opt,name=default_value,json=defaultValue" json:"default_value,omitempty"` + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + OneofIndex *int32 `protobuf:"varint,9,opt,name=oneof_index,json=oneofIndex" json:"oneof_index,omitempty"` + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + JsonName *string `protobuf:"bytes,10,opt,name=json_name,json=jsonName" json:"json_name,omitempty"` + Options *FieldOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FieldDescriptorProto) Reset() { *m = FieldDescriptorProto{} } +func (m *FieldDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FieldDescriptorProto) ProtoMessage() {} +func (*FieldDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{4} +} + +func (m *FieldDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FieldDescriptorProto.Unmarshal(m, b) +} +func (m *FieldDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FieldDescriptorProto.Marshal(b, m, deterministic) +} +func (m *FieldDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldDescriptorProto.Merge(m, src) +} +func (m *FieldDescriptorProto) XXX_Size() int { + return xxx_messageInfo_FieldDescriptorProto.Size(m) +} +func (m *FieldDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_FieldDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldDescriptorProto proto.InternalMessageInfo + +func (m *FieldDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FieldDescriptorProto) GetNumber() int32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *FieldDescriptorProto) GetLabel() FieldDescriptorProto_Label { + if m != nil && m.Label != nil { + return *m.Label + } + return FieldDescriptorProto_LABEL_OPTIONAL +} + +func (m *FieldDescriptorProto) GetType() FieldDescriptorProto_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return FieldDescriptorProto_TYPE_DOUBLE +} + +func (m *FieldDescriptorProto) GetTypeName() string { + if m != nil && m.TypeName != nil { + return *m.TypeName + } + return "" +} + +func (m *FieldDescriptorProto) GetExtendee() string { + if m != nil && m.Extendee != nil { + return *m.Extendee + } + return "" +} + +func (m *FieldDescriptorProto) GetDefaultValue() string { + if m != nil && m.DefaultValue != nil { + return *m.DefaultValue + } + return "" +} + +func (m *FieldDescriptorProto) GetOneofIndex() int32 { + if m != nil && m.OneofIndex != nil { + return *m.OneofIndex + } + return 0 +} + +func (m *FieldDescriptorProto) GetJsonName() string { + if m != nil && m.JsonName != nil { + return *m.JsonName + } + return "" +} + +func (m *FieldDescriptorProto) GetOptions() *FieldOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a oneof. +type OneofDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Options *OneofOptions `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OneofDescriptorProto) Reset() { *m = OneofDescriptorProto{} } +func (m *OneofDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*OneofDescriptorProto) ProtoMessage() {} +func (*OneofDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{5} +} + +func (m *OneofDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OneofDescriptorProto.Unmarshal(m, b) +} +func (m *OneofDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OneofDescriptorProto.Marshal(b, m, deterministic) +} +func (m *OneofDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_OneofDescriptorProto.Merge(m, src) +} +func (m *OneofDescriptorProto) XXX_Size() int { + return xxx_messageInfo_OneofDescriptorProto.Size(m) +} +func (m *OneofDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_OneofDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_OneofDescriptorProto proto.InternalMessageInfo + +func (m *OneofDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *OneofDescriptorProto) GetOptions() *OneofOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes an enum type. +type EnumDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Value []*EnumValueDescriptorProto `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` + Options *EnumOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + ReservedRange []*EnumDescriptorProto_EnumReservedRange `protobuf:"bytes,4,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"` + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + ReservedName []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumDescriptorProto) Reset() { *m = EnumDescriptorProto{} } +func (m *EnumDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumDescriptorProto) ProtoMessage() {} +func (*EnumDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{6} +} + +func (m *EnumDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumDescriptorProto.Unmarshal(m, b) +} +func (m *EnumDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumDescriptorProto.Marshal(b, m, deterministic) +} +func (m *EnumDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumDescriptorProto.Merge(m, src) +} +func (m *EnumDescriptorProto) XXX_Size() int { + return xxx_messageInfo_EnumDescriptorProto.Size(m) +} +func (m *EnumDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_EnumDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumDescriptorProto proto.InternalMessageInfo + +func (m *EnumDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EnumDescriptorProto) GetValue() []*EnumValueDescriptorProto { + if m != nil { + return m.Value + } + return nil +} + +func (m *EnumDescriptorProto) GetOptions() *EnumOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *EnumDescriptorProto) GetReservedRange() []*EnumDescriptorProto_EnumReservedRange { + if m != nil { + return m.ReservedRange + } + return nil +} + +func (m *EnumDescriptorProto) GetReservedName() []string { + if m != nil { + return m.ReservedName + } + return nil +} + +// Range of reserved numeric values. Reserved values may not be used by +// entries in the same enum. Reserved ranges may not overlap. +// +// Note that this is distinct from DescriptorProto.ReservedRange in that it +// is inclusive such that it can appropriately represent the entire int32 +// domain. +type EnumDescriptorProto_EnumReservedRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumDescriptorProto_EnumReservedRange) Reset() { *m = EnumDescriptorProto_EnumReservedRange{} } +func (m *EnumDescriptorProto_EnumReservedRange) String() string { return proto.CompactTextString(m) } +func (*EnumDescriptorProto_EnumReservedRange) ProtoMessage() {} +func (*EnumDescriptorProto_EnumReservedRange) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{6, 0} +} + +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Unmarshal(m, b) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Marshal(b, m, deterministic) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Merge(m, src) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_Size() int { + return xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.Size(m) +} +func (m *EnumDescriptorProto_EnumReservedRange) XXX_DiscardUnknown() { + xxx_messageInfo_EnumDescriptorProto_EnumReservedRange.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumDescriptorProto_EnumReservedRange proto.InternalMessageInfo + +func (m *EnumDescriptorProto_EnumReservedRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *EnumDescriptorProto_EnumReservedRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +// Describes a value within an enum. +type EnumValueDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,2,opt,name=number" json:"number,omitempty"` + Options *EnumValueOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumValueDescriptorProto) Reset() { *m = EnumValueDescriptorProto{} } +func (m *EnumValueDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumValueDescriptorProto) ProtoMessage() {} +func (*EnumValueDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{7} +} + +func (m *EnumValueDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumValueDescriptorProto.Unmarshal(m, b) +} +func (m *EnumValueDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumValueDescriptorProto.Marshal(b, m, deterministic) +} +func (m *EnumValueDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumValueDescriptorProto.Merge(m, src) +} +func (m *EnumValueDescriptorProto) XXX_Size() int { + return xxx_messageInfo_EnumValueDescriptorProto.Size(m) +} +func (m *EnumValueDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_EnumValueDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumValueDescriptorProto proto.InternalMessageInfo + +func (m *EnumValueDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EnumValueDescriptorProto) GetNumber() int32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *EnumValueDescriptorProto) GetOptions() *EnumValueOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a service. +type ServiceDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Method []*MethodDescriptorProto `protobuf:"bytes,2,rep,name=method" json:"method,omitempty"` + Options *ServiceOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceDescriptorProto) Reset() { *m = ServiceDescriptorProto{} } +func (m *ServiceDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*ServiceDescriptorProto) ProtoMessage() {} +func (*ServiceDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{8} +} + +func (m *ServiceDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceDescriptorProto.Unmarshal(m, b) +} +func (m *ServiceDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceDescriptorProto.Marshal(b, m, deterministic) +} +func (m *ServiceDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceDescriptorProto.Merge(m, src) +} +func (m *ServiceDescriptorProto) XXX_Size() int { + return xxx_messageInfo_ServiceDescriptorProto.Size(m) +} +func (m *ServiceDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceDescriptorProto proto.InternalMessageInfo + +func (m *ServiceDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *ServiceDescriptorProto) GetMethod() []*MethodDescriptorProto { + if m != nil { + return m.Method + } + return nil +} + +func (m *ServiceDescriptorProto) GetOptions() *ServiceOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a method of a service. +type MethodDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + InputType *string `protobuf:"bytes,2,opt,name=input_type,json=inputType" json:"input_type,omitempty"` + OutputType *string `protobuf:"bytes,3,opt,name=output_type,json=outputType" json:"output_type,omitempty"` + Options *MethodOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` + // Identifies if client streams multiple client messages + ClientStreaming *bool `protobuf:"varint,5,opt,name=client_streaming,json=clientStreaming,def=0" json:"client_streaming,omitempty"` + // Identifies if server streams multiple server messages + ServerStreaming *bool `protobuf:"varint,6,opt,name=server_streaming,json=serverStreaming,def=0" json:"server_streaming,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodDescriptorProto) Reset() { *m = MethodDescriptorProto{} } +func (m *MethodDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*MethodDescriptorProto) ProtoMessage() {} +func (*MethodDescriptorProto) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{9} +} + +func (m *MethodDescriptorProto) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodDescriptorProto.Unmarshal(m, b) +} +func (m *MethodDescriptorProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodDescriptorProto.Marshal(b, m, deterministic) +} +func (m *MethodDescriptorProto) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodDescriptorProto.Merge(m, src) +} +func (m *MethodDescriptorProto) XXX_Size() int { + return xxx_messageInfo_MethodDescriptorProto.Size(m) +} +func (m *MethodDescriptorProto) XXX_DiscardUnknown() { + xxx_messageInfo_MethodDescriptorProto.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodDescriptorProto proto.InternalMessageInfo + +const Default_MethodDescriptorProto_ClientStreaming bool = false +const Default_MethodDescriptorProto_ServerStreaming bool = false + +func (m *MethodDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MethodDescriptorProto) GetInputType() string { + if m != nil && m.InputType != nil { + return *m.InputType + } + return "" +} + +func (m *MethodDescriptorProto) GetOutputType() string { + if m != nil && m.OutputType != nil { + return *m.OutputType + } + return "" +} + +func (m *MethodDescriptorProto) GetOptions() *MethodOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *MethodDescriptorProto) GetClientStreaming() bool { + if m != nil && m.ClientStreaming != nil { + return *m.ClientStreaming + } + return Default_MethodDescriptorProto_ClientStreaming +} + +func (m *MethodDescriptorProto) GetServerStreaming() bool { + if m != nil && m.ServerStreaming != nil { + return *m.ServerStreaming + } + return Default_MethodDescriptorProto_ServerStreaming +} + +type FileOptions struct { + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + JavaPackage *string `protobuf:"bytes,1,opt,name=java_package,json=javaPackage" json:"java_package,omitempty"` + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + JavaOuterClassname *string `protobuf:"bytes,8,opt,name=java_outer_classname,json=javaOuterClassname" json:"java_outer_classname,omitempty"` + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,json=javaMultipleFiles,def=0" json:"java_multiple_files,omitempty"` + // This option does nothing. + JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,json=javaGenerateEqualsAndHash" json:"java_generate_equals_and_hash,omitempty"` // Deprecated: Do not use. + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + JavaStringCheckUtf8 *bool `protobuf:"varint,27,opt,name=java_string_check_utf8,json=javaStringCheckUtf8,def=0" json:"java_string_check_utf8,omitempty"` + OptimizeFor *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,json=optimizeFor,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"` + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + GoPackage *string `protobuf:"bytes,11,opt,name=go_package,json=goPackage" json:"go_package,omitempty"` + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + CcGenericServices *bool `protobuf:"varint,16,opt,name=cc_generic_services,json=ccGenericServices,def=0" json:"cc_generic_services,omitempty"` + JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,json=javaGenericServices,def=0" json:"java_generic_services,omitempty"` + PyGenericServices *bool `protobuf:"varint,18,opt,name=py_generic_services,json=pyGenericServices,def=0" json:"py_generic_services,omitempty"` + PhpGenericServices *bool `protobuf:"varint,42,opt,name=php_generic_services,json=phpGenericServices,def=0" json:"php_generic_services,omitempty"` + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + Deprecated *bool `protobuf:"varint,23,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + CcEnableArenas *bool `protobuf:"varint,31,opt,name=cc_enable_arenas,json=ccEnableArenas,def=0" json:"cc_enable_arenas,omitempty"` + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + ObjcClassPrefix *string `protobuf:"bytes,36,opt,name=objc_class_prefix,json=objcClassPrefix" json:"objc_class_prefix,omitempty"` + // Namespace for generated classes; defaults to the package. + CsharpNamespace *string `protobuf:"bytes,37,opt,name=csharp_namespace,json=csharpNamespace" json:"csharp_namespace,omitempty"` + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + SwiftPrefix *string `protobuf:"bytes,39,opt,name=swift_prefix,json=swiftPrefix" json:"swift_prefix,omitempty"` + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + PhpClassPrefix *string `protobuf:"bytes,40,opt,name=php_class_prefix,json=phpClassPrefix" json:"php_class_prefix,omitempty"` + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + PhpNamespace *string `protobuf:"bytes,41,opt,name=php_namespace,json=phpNamespace" json:"php_namespace,omitempty"` + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be used + // for determining the namespace. + PhpMetadataNamespace *string `protobuf:"bytes,44,opt,name=php_metadata_namespace,json=phpMetadataNamespace" json:"php_metadata_namespace,omitempty"` + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + RubyPackage *string `protobuf:"bytes,45,opt,name=ruby_package,json=rubyPackage" json:"ruby_package,omitempty"` + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FileOptions) Reset() { *m = FileOptions{} } +func (m *FileOptions) String() string { return proto.CompactTextString(m) } +func (*FileOptions) ProtoMessage() {} +func (*FileOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{10} +} + +var extRange_FileOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*FileOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_FileOptions +} + +func (m *FileOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FileOptions.Unmarshal(m, b) +} +func (m *FileOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FileOptions.Marshal(b, m, deterministic) +} +func (m *FileOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_FileOptions.Merge(m, src) +} +func (m *FileOptions) XXX_Size() int { + return xxx_messageInfo_FileOptions.Size(m) +} +func (m *FileOptions) XXX_DiscardUnknown() { + xxx_messageInfo_FileOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_FileOptions proto.InternalMessageInfo + +const Default_FileOptions_JavaMultipleFiles bool = false +const Default_FileOptions_JavaStringCheckUtf8 bool = false +const Default_FileOptions_OptimizeFor FileOptions_OptimizeMode = FileOptions_SPEED +const Default_FileOptions_CcGenericServices bool = false +const Default_FileOptions_JavaGenericServices bool = false +const Default_FileOptions_PyGenericServices bool = false +const Default_FileOptions_PhpGenericServices bool = false +const Default_FileOptions_Deprecated bool = false +const Default_FileOptions_CcEnableArenas bool = false + +func (m *FileOptions) GetJavaPackage() string { + if m != nil && m.JavaPackage != nil { + return *m.JavaPackage + } + return "" +} + +func (m *FileOptions) GetJavaOuterClassname() string { + if m != nil && m.JavaOuterClassname != nil { + return *m.JavaOuterClassname + } + return "" +} + +func (m *FileOptions) GetJavaMultipleFiles() bool { + if m != nil && m.JavaMultipleFiles != nil { + return *m.JavaMultipleFiles + } + return Default_FileOptions_JavaMultipleFiles +} + +// Deprecated: Do not use. +func (m *FileOptions) GetJavaGenerateEqualsAndHash() bool { + if m != nil && m.JavaGenerateEqualsAndHash != nil { + return *m.JavaGenerateEqualsAndHash + } + return false +} + +func (m *FileOptions) GetJavaStringCheckUtf8() bool { + if m != nil && m.JavaStringCheckUtf8 != nil { + return *m.JavaStringCheckUtf8 + } + return Default_FileOptions_JavaStringCheckUtf8 +} + +func (m *FileOptions) GetOptimizeFor() FileOptions_OptimizeMode { + if m != nil && m.OptimizeFor != nil { + return *m.OptimizeFor + } + return Default_FileOptions_OptimizeFor +} + +func (m *FileOptions) GetGoPackage() string { + if m != nil && m.GoPackage != nil { + return *m.GoPackage + } + return "" +} + +func (m *FileOptions) GetCcGenericServices() bool { + if m != nil && m.CcGenericServices != nil { + return *m.CcGenericServices + } + return Default_FileOptions_CcGenericServices +} + +func (m *FileOptions) GetJavaGenericServices() bool { + if m != nil && m.JavaGenericServices != nil { + return *m.JavaGenericServices + } + return Default_FileOptions_JavaGenericServices +} + +func (m *FileOptions) GetPyGenericServices() bool { + if m != nil && m.PyGenericServices != nil { + return *m.PyGenericServices + } + return Default_FileOptions_PyGenericServices +} + +func (m *FileOptions) GetPhpGenericServices() bool { + if m != nil && m.PhpGenericServices != nil { + return *m.PhpGenericServices + } + return Default_FileOptions_PhpGenericServices +} + +func (m *FileOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FileOptions_Deprecated +} + +func (m *FileOptions) GetCcEnableArenas() bool { + if m != nil && m.CcEnableArenas != nil { + return *m.CcEnableArenas + } + return Default_FileOptions_CcEnableArenas +} + +func (m *FileOptions) GetObjcClassPrefix() string { + if m != nil && m.ObjcClassPrefix != nil { + return *m.ObjcClassPrefix + } + return "" +} + +func (m *FileOptions) GetCsharpNamespace() string { + if m != nil && m.CsharpNamespace != nil { + return *m.CsharpNamespace + } + return "" +} + +func (m *FileOptions) GetSwiftPrefix() string { + if m != nil && m.SwiftPrefix != nil { + return *m.SwiftPrefix + } + return "" +} + +func (m *FileOptions) GetPhpClassPrefix() string { + if m != nil && m.PhpClassPrefix != nil { + return *m.PhpClassPrefix + } + return "" +} + +func (m *FileOptions) GetPhpNamespace() string { + if m != nil && m.PhpNamespace != nil { + return *m.PhpNamespace + } + return "" +} + +func (m *FileOptions) GetPhpMetadataNamespace() string { + if m != nil && m.PhpMetadataNamespace != nil { + return *m.PhpMetadataNamespace + } + return "" +} + +func (m *FileOptions) GetRubyPackage() string { + if m != nil && m.RubyPackage != nil { + return *m.RubyPackage + } + return "" +} + +func (m *FileOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type MessageOptions struct { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + MessageSetWireFormat *bool `protobuf:"varint,1,opt,name=message_set_wire_format,json=messageSetWireFormat,def=0" json:"message_set_wire_format,omitempty"` + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + NoStandardDescriptorAccessor *bool `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,json=noStandardDescriptorAccessor,def=0" json:"no_standard_descriptor_accessor,omitempty"` + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + MapEntry *bool `protobuf:"varint,7,opt,name=map_entry,json=mapEntry" json:"map_entry,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MessageOptions) Reset() { *m = MessageOptions{} } +func (m *MessageOptions) String() string { return proto.CompactTextString(m) } +func (*MessageOptions) ProtoMessage() {} +func (*MessageOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{11} +} + +var extRange_MessageOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*MessageOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MessageOptions +} + +func (m *MessageOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MessageOptions.Unmarshal(m, b) +} +func (m *MessageOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MessageOptions.Marshal(b, m, deterministic) +} +func (m *MessageOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageOptions.Merge(m, src) +} +func (m *MessageOptions) XXX_Size() int { + return xxx_messageInfo_MessageOptions.Size(m) +} +func (m *MessageOptions) XXX_DiscardUnknown() { + xxx_messageInfo_MessageOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_MessageOptions proto.InternalMessageInfo + +const Default_MessageOptions_MessageSetWireFormat bool = false +const Default_MessageOptions_NoStandardDescriptorAccessor bool = false +const Default_MessageOptions_Deprecated bool = false + +func (m *MessageOptions) GetMessageSetWireFormat() bool { + if m != nil && m.MessageSetWireFormat != nil { + return *m.MessageSetWireFormat + } + return Default_MessageOptions_MessageSetWireFormat +} + +func (m *MessageOptions) GetNoStandardDescriptorAccessor() bool { + if m != nil && m.NoStandardDescriptorAccessor != nil { + return *m.NoStandardDescriptorAccessor + } + return Default_MessageOptions_NoStandardDescriptorAccessor +} + +func (m *MessageOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MessageOptions_Deprecated +} + +func (m *MessageOptions) GetMapEntry() bool { + if m != nil && m.MapEntry != nil { + return *m.MapEntry + } + return false +} + +func (m *MessageOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type FieldOptions struct { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + Ctype *FieldOptions_CType `protobuf:"varint,1,opt,name=ctype,enum=google.protobuf.FieldOptions_CType,def=0" json:"ctype,omitempty"` + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + Packed *bool `protobuf:"varint,2,opt,name=packed" json:"packed,omitempty"` + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + Jstype *FieldOptions_JSType `protobuf:"varint,6,opt,name=jstype,enum=google.protobuf.FieldOptions_JSType,def=0" json:"jstype,omitempty"` + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + Lazy *bool `protobuf:"varint,5,opt,name=lazy,def=0" json:"lazy,omitempty"` + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // For Google-internal migration only. Do not use. + Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FieldOptions) Reset() { *m = FieldOptions{} } +func (m *FieldOptions) String() string { return proto.CompactTextString(m) } +func (*FieldOptions) ProtoMessage() {} +func (*FieldOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{12} +} + +var extRange_FieldOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*FieldOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_FieldOptions +} + +func (m *FieldOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FieldOptions.Unmarshal(m, b) +} +func (m *FieldOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FieldOptions.Marshal(b, m, deterministic) +} +func (m *FieldOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldOptions.Merge(m, src) +} +func (m *FieldOptions) XXX_Size() int { + return xxx_messageInfo_FieldOptions.Size(m) +} +func (m *FieldOptions) XXX_DiscardUnknown() { + xxx_messageInfo_FieldOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldOptions proto.InternalMessageInfo + +const Default_FieldOptions_Ctype FieldOptions_CType = FieldOptions_STRING +const Default_FieldOptions_Jstype FieldOptions_JSType = FieldOptions_JS_NORMAL +const Default_FieldOptions_Lazy bool = false +const Default_FieldOptions_Deprecated bool = false +const Default_FieldOptions_Weak bool = false + +func (m *FieldOptions) GetCtype() FieldOptions_CType { + if m != nil && m.Ctype != nil { + return *m.Ctype + } + return Default_FieldOptions_Ctype +} + +func (m *FieldOptions) GetPacked() bool { + if m != nil && m.Packed != nil { + return *m.Packed + } + return false +} + +func (m *FieldOptions) GetJstype() FieldOptions_JSType { + if m != nil && m.Jstype != nil { + return *m.Jstype + } + return Default_FieldOptions_Jstype +} + +func (m *FieldOptions) GetLazy() bool { + if m != nil && m.Lazy != nil { + return *m.Lazy + } + return Default_FieldOptions_Lazy +} + +func (m *FieldOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FieldOptions_Deprecated +} + +func (m *FieldOptions) GetWeak() bool { + if m != nil && m.Weak != nil { + return *m.Weak + } + return Default_FieldOptions_Weak +} + +func (m *FieldOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type OneofOptions struct { + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OneofOptions) Reset() { *m = OneofOptions{} } +func (m *OneofOptions) String() string { return proto.CompactTextString(m) } +func (*OneofOptions) ProtoMessage() {} +func (*OneofOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{13} +} + +var extRange_OneofOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*OneofOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OneofOptions +} + +func (m *OneofOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OneofOptions.Unmarshal(m, b) +} +func (m *OneofOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OneofOptions.Marshal(b, m, deterministic) +} +func (m *OneofOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_OneofOptions.Merge(m, src) +} +func (m *OneofOptions) XXX_Size() int { + return xxx_messageInfo_OneofOptions.Size(m) +} +func (m *OneofOptions) XXX_DiscardUnknown() { + xxx_messageInfo_OneofOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_OneofOptions proto.InternalMessageInfo + +func (m *OneofOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type EnumOptions struct { + // Set this option to true to allow mapping different tag names to the same + // value. + AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias,json=allowAlias" json:"allow_alias,omitempty"` + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumOptions) Reset() { *m = EnumOptions{} } +func (m *EnumOptions) String() string { return proto.CompactTextString(m) } +func (*EnumOptions) ProtoMessage() {} +func (*EnumOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{14} +} + +var extRange_EnumOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*EnumOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_EnumOptions +} + +func (m *EnumOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumOptions.Unmarshal(m, b) +} +func (m *EnumOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumOptions.Marshal(b, m, deterministic) +} +func (m *EnumOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumOptions.Merge(m, src) +} +func (m *EnumOptions) XXX_Size() int { + return xxx_messageInfo_EnumOptions.Size(m) +} +func (m *EnumOptions) XXX_DiscardUnknown() { + xxx_messageInfo_EnumOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumOptions proto.InternalMessageInfo + +const Default_EnumOptions_Deprecated bool = false + +func (m *EnumOptions) GetAllowAlias() bool { + if m != nil && m.AllowAlias != nil { + return *m.AllowAlias + } + return false +} + +func (m *EnumOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumOptions_Deprecated +} + +func (m *EnumOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type EnumValueOptions struct { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + Deprecated *bool `protobuf:"varint,1,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *EnumValueOptions) Reset() { *m = EnumValueOptions{} } +func (m *EnumValueOptions) String() string { return proto.CompactTextString(m) } +func (*EnumValueOptions) ProtoMessage() {} +func (*EnumValueOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{15} +} + +var extRange_EnumValueOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*EnumValueOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_EnumValueOptions +} + +func (m *EnumValueOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_EnumValueOptions.Unmarshal(m, b) +} +func (m *EnumValueOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_EnumValueOptions.Marshal(b, m, deterministic) +} +func (m *EnumValueOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_EnumValueOptions.Merge(m, src) +} +func (m *EnumValueOptions) XXX_Size() int { + return xxx_messageInfo_EnumValueOptions.Size(m) +} +func (m *EnumValueOptions) XXX_DiscardUnknown() { + xxx_messageInfo_EnumValueOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_EnumValueOptions proto.InternalMessageInfo + +const Default_EnumValueOptions_Deprecated bool = false + +func (m *EnumValueOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumValueOptions_Deprecated +} + +func (m *EnumValueOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type ServiceOptions struct { + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceOptions) Reset() { *m = ServiceOptions{} } +func (m *ServiceOptions) String() string { return proto.CompactTextString(m) } +func (*ServiceOptions) ProtoMessage() {} +func (*ServiceOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{16} +} + +var extRange_ServiceOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*ServiceOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ServiceOptions +} + +func (m *ServiceOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceOptions.Unmarshal(m, b) +} +func (m *ServiceOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceOptions.Marshal(b, m, deterministic) +} +func (m *ServiceOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceOptions.Merge(m, src) +} +func (m *ServiceOptions) XXX_Size() int { + return xxx_messageInfo_ServiceOptions.Size(m) +} +func (m *ServiceOptions) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceOptions proto.InternalMessageInfo + +const Default_ServiceOptions_Deprecated bool = false + +func (m *ServiceOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_ServiceOptions_Deprecated +} + +func (m *ServiceOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type MethodOptions struct { + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + IdempotencyLevel *MethodOptions_IdempotencyLevel `protobuf:"varint,34,opt,name=idempotency_level,json=idempotencyLevel,enum=google.protobuf.MethodOptions_IdempotencyLevel,def=0" json:"idempotency_level,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option,json=uninterpretedOption" json:"uninterpreted_option,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodOptions) Reset() { *m = MethodOptions{} } +func (m *MethodOptions) String() string { return proto.CompactTextString(m) } +func (*MethodOptions) ProtoMessage() {} +func (*MethodOptions) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{17} +} + +var extRange_MethodOptions = []proto.ExtensionRange{ + {Start: 1000, End: 536870911}, +} + +func (*MethodOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MethodOptions +} + +func (m *MethodOptions) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodOptions.Unmarshal(m, b) +} +func (m *MethodOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodOptions.Marshal(b, m, deterministic) +} +func (m *MethodOptions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodOptions.Merge(m, src) +} +func (m *MethodOptions) XXX_Size() int { + return xxx_messageInfo_MethodOptions.Size(m) +} +func (m *MethodOptions) XXX_DiscardUnknown() { + xxx_messageInfo_MethodOptions.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodOptions proto.InternalMessageInfo + +const Default_MethodOptions_Deprecated bool = false +const Default_MethodOptions_IdempotencyLevel MethodOptions_IdempotencyLevel = MethodOptions_IDEMPOTENCY_UNKNOWN + +func (m *MethodOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MethodOptions_Deprecated +} + +func (m *MethodOptions) GetIdempotencyLevel() MethodOptions_IdempotencyLevel { + if m != nil && m.IdempotencyLevel != nil { + return *m.IdempotencyLevel + } + return Default_MethodOptions_IdempotencyLevel +} + +func (m *MethodOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +type UninterpretedOption struct { + Name []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"` + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + IdentifierValue *string `protobuf:"bytes,3,opt,name=identifier_value,json=identifierValue" json:"identifier_value,omitempty"` + PositiveIntValue *uint64 `protobuf:"varint,4,opt,name=positive_int_value,json=positiveIntValue" json:"positive_int_value,omitempty"` + NegativeIntValue *int64 `protobuf:"varint,5,opt,name=negative_int_value,json=negativeIntValue" json:"negative_int_value,omitempty"` + DoubleValue *float64 `protobuf:"fixed64,6,opt,name=double_value,json=doubleValue" json:"double_value,omitempty"` + StringValue []byte `protobuf:"bytes,7,opt,name=string_value,json=stringValue" json:"string_value,omitempty"` + AggregateValue *string `protobuf:"bytes,8,opt,name=aggregate_value,json=aggregateValue" json:"aggregate_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UninterpretedOption) Reset() { *m = UninterpretedOption{} } +func (m *UninterpretedOption) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption) ProtoMessage() {} +func (*UninterpretedOption) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{18} +} + +func (m *UninterpretedOption) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UninterpretedOption.Unmarshal(m, b) +} +func (m *UninterpretedOption) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UninterpretedOption.Marshal(b, m, deterministic) +} +func (m *UninterpretedOption) XXX_Merge(src proto.Message) { + xxx_messageInfo_UninterpretedOption.Merge(m, src) +} +func (m *UninterpretedOption) XXX_Size() int { + return xxx_messageInfo_UninterpretedOption.Size(m) +} +func (m *UninterpretedOption) XXX_DiscardUnknown() { + xxx_messageInfo_UninterpretedOption.DiscardUnknown(m) +} + +var xxx_messageInfo_UninterpretedOption proto.InternalMessageInfo + +func (m *UninterpretedOption) GetName() []*UninterpretedOption_NamePart { + if m != nil { + return m.Name + } + return nil +} + +func (m *UninterpretedOption) GetIdentifierValue() string { + if m != nil && m.IdentifierValue != nil { + return *m.IdentifierValue + } + return "" +} + +func (m *UninterpretedOption) GetPositiveIntValue() uint64 { + if m != nil && m.PositiveIntValue != nil { + return *m.PositiveIntValue + } + return 0 +} + +func (m *UninterpretedOption) GetNegativeIntValue() int64 { + if m != nil && m.NegativeIntValue != nil { + return *m.NegativeIntValue + } + return 0 +} + +func (m *UninterpretedOption) GetDoubleValue() float64 { + if m != nil && m.DoubleValue != nil { + return *m.DoubleValue + } + return 0 +} + +func (m *UninterpretedOption) GetStringValue() []byte { + if m != nil { + return m.StringValue + } + return nil +} + +func (m *UninterpretedOption) GetAggregateValue() string { + if m != nil && m.AggregateValue != nil { + return *m.AggregateValue + } + return "" +} + +// The name of the uninterpreted option. Each string represents a segment in +// a dot-separated name. is_extension is true iff a segment represents an +// extension (denoted with parentheses in options specs in .proto files). +// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents +// "foo.(bar.baz).qux". +type UninterpretedOption_NamePart struct { + NamePart *string `protobuf:"bytes,1,req,name=name_part,json=namePart" json:"name_part,omitempty"` + IsExtension *bool `protobuf:"varint,2,req,name=is_extension,json=isExtension" json:"is_extension,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UninterpretedOption_NamePart) Reset() { *m = UninterpretedOption_NamePart{} } +func (m *UninterpretedOption_NamePart) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption_NamePart) ProtoMessage() {} +func (*UninterpretedOption_NamePart) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{18, 0} +} + +func (m *UninterpretedOption_NamePart) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UninterpretedOption_NamePart.Unmarshal(m, b) +} +func (m *UninterpretedOption_NamePart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UninterpretedOption_NamePart.Marshal(b, m, deterministic) +} +func (m *UninterpretedOption_NamePart) XXX_Merge(src proto.Message) { + xxx_messageInfo_UninterpretedOption_NamePart.Merge(m, src) +} +func (m *UninterpretedOption_NamePart) XXX_Size() int { + return xxx_messageInfo_UninterpretedOption_NamePart.Size(m) +} +func (m *UninterpretedOption_NamePart) XXX_DiscardUnknown() { + xxx_messageInfo_UninterpretedOption_NamePart.DiscardUnknown(m) +} + +var xxx_messageInfo_UninterpretedOption_NamePart proto.InternalMessageInfo + +func (m *UninterpretedOption_NamePart) GetNamePart() string { + if m != nil && m.NamePart != nil { + return *m.NamePart + } + return "" +} + +func (m *UninterpretedOption_NamePart) GetIsExtension() bool { + if m != nil && m.IsExtension != nil { + return *m.IsExtension + } + return false +} + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +type SourceCodeInfo struct { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + Location []*SourceCodeInfo_Location `protobuf:"bytes,1,rep,name=location" json:"location,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SourceCodeInfo) Reset() { *m = SourceCodeInfo{} } +func (m *SourceCodeInfo) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo) ProtoMessage() {} +func (*SourceCodeInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{19} +} + +func (m *SourceCodeInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SourceCodeInfo.Unmarshal(m, b) +} +func (m *SourceCodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SourceCodeInfo.Marshal(b, m, deterministic) +} +func (m *SourceCodeInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceCodeInfo.Merge(m, src) +} +func (m *SourceCodeInfo) XXX_Size() int { + return xxx_messageInfo_SourceCodeInfo.Size(m) +} +func (m *SourceCodeInfo) XXX_DiscardUnknown() { + xxx_messageInfo_SourceCodeInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceCodeInfo proto.InternalMessageInfo + +func (m *SourceCodeInfo) GetLocation() []*SourceCodeInfo_Location { + if m != nil { + return m.Location + } + return nil +} + +type SourceCodeInfo_Location struct { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + Span []int32 `protobuf:"varint,2,rep,packed,name=span" json:"span,omitempty"` + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + LeadingComments *string `protobuf:"bytes,3,opt,name=leading_comments,json=leadingComments" json:"leading_comments,omitempty"` + TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments,json=trailingComments" json:"trailing_comments,omitempty"` + LeadingDetachedComments []string `protobuf:"bytes,6,rep,name=leading_detached_comments,json=leadingDetachedComments" json:"leading_detached_comments,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SourceCodeInfo_Location) Reset() { *m = SourceCodeInfo_Location{} } +func (m *SourceCodeInfo_Location) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo_Location) ProtoMessage() {} +func (*SourceCodeInfo_Location) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{19, 0} +} + +func (m *SourceCodeInfo_Location) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SourceCodeInfo_Location.Unmarshal(m, b) +} +func (m *SourceCodeInfo_Location) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SourceCodeInfo_Location.Marshal(b, m, deterministic) +} +func (m *SourceCodeInfo_Location) XXX_Merge(src proto.Message) { + xxx_messageInfo_SourceCodeInfo_Location.Merge(m, src) +} +func (m *SourceCodeInfo_Location) XXX_Size() int { + return xxx_messageInfo_SourceCodeInfo_Location.Size(m) +} +func (m *SourceCodeInfo_Location) XXX_DiscardUnknown() { + xxx_messageInfo_SourceCodeInfo_Location.DiscardUnknown(m) +} + +var xxx_messageInfo_SourceCodeInfo_Location proto.InternalMessageInfo + +func (m *SourceCodeInfo_Location) GetPath() []int32 { + if m != nil { + return m.Path + } + return nil +} + +func (m *SourceCodeInfo_Location) GetSpan() []int32 { + if m != nil { + return m.Span + } + return nil +} + +func (m *SourceCodeInfo_Location) GetLeadingComments() string { + if m != nil && m.LeadingComments != nil { + return *m.LeadingComments + } + return "" +} + +func (m *SourceCodeInfo_Location) GetTrailingComments() string { + if m != nil && m.TrailingComments != nil { + return *m.TrailingComments + } + return "" +} + +func (m *SourceCodeInfo_Location) GetLeadingDetachedComments() []string { + if m != nil { + return m.LeadingDetachedComments + } + return nil +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +type GeneratedCodeInfo struct { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + Annotation []*GeneratedCodeInfo_Annotation `protobuf:"bytes,1,rep,name=annotation" json:"annotation,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GeneratedCodeInfo) Reset() { *m = GeneratedCodeInfo{} } +func (m *GeneratedCodeInfo) String() string { return proto.CompactTextString(m) } +func (*GeneratedCodeInfo) ProtoMessage() {} +func (*GeneratedCodeInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{20} +} + +func (m *GeneratedCodeInfo) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GeneratedCodeInfo.Unmarshal(m, b) +} +func (m *GeneratedCodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GeneratedCodeInfo.Marshal(b, m, deterministic) +} +func (m *GeneratedCodeInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_GeneratedCodeInfo.Merge(m, src) +} +func (m *GeneratedCodeInfo) XXX_Size() int { + return xxx_messageInfo_GeneratedCodeInfo.Size(m) +} +func (m *GeneratedCodeInfo) XXX_DiscardUnknown() { + xxx_messageInfo_GeneratedCodeInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_GeneratedCodeInfo proto.InternalMessageInfo + +func (m *GeneratedCodeInfo) GetAnnotation() []*GeneratedCodeInfo_Annotation { + if m != nil { + return m.Annotation + } + return nil +} + +type GeneratedCodeInfo_Annotation struct { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` + // Identifies the filesystem path to the original source .proto. + SourceFile *string `protobuf:"bytes,2,opt,name=source_file,json=sourceFile" json:"source_file,omitempty"` + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + Begin *int32 `protobuf:"varint,3,opt,name=begin" json:"begin,omitempty"` + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + End *int32 `protobuf:"varint,4,opt,name=end" json:"end,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GeneratedCodeInfo_Annotation) Reset() { *m = GeneratedCodeInfo_Annotation{} } +func (m *GeneratedCodeInfo_Annotation) String() string { return proto.CompactTextString(m) } +func (*GeneratedCodeInfo_Annotation) ProtoMessage() {} +func (*GeneratedCodeInfo_Annotation) Descriptor() ([]byte, []int) { + return fileDescriptor_e5baabe45344a177, []int{20, 0} +} + +func (m *GeneratedCodeInfo_Annotation) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Unmarshal(m, b) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Marshal(b, m, deterministic) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Merge(src proto.Message) { + xxx_messageInfo_GeneratedCodeInfo_Annotation.Merge(m, src) +} +func (m *GeneratedCodeInfo_Annotation) XXX_Size() int { + return xxx_messageInfo_GeneratedCodeInfo_Annotation.Size(m) +} +func (m *GeneratedCodeInfo_Annotation) XXX_DiscardUnknown() { + xxx_messageInfo_GeneratedCodeInfo_Annotation.DiscardUnknown(m) +} + +var xxx_messageInfo_GeneratedCodeInfo_Annotation proto.InternalMessageInfo + +func (m *GeneratedCodeInfo_Annotation) GetPath() []int32 { + if m != nil { + return m.Path + } + return nil +} + +func (m *GeneratedCodeInfo_Annotation) GetSourceFile() string { + if m != nil && m.SourceFile != nil { + return *m.SourceFile + } + return "" +} + +func (m *GeneratedCodeInfo_Annotation) GetBegin() int32 { + if m != nil && m.Begin != nil { + return *m.Begin + } + return 0 +} + +func (m *GeneratedCodeInfo_Annotation) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +func init() { + proto.RegisterEnum("google.protobuf.FieldDescriptorProto_Type", FieldDescriptorProto_Type_name, FieldDescriptorProto_Type_value) + proto.RegisterEnum("google.protobuf.FieldDescriptorProto_Label", FieldDescriptorProto_Label_name, FieldDescriptorProto_Label_value) + proto.RegisterEnum("google.protobuf.FileOptions_OptimizeMode", FileOptions_OptimizeMode_name, FileOptions_OptimizeMode_value) + proto.RegisterEnum("google.protobuf.FieldOptions_CType", FieldOptions_CType_name, FieldOptions_CType_value) + proto.RegisterEnum("google.protobuf.FieldOptions_JSType", FieldOptions_JSType_name, FieldOptions_JSType_value) + proto.RegisterEnum("google.protobuf.MethodOptions_IdempotencyLevel", MethodOptions_IdempotencyLevel_name, MethodOptions_IdempotencyLevel_value) + proto.RegisterType((*FileDescriptorSet)(nil), "google.protobuf.FileDescriptorSet") + proto.RegisterType((*FileDescriptorProto)(nil), "google.protobuf.FileDescriptorProto") + proto.RegisterType((*DescriptorProto)(nil), "google.protobuf.DescriptorProto") + proto.RegisterType((*DescriptorProto_ExtensionRange)(nil), "google.protobuf.DescriptorProto.ExtensionRange") + proto.RegisterType((*DescriptorProto_ReservedRange)(nil), "google.protobuf.DescriptorProto.ReservedRange") + proto.RegisterType((*ExtensionRangeOptions)(nil), "google.protobuf.ExtensionRangeOptions") + proto.RegisterType((*FieldDescriptorProto)(nil), "google.protobuf.FieldDescriptorProto") + proto.RegisterType((*OneofDescriptorProto)(nil), "google.protobuf.OneofDescriptorProto") + proto.RegisterType((*EnumDescriptorProto)(nil), "google.protobuf.EnumDescriptorProto") + proto.RegisterType((*EnumDescriptorProto_EnumReservedRange)(nil), "google.protobuf.EnumDescriptorProto.EnumReservedRange") + proto.RegisterType((*EnumValueDescriptorProto)(nil), "google.protobuf.EnumValueDescriptorProto") + proto.RegisterType((*ServiceDescriptorProto)(nil), "google.protobuf.ServiceDescriptorProto") + proto.RegisterType((*MethodDescriptorProto)(nil), "google.protobuf.MethodDescriptorProto") + proto.RegisterType((*FileOptions)(nil), "google.protobuf.FileOptions") + proto.RegisterType((*MessageOptions)(nil), "google.protobuf.MessageOptions") + proto.RegisterType((*FieldOptions)(nil), "google.protobuf.FieldOptions") + proto.RegisterType((*OneofOptions)(nil), "google.protobuf.OneofOptions") + proto.RegisterType((*EnumOptions)(nil), "google.protobuf.EnumOptions") + proto.RegisterType((*EnumValueOptions)(nil), "google.protobuf.EnumValueOptions") + proto.RegisterType((*ServiceOptions)(nil), "google.protobuf.ServiceOptions") + proto.RegisterType((*MethodOptions)(nil), "google.protobuf.MethodOptions") + proto.RegisterType((*UninterpretedOption)(nil), "google.protobuf.UninterpretedOption") + proto.RegisterType((*UninterpretedOption_NamePart)(nil), "google.protobuf.UninterpretedOption.NamePart") + proto.RegisterType((*SourceCodeInfo)(nil), "google.protobuf.SourceCodeInfo") + proto.RegisterType((*SourceCodeInfo_Location)(nil), "google.protobuf.SourceCodeInfo.Location") + proto.RegisterType((*GeneratedCodeInfo)(nil), "google.protobuf.GeneratedCodeInfo") + proto.RegisterType((*GeneratedCodeInfo_Annotation)(nil), "google.protobuf.GeneratedCodeInfo.Annotation") +} + +func init() { proto.RegisterFile("google/protobuf/descriptor.proto", fileDescriptor_e5baabe45344a177) } + +var fileDescriptor_e5baabe45344a177 = []byte{ + // 2589 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xdd, 0x8e, 0xdb, 0xc6, + 0x15, 0x0e, 0xf5, 0xb7, 0xd2, 0x91, 0x56, 0x3b, 0x3b, 0xbb, 0xb1, 0xe9, 0xcd, 0x8f, 0xd7, 0xca, + 0x8f, 0xd7, 0x4e, 0xac, 0x0d, 0x1c, 0xdb, 0x71, 0xd6, 0x45, 0x5a, 0xad, 0x44, 0x6f, 0xe4, 0xee, + 0x4a, 0x2a, 0xa5, 0x6d, 0x7e, 0x80, 0x82, 0x98, 0x25, 0x47, 0x12, 0x6d, 0x8a, 0x64, 0x48, 0xca, + 0xf6, 0x06, 0xbd, 0x30, 0xd0, 0xab, 0x5e, 0x15, 0xe8, 0x55, 0x51, 0x14, 0xbd, 0xe8, 0x4d, 0x80, + 0x3e, 0x40, 0x81, 0xde, 0xf5, 0x09, 0x0a, 0xe4, 0x0d, 0x8a, 0xb6, 0x40, 0xfb, 0x08, 0xbd, 0x2c, + 0x66, 0x86, 0xa4, 0x48, 0x49, 0x1b, 0x6f, 0x02, 0xc4, 0xb9, 0x92, 0xe6, 0x3b, 0xdf, 0x39, 0x73, + 0xe6, 0xcc, 0x99, 0x99, 0x33, 0x43, 0xd8, 0x1e, 0x39, 0xce, 0xc8, 0xa2, 0xbb, 0xae, 0xe7, 0x04, + 0xce, 0xc9, 0x74, 0xb8, 0x6b, 0x50, 0x5f, 0xf7, 0x4c, 0x37, 0x70, 0xbc, 0x3a, 0xc7, 0xf0, 0x9a, + 0x60, 0xd4, 0x23, 0x46, 0xed, 0x08, 0xd6, 0xef, 0x9b, 0x16, 0x6d, 0xc5, 0xc4, 0x3e, 0x0d, 0xf0, + 0x5d, 0xc8, 0x0d, 0x4d, 0x8b, 0xca, 0xd2, 0x76, 0x76, 0xa7, 0x7c, 0xf3, 0xcd, 0xfa, 0x9c, 0x52, + 0x3d, 0xad, 0xd1, 0x63, 0xb0, 0xca, 0x35, 0x6a, 0xff, 0xce, 0xc1, 0xc6, 0x12, 0x29, 0xc6, 0x90, + 0xb3, 0xc9, 0x84, 0x59, 0x94, 0x76, 0x4a, 0x2a, 0xff, 0x8f, 0x65, 0x58, 0x71, 0x89, 0xfe, 0x88, + 0x8c, 0xa8, 0x9c, 0xe1, 0x70, 0xd4, 0xc4, 0xaf, 0x03, 0x18, 0xd4, 0xa5, 0xb6, 0x41, 0x6d, 0xfd, + 0x54, 0xce, 0x6e, 0x67, 0x77, 0x4a, 0x6a, 0x02, 0xc1, 0xef, 0xc0, 0xba, 0x3b, 0x3d, 0xb1, 0x4c, + 0x5d, 0x4b, 0xd0, 0x60, 0x3b, 0xbb, 0x93, 0x57, 0x91, 0x10, 0xb4, 0x66, 0xe4, 0xab, 0xb0, 0xf6, + 0x84, 0x92, 0x47, 0x49, 0x6a, 0x99, 0x53, 0xab, 0x0c, 0x4e, 0x10, 0x9b, 0x50, 0x99, 0x50, 0xdf, + 0x27, 0x23, 0xaa, 0x05, 0xa7, 0x2e, 0x95, 0x73, 0x7c, 0xf4, 0xdb, 0x0b, 0xa3, 0x9f, 0x1f, 0x79, + 0x39, 0xd4, 0x1a, 0x9c, 0xba, 0x14, 0x37, 0xa0, 0x44, 0xed, 0xe9, 0x44, 0x58, 0xc8, 0x9f, 0x11, + 0x3f, 0xc5, 0x9e, 0x4e, 0xe6, 0xad, 0x14, 0x99, 0x5a, 0x68, 0x62, 0xc5, 0xa7, 0xde, 0x63, 0x53, + 0xa7, 0x72, 0x81, 0x1b, 0xb8, 0xba, 0x60, 0xa0, 0x2f, 0xe4, 0xf3, 0x36, 0x22, 0x3d, 0xdc, 0x84, + 0x12, 0x7d, 0x1a, 0x50, 0xdb, 0x37, 0x1d, 0x5b, 0x5e, 0xe1, 0x46, 0xde, 0x5a, 0x32, 0x8b, 0xd4, + 0x32, 0xe6, 0x4d, 0xcc, 0xf4, 0xf0, 0x1d, 0x58, 0x71, 0xdc, 0xc0, 0x74, 0x6c, 0x5f, 0x2e, 0x6e, + 0x4b, 0x3b, 0xe5, 0x9b, 0xaf, 0x2e, 0x4d, 0x84, 0xae, 0xe0, 0xa8, 0x11, 0x19, 0xb7, 0x01, 0xf9, + 0xce, 0xd4, 0xd3, 0xa9, 0xa6, 0x3b, 0x06, 0xd5, 0x4c, 0x7b, 0xe8, 0xc8, 0x25, 0x6e, 0xe0, 0xf2, + 0xe2, 0x40, 0x38, 0xb1, 0xe9, 0x18, 0xb4, 0x6d, 0x0f, 0x1d, 0xb5, 0xea, 0xa7, 0xda, 0xf8, 0x02, + 0x14, 0xfc, 0x53, 0x3b, 0x20, 0x4f, 0xe5, 0x0a, 0xcf, 0x90, 0xb0, 0x55, 0xfb, 0x6b, 0x01, 0xd6, + 0xce, 0x93, 0x62, 0xf7, 0x20, 0x3f, 0x64, 0xa3, 0x94, 0x33, 0xdf, 0x26, 0x06, 0x42, 0x27, 0x1d, + 0xc4, 0xc2, 0x77, 0x0c, 0x62, 0x03, 0xca, 0x36, 0xf5, 0x03, 0x6a, 0x88, 0x8c, 0xc8, 0x9e, 0x33, + 0xa7, 0x40, 0x28, 0x2d, 0xa6, 0x54, 0xee, 0x3b, 0xa5, 0xd4, 0xa7, 0xb0, 0x16, 0xbb, 0xa4, 0x79, + 0xc4, 0x1e, 0x45, 0xb9, 0xb9, 0xfb, 0x3c, 0x4f, 0xea, 0x4a, 0xa4, 0xa7, 0x32, 0x35, 0xb5, 0x4a, + 0x53, 0x6d, 0xdc, 0x02, 0x70, 0x6c, 0xea, 0x0c, 0x35, 0x83, 0xea, 0x96, 0x5c, 0x3c, 0x23, 0x4a, + 0x5d, 0x46, 0x59, 0x88, 0x92, 0x23, 0x50, 0xdd, 0xc2, 0x1f, 0xce, 0x52, 0x6d, 0xe5, 0x8c, 0x4c, + 0x39, 0x12, 0x8b, 0x6c, 0x21, 0xdb, 0x8e, 0xa1, 0xea, 0x51, 0x96, 0xf7, 0xd4, 0x08, 0x47, 0x56, + 0xe2, 0x4e, 0xd4, 0x9f, 0x3b, 0x32, 0x35, 0x54, 0x13, 0x03, 0x5b, 0xf5, 0x92, 0x4d, 0xfc, 0x06, + 0xc4, 0x80, 0xc6, 0xd3, 0x0a, 0xf8, 0x2e, 0x54, 0x89, 0xc0, 0x0e, 0x99, 0xd0, 0xad, 0x2f, 0xa1, + 0x9a, 0x0e, 0x0f, 0xde, 0x84, 0xbc, 0x1f, 0x10, 0x2f, 0xe0, 0x59, 0x98, 0x57, 0x45, 0x03, 0x23, + 0xc8, 0x52, 0xdb, 0xe0, 0xbb, 0x5c, 0x5e, 0x65, 0x7f, 0xf1, 0x4f, 0x66, 0x03, 0xce, 0xf2, 0x01, + 0xbf, 0xbd, 0x38, 0xa3, 0x29, 0xcb, 0xf3, 0xe3, 0xde, 0xfa, 0x00, 0x56, 0x53, 0x03, 0x38, 0x6f, + 0xd7, 0xb5, 0x5f, 0xc2, 0xcb, 0x4b, 0x4d, 0xe3, 0x4f, 0x61, 0x73, 0x6a, 0x9b, 0x76, 0x40, 0x3d, + 0xd7, 0xa3, 0x2c, 0x63, 0x45, 0x57, 0xf2, 0x7f, 0x56, 0xce, 0xc8, 0xb9, 0xe3, 0x24, 0x5b, 0x58, + 0x51, 0x37, 0xa6, 0x8b, 0xe0, 0xf5, 0x52, 0xf1, 0xbf, 0x2b, 0xe8, 0xd9, 0xb3, 0x67, 0xcf, 0x32, + 0xb5, 0xdf, 0x15, 0x60, 0x73, 0xd9, 0x9a, 0x59, 0xba, 0x7c, 0x2f, 0x40, 0xc1, 0x9e, 0x4e, 0x4e, + 0xa8, 0xc7, 0x83, 0x94, 0x57, 0xc3, 0x16, 0x6e, 0x40, 0xde, 0x22, 0x27, 0xd4, 0x92, 0x73, 0xdb, + 0xd2, 0x4e, 0xf5, 0xe6, 0x3b, 0xe7, 0x5a, 0x95, 0xf5, 0x43, 0xa6, 0xa2, 0x0a, 0x4d, 0xfc, 0x11, + 0xe4, 0xc2, 0x2d, 0x9a, 0x59, 0xb8, 0x7e, 0x3e, 0x0b, 0x6c, 0x2d, 0xa9, 0x5c, 0x0f, 0xbf, 0x02, + 0x25, 0xf6, 0x2b, 0x72, 0xa3, 0xc0, 0x7d, 0x2e, 0x32, 0x80, 0xe5, 0x05, 0xde, 0x82, 0x22, 0x5f, + 0x26, 0x06, 0x8d, 0x8e, 0xb6, 0xb8, 0xcd, 0x12, 0xcb, 0xa0, 0x43, 0x32, 0xb5, 0x02, 0xed, 0x31, + 0xb1, 0xa6, 0x94, 0x27, 0x7c, 0x49, 0xad, 0x84, 0xe0, 0xcf, 0x19, 0x86, 0x2f, 0x43, 0x59, 0xac, + 0x2a, 0xd3, 0x36, 0xe8, 0x53, 0xbe, 0x7b, 0xe6, 0x55, 0xb1, 0xd0, 0xda, 0x0c, 0x61, 0xdd, 0x3f, + 0xf4, 0x1d, 0x3b, 0x4a, 0x4d, 0xde, 0x05, 0x03, 0x78, 0xf7, 0x1f, 0xcc, 0x6f, 0xdc, 0xaf, 0x2d, + 0x1f, 0xde, 0x7c, 0x4e, 0xd5, 0xfe, 0x92, 0x81, 0x1c, 0xdf, 0x2f, 0xd6, 0xa0, 0x3c, 0xf8, 0xac, + 0xa7, 0x68, 0xad, 0xee, 0xf1, 0xfe, 0xa1, 0x82, 0x24, 0x5c, 0x05, 0xe0, 0xc0, 0xfd, 0xc3, 0x6e, + 0x63, 0x80, 0x32, 0x71, 0xbb, 0xdd, 0x19, 0xdc, 0xb9, 0x85, 0xb2, 0xb1, 0xc2, 0xb1, 0x00, 0x72, + 0x49, 0xc2, 0xfb, 0x37, 0x51, 0x1e, 0x23, 0xa8, 0x08, 0x03, 0xed, 0x4f, 0x95, 0xd6, 0x9d, 0x5b, + 0xa8, 0x90, 0x46, 0xde, 0xbf, 0x89, 0x56, 0xf0, 0x2a, 0x94, 0x38, 0xb2, 0xdf, 0xed, 0x1e, 0xa2, + 0x62, 0x6c, 0xb3, 0x3f, 0x50, 0xdb, 0x9d, 0x03, 0x54, 0x8a, 0x6d, 0x1e, 0xa8, 0xdd, 0xe3, 0x1e, + 0x82, 0xd8, 0xc2, 0x91, 0xd2, 0xef, 0x37, 0x0e, 0x14, 0x54, 0x8e, 0x19, 0xfb, 0x9f, 0x0d, 0x94, + 0x3e, 0xaa, 0xa4, 0xdc, 0x7a, 0xff, 0x26, 0x5a, 0x8d, 0xbb, 0x50, 0x3a, 0xc7, 0x47, 0xa8, 0x8a, + 0xd7, 0x61, 0x55, 0x74, 0x11, 0x39, 0xb1, 0x36, 0x07, 0xdd, 0xb9, 0x85, 0xd0, 0xcc, 0x11, 0x61, + 0x65, 0x3d, 0x05, 0xdc, 0xb9, 0x85, 0x70, 0xad, 0x09, 0x79, 0x9e, 0x5d, 0x18, 0x43, 0xf5, 0xb0, + 0xb1, 0xaf, 0x1c, 0x6a, 0xdd, 0xde, 0xa0, 0xdd, 0xed, 0x34, 0x0e, 0x91, 0x34, 0xc3, 0x54, 0xe5, + 0x67, 0xc7, 0x6d, 0x55, 0x69, 0xa1, 0x4c, 0x12, 0xeb, 0x29, 0x8d, 0x81, 0xd2, 0x42, 0xd9, 0x9a, + 0x0e, 0x9b, 0xcb, 0xf6, 0xc9, 0xa5, 0x2b, 0x23, 0x31, 0xc5, 0x99, 0x33, 0xa6, 0x98, 0xdb, 0x5a, + 0x98, 0xe2, 0x7f, 0x65, 0x60, 0x63, 0xc9, 0x59, 0xb1, 0xb4, 0x93, 0x1f, 0x43, 0x5e, 0xa4, 0xa8, + 0x38, 0x3d, 0xaf, 0x2d, 0x3d, 0x74, 0x78, 0xc2, 0x2e, 0x9c, 0xa0, 0x5c, 0x2f, 0x59, 0x41, 0x64, + 0xcf, 0xa8, 0x20, 0x98, 0x89, 0x85, 0x3d, 0xfd, 0x17, 0x0b, 0x7b, 0xba, 0x38, 0xf6, 0xee, 0x9c, + 0xe7, 0xd8, 0xe3, 0xd8, 0xb7, 0xdb, 0xdb, 0xf3, 0x4b, 0xf6, 0xf6, 0x7b, 0xb0, 0xbe, 0x60, 0xe8, + 0xdc, 0x7b, 0xec, 0xaf, 0x24, 0x90, 0xcf, 0x0a, 0xce, 0x73, 0x76, 0xba, 0x4c, 0x6a, 0xa7, 0xbb, + 0x37, 0x1f, 0xc1, 0x2b, 0x67, 0x4f, 0xc2, 0xc2, 0x5c, 0x7f, 0x25, 0xc1, 0x85, 0xe5, 0x95, 0xe2, + 0x52, 0x1f, 0x3e, 0x82, 0xc2, 0x84, 0x06, 0x63, 0x27, 0xaa, 0x96, 0xde, 0x5e, 0x72, 0x06, 0x33, + 0xf1, 0xfc, 0x64, 0x87, 0x5a, 0xc9, 0x43, 0x3c, 0x7b, 0x56, 0xb9, 0x27, 0xbc, 0x59, 0xf0, 0xf4, + 0xd7, 0x19, 0x78, 0x79, 0xa9, 0xf1, 0xa5, 0x8e, 0xbe, 0x06, 0x60, 0xda, 0xee, 0x34, 0x10, 0x15, + 0x91, 0xd8, 0x60, 0x4b, 0x1c, 0xe1, 0x9b, 0x17, 0xdb, 0x3c, 0xa7, 0x41, 0x2c, 0xcf, 0x72, 0x39, + 0x08, 0x88, 0x13, 0xee, 0xce, 0x1c, 0xcd, 0x71, 0x47, 0x5f, 0x3f, 0x63, 0xa4, 0x0b, 0x89, 0xf9, + 0x1e, 0x20, 0xdd, 0x32, 0xa9, 0x1d, 0x68, 0x7e, 0xe0, 0x51, 0x32, 0x31, 0xed, 0x11, 0x3f, 0x41, + 0x8a, 0x7b, 0xf9, 0x21, 0xb1, 0x7c, 0xaa, 0xae, 0x09, 0x71, 0x3f, 0x92, 0x32, 0x0d, 0x9e, 0x40, + 0x5e, 0x42, 0xa3, 0x90, 0xd2, 0x10, 0xe2, 0x58, 0xa3, 0xf6, 0xdb, 0x12, 0x94, 0x13, 0x75, 0x35, + 0xbe, 0x02, 0x95, 0x87, 0xe4, 0x31, 0xd1, 0xa2, 0xbb, 0x92, 0x88, 0x44, 0x99, 0x61, 0xbd, 0xf0, + 0xbe, 0xf4, 0x1e, 0x6c, 0x72, 0x8a, 0x33, 0x0d, 0xa8, 0xa7, 0xe9, 0x16, 0xf1, 0x7d, 0x1e, 0xb4, + 0x22, 0xa7, 0x62, 0x26, 0xeb, 0x32, 0x51, 0x33, 0x92, 0xe0, 0xdb, 0xb0, 0xc1, 0x35, 0x26, 0x53, + 0x2b, 0x30, 0x5d, 0x8b, 0x6a, 0xec, 0xf6, 0xe6, 0xf3, 0x93, 0x24, 0xf6, 0x6c, 0x9d, 0x31, 0x8e, + 0x42, 0x02, 0xf3, 0xc8, 0xc7, 0x2d, 0x78, 0x8d, 0xab, 0x8d, 0xa8, 0x4d, 0x3d, 0x12, 0x50, 0x8d, + 0x7e, 0x31, 0x25, 0x96, 0xaf, 0x11, 0xdb, 0xd0, 0xc6, 0xc4, 0x1f, 0xcb, 0x9b, 0xcc, 0xc0, 0x7e, + 0x46, 0x96, 0xd4, 0x4b, 0x8c, 0x78, 0x10, 0xf2, 0x14, 0x4e, 0x6b, 0xd8, 0xc6, 0xc7, 0xc4, 0x1f, + 0xe3, 0x3d, 0xb8, 0xc0, 0xad, 0xf8, 0x81, 0x67, 0xda, 0x23, 0x4d, 0x1f, 0x53, 0xfd, 0x91, 0x36, + 0x0d, 0x86, 0x77, 0xe5, 0x57, 0x92, 0xfd, 0x73, 0x0f, 0xfb, 0x9c, 0xd3, 0x64, 0x94, 0xe3, 0x60, + 0x78, 0x17, 0xf7, 0xa1, 0xc2, 0x26, 0x63, 0x62, 0x7e, 0x49, 0xb5, 0xa1, 0xe3, 0xf1, 0xa3, 0xb1, + 0xba, 0x64, 0x6b, 0x4a, 0x44, 0xb0, 0xde, 0x0d, 0x15, 0x8e, 0x1c, 0x83, 0xee, 0xe5, 0xfb, 0x3d, + 0x45, 0x69, 0xa9, 0xe5, 0xc8, 0xca, 0x7d, 0xc7, 0x63, 0x09, 0x35, 0x72, 0xe2, 0x00, 0x97, 0x45, + 0x42, 0x8d, 0x9c, 0x28, 0xbc, 0xb7, 0x61, 0x43, 0xd7, 0xc5, 0x98, 0x4d, 0x5d, 0x0b, 0xef, 0x58, + 0xbe, 0x8c, 0x52, 0xc1, 0xd2, 0xf5, 0x03, 0x41, 0x08, 0x73, 0xdc, 0xc7, 0x1f, 0xc2, 0xcb, 0xb3, + 0x60, 0x25, 0x15, 0xd7, 0x17, 0x46, 0x39, 0xaf, 0x7a, 0x1b, 0x36, 0xdc, 0xd3, 0x45, 0x45, 0x9c, + 0xea, 0xd1, 0x3d, 0x9d, 0x57, 0xfb, 0x00, 0x36, 0xdd, 0xb1, 0xbb, 0xa8, 0x77, 0x3d, 0xa9, 0x87, + 0xdd, 0xb1, 0x3b, 0xaf, 0xf8, 0x16, 0xbf, 0x70, 0x7b, 0x54, 0x27, 0x01, 0x35, 0xe4, 0x8b, 0x49, + 0x7a, 0x42, 0x80, 0x77, 0x01, 0xe9, 0xba, 0x46, 0x6d, 0x72, 0x62, 0x51, 0x8d, 0x78, 0xd4, 0x26, + 0xbe, 0x7c, 0x39, 0x49, 0xae, 0xea, 0xba, 0xc2, 0xa5, 0x0d, 0x2e, 0xc4, 0xd7, 0x61, 0xdd, 0x39, + 0x79, 0xa8, 0x8b, 0x94, 0xd4, 0x5c, 0x8f, 0x0e, 0xcd, 0xa7, 0xf2, 0x9b, 0x3c, 0xbe, 0x6b, 0x4c, + 0xc0, 0x13, 0xb2, 0xc7, 0x61, 0x7c, 0x0d, 0x90, 0xee, 0x8f, 0x89, 0xe7, 0xf2, 0x3d, 0xd9, 0x77, + 0x89, 0x4e, 0xe5, 0xb7, 0x04, 0x55, 0xe0, 0x9d, 0x08, 0x66, 0x4b, 0xc2, 0x7f, 0x62, 0x0e, 0x83, + 0xc8, 0xe2, 0x55, 0xb1, 0x24, 0x38, 0x16, 0x5a, 0xdb, 0x01, 0xc4, 0x42, 0x91, 0xea, 0x78, 0x87, + 0xd3, 0xaa, 0xee, 0xd8, 0x4d, 0xf6, 0xfb, 0x06, 0xac, 0x32, 0xe6, 0xac, 0xd3, 0x6b, 0xa2, 0x20, + 0x73, 0xc7, 0x89, 0x1e, 0x6f, 0xc1, 0x05, 0x46, 0x9a, 0xd0, 0x80, 0x18, 0x24, 0x20, 0x09, 0xf6, + 0xbb, 0x9c, 0xcd, 0xe2, 0x7e, 0x14, 0x0a, 0x53, 0x7e, 0x7a, 0xd3, 0x93, 0xd3, 0x38, 0xb3, 0x6e, + 0x08, 0x3f, 0x19, 0x16, 0xe5, 0xd6, 0xf7, 0x56, 0x74, 0xd7, 0xf6, 0xa0, 0x92, 0x4c, 0x7c, 0x5c, + 0x02, 0x91, 0xfa, 0x48, 0x62, 0x55, 0x50, 0xb3, 0xdb, 0x62, 0xf5, 0xcb, 0xe7, 0x0a, 0xca, 0xb0, + 0x3a, 0xea, 0xb0, 0x3d, 0x50, 0x34, 0xf5, 0xb8, 0x33, 0x68, 0x1f, 0x29, 0x28, 0x9b, 0x28, 0xd8, + 0x1f, 0xe4, 0x8a, 0x6f, 0xa3, 0xab, 0xb5, 0xaf, 0x33, 0x50, 0x4d, 0xdf, 0xc0, 0xf0, 0x8f, 0xe0, + 0x62, 0xf4, 0x5c, 0xe2, 0xd3, 0x40, 0x7b, 0x62, 0x7a, 0x7c, 0x45, 0x4e, 0x88, 0x38, 0x1d, 0xe3, + 0x9c, 0xd8, 0x0c, 0x59, 0x7d, 0x1a, 0x7c, 0x62, 0x7a, 0x6c, 0xbd, 0x4d, 0x48, 0x80, 0x0f, 0xe1, + 0xb2, 0xed, 0x68, 0x7e, 0x40, 0x6c, 0x83, 0x78, 0x86, 0x36, 0x7b, 0xa8, 0xd2, 0x88, 0xae, 0x53, + 0xdf, 0x77, 0xc4, 0x49, 0x18, 0x5b, 0x79, 0xd5, 0x76, 0xfa, 0x21, 0x79, 0x76, 0x44, 0x34, 0x42, + 0xea, 0x5c, 0xfe, 0x66, 0xcf, 0xca, 0xdf, 0x57, 0xa0, 0x34, 0x21, 0xae, 0x46, 0xed, 0xc0, 0x3b, + 0xe5, 0x75, 0x77, 0x51, 0x2d, 0x4e, 0x88, 0xab, 0xb0, 0xf6, 0x0b, 0xb9, 0xfe, 0x3c, 0xc8, 0x15, + 0x8b, 0xa8, 0xf4, 0x20, 0x57, 0x2c, 0x21, 0xa8, 0xfd, 0x33, 0x0b, 0x95, 0x64, 0x1d, 0xce, 0xae, + 0x35, 0x3a, 0x3f, 0xb2, 0x24, 0xbe, 0xa9, 0xbd, 0xf1, 0x8d, 0x55, 0x7b, 0xbd, 0xc9, 0xce, 0xb2, + 0xbd, 0x82, 0xa8, 0x8e, 0x55, 0xa1, 0xc9, 0xea, 0x08, 0x96, 0x6c, 0x54, 0x54, 0x23, 0x45, 0x35, + 0x6c, 0xe1, 0x03, 0x28, 0x3c, 0xf4, 0xb9, 0xed, 0x02, 0xb7, 0xfd, 0xe6, 0x37, 0xdb, 0x7e, 0xd0, + 0xe7, 0xc6, 0x4b, 0x0f, 0xfa, 0x5a, 0xa7, 0xab, 0x1e, 0x35, 0x0e, 0xd5, 0x50, 0x1d, 0x5f, 0x82, + 0x9c, 0x45, 0xbe, 0x3c, 0x4d, 0x9f, 0x7a, 0x1c, 0x3a, 0xef, 0x24, 0x5c, 0x82, 0xdc, 0x13, 0x4a, + 0x1e, 0xa5, 0xcf, 0x1a, 0x0e, 0x7d, 0x8f, 0x8b, 0x61, 0x17, 0xf2, 0x3c, 0x5e, 0x18, 0x20, 0x8c, + 0x18, 0x7a, 0x09, 0x17, 0x21, 0xd7, 0xec, 0xaa, 0x6c, 0x41, 0x20, 0xa8, 0x08, 0x54, 0xeb, 0xb5, + 0x95, 0xa6, 0x82, 0x32, 0xb5, 0xdb, 0x50, 0x10, 0x41, 0x60, 0x8b, 0x25, 0x0e, 0x03, 0x7a, 0x29, + 0x6c, 0x86, 0x36, 0xa4, 0x48, 0x7a, 0x7c, 0xb4, 0xaf, 0xa8, 0x28, 0x93, 0x9e, 0xea, 0x1c, 0xca, + 0xd7, 0x7c, 0xa8, 0x24, 0x0b, 0xf1, 0x17, 0x73, 0xc9, 0xfe, 0x9b, 0x04, 0xe5, 0x44, 0x61, 0xcd, + 0x2a, 0x22, 0x62, 0x59, 0xce, 0x13, 0x8d, 0x58, 0x26, 0xf1, 0xc3, 0xd4, 0x00, 0x0e, 0x35, 0x18, + 0x72, 0xde, 0xa9, 0x7b, 0x41, 0x4b, 0x24, 0x8f, 0x0a, 0xb5, 0x3f, 0x4a, 0x80, 0xe6, 0x2b, 0xdb, + 0x39, 0x37, 0xa5, 0x1f, 0xd2, 0xcd, 0xda, 0x1f, 0x24, 0xa8, 0xa6, 0xcb, 0xd9, 0x39, 0xf7, 0xae, + 0xfc, 0xa0, 0xee, 0xfd, 0x23, 0x03, 0xab, 0xa9, 0x22, 0xf6, 0xbc, 0xde, 0x7d, 0x01, 0xeb, 0xa6, + 0x41, 0x27, 0xae, 0x13, 0x50, 0x5b, 0x3f, 0xd5, 0x2c, 0xfa, 0x98, 0x5a, 0x72, 0x8d, 0x6f, 0x1a, + 0xbb, 0xdf, 0x5c, 0x26, 0xd7, 0xdb, 0x33, 0xbd, 0x43, 0xa6, 0xb6, 0xb7, 0xd1, 0x6e, 0x29, 0x47, + 0xbd, 0xee, 0x40, 0xe9, 0x34, 0x3f, 0xd3, 0x8e, 0x3b, 0x3f, 0xed, 0x74, 0x3f, 0xe9, 0xa8, 0xc8, + 0x9c, 0xa3, 0x7d, 0x8f, 0xcb, 0xbe, 0x07, 0x68, 0xde, 0x29, 0x7c, 0x11, 0x96, 0xb9, 0x85, 0x5e, + 0xc2, 0x1b, 0xb0, 0xd6, 0xe9, 0x6a, 0xfd, 0x76, 0x4b, 0xd1, 0x94, 0xfb, 0xf7, 0x95, 0xe6, 0xa0, + 0x2f, 0x1e, 0x3e, 0x62, 0xf6, 0x20, 0xb5, 0xc0, 0x6b, 0xbf, 0xcf, 0xc2, 0xc6, 0x12, 0x4f, 0x70, + 0x23, 0xbc, 0xb2, 0x88, 0x5b, 0xd4, 0x8d, 0xf3, 0x78, 0x5f, 0x67, 0x35, 0x43, 0x8f, 0x78, 0x41, + 0x78, 0xc3, 0xb9, 0x06, 0x2c, 0x4a, 0x76, 0x60, 0x0e, 0x4d, 0xea, 0x85, 0xef, 0x44, 0xe2, 0x1e, + 0xb3, 0x36, 0xc3, 0xc5, 0x53, 0xd1, 0xbb, 0x80, 0x5d, 0xc7, 0x37, 0x03, 0xf3, 0x31, 0xd5, 0x4c, + 0x3b, 0x7a, 0x54, 0x62, 0xf7, 0x9a, 0x9c, 0x8a, 0x22, 0x49, 0xdb, 0x0e, 0x62, 0xb6, 0x4d, 0x47, + 0x64, 0x8e, 0xcd, 0x36, 0xf3, 0xac, 0x8a, 0x22, 0x49, 0xcc, 0xbe, 0x02, 0x15, 0xc3, 0x99, 0xb2, + 0x62, 0x4f, 0xf0, 0xd8, 0xd9, 0x21, 0xa9, 0x65, 0x81, 0xc5, 0x94, 0xb0, 0x8c, 0x9f, 0xbd, 0x66, + 0x55, 0xd4, 0xb2, 0xc0, 0x04, 0xe5, 0x2a, 0xac, 0x91, 0xd1, 0xc8, 0x63, 0xc6, 0x23, 0x43, 0xe2, + 0x62, 0x52, 0x8d, 0x61, 0x4e, 0xdc, 0x7a, 0x00, 0xc5, 0x28, 0x0e, 0xec, 0xa8, 0x66, 0x91, 0xd0, + 0x5c, 0x71, 0xdb, 0xce, 0xec, 0x94, 0xd4, 0xa2, 0x1d, 0x09, 0xaf, 0x40, 0xc5, 0xf4, 0xb5, 0xd9, + 0xe3, 0x7c, 0x66, 0x3b, 0xb3, 0x53, 0x54, 0xcb, 0xa6, 0x1f, 0x3f, 0x6c, 0xd6, 0xbe, 0xca, 0x40, + 0x35, 0xfd, 0x71, 0x01, 0xb7, 0xa0, 0x68, 0x39, 0x3a, 0xe1, 0xa9, 0x25, 0xbe, 0x6c, 0xed, 0x3c, + 0xe7, 0x7b, 0x44, 0xfd, 0x30, 0xe4, 0xab, 0xb1, 0xe6, 0xd6, 0xdf, 0x25, 0x28, 0x46, 0x30, 0xbe, + 0x00, 0x39, 0x97, 0x04, 0x63, 0x6e, 0x2e, 0xbf, 0x9f, 0x41, 0x92, 0xca, 0xdb, 0x0c, 0xf7, 0x5d, + 0x62, 0xf3, 0x14, 0x08, 0x71, 0xd6, 0x66, 0xf3, 0x6a, 0x51, 0x62, 0xf0, 0x5b, 0x8f, 0x33, 0x99, + 0x50, 0x3b, 0xf0, 0xa3, 0x79, 0x0d, 0xf1, 0x66, 0x08, 0xe3, 0x77, 0x60, 0x3d, 0xf0, 0x88, 0x69, + 0xa5, 0xb8, 0x39, 0xce, 0x45, 0x91, 0x20, 0x26, 0xef, 0xc1, 0xa5, 0xc8, 0xae, 0x41, 0x03, 0xa2, + 0x8f, 0xa9, 0x31, 0x53, 0x2a, 0xf0, 0xd7, 0x8d, 0x8b, 0x21, 0xa1, 0x15, 0xca, 0x23, 0xdd, 0xda, + 0xd7, 0x12, 0xac, 0x47, 0xf7, 0x34, 0x23, 0x0e, 0xd6, 0x11, 0x00, 0xb1, 0x6d, 0x27, 0x48, 0x86, + 0x6b, 0x31, 0x95, 0x17, 0xf4, 0xea, 0x8d, 0x58, 0x49, 0x4d, 0x18, 0xd8, 0x9a, 0x00, 0xcc, 0x24, + 0x67, 0x86, 0xed, 0x32, 0x94, 0xc3, 0x2f, 0x47, 0xfc, 0xf3, 0xa3, 0xb8, 0xd9, 0x83, 0x80, 0xd8, + 0x85, 0x0e, 0x6f, 0x42, 0xfe, 0x84, 0x8e, 0x4c, 0x3b, 0x7c, 0x0f, 0x16, 0x8d, 0xe8, 0xfd, 0x25, + 0x17, 0xbf, 0xbf, 0xec, 0xff, 0x46, 0x82, 0x0d, 0xdd, 0x99, 0xcc, 0xfb, 0xbb, 0x8f, 0xe6, 0x9e, + 0x17, 0xfc, 0x8f, 0xa5, 0xcf, 0x3f, 0x1a, 0x99, 0xc1, 0x78, 0x7a, 0x52, 0xd7, 0x9d, 0xc9, 0xee, + 0xc8, 0xb1, 0x88, 0x3d, 0x9a, 0x7d, 0x3f, 0xe5, 0x7f, 0xf4, 0x1b, 0x23, 0x6a, 0xdf, 0x18, 0x39, + 0x89, 0xaf, 0xa9, 0xf7, 0x66, 0x7f, 0xff, 0x27, 0x49, 0x7f, 0xca, 0x64, 0x0f, 0x7a, 0xfb, 0x7f, + 0xce, 0x6c, 0x1d, 0x88, 0xee, 0x7a, 0x51, 0x78, 0x54, 0x3a, 0xb4, 0xa8, 0xce, 0x86, 0xfc, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x3e, 0xe8, 0xef, 0xc4, 0x9b, 0x1d, 0x00, 0x00, +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto new file mode 100644 index 000000000..ed08fcbc5 --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto @@ -0,0 +1,883 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; +option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; + optional int32 end = 2; + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + TYPE_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + }; + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + }; + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default=false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default=false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + optional string java_outer_classname = 8; + + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default=false]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default=false]; + + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default=SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default=false]; + optional bool java_generic_services = 17 [default=false]; + optional bool py_generic_services = 18 [default=false]; + optional bool php_generic_services = 42 [default=false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default=false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default=false]; + + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be used + // for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default=false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default=false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default=false]; + + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + optional bool lazy = 5 [default=false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default=false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default=false]; + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype +} + +message OneofOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default=false]; + + reserved 5; // javanano_as_lite + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default=false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default=false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = + 34 [default=IDEMPOTENCY_UNKNOWN]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents + // "foo.(bar.baz).qux". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed=true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed=true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed=true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + } +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/generator/generator.go b/vendor/github.com/golang/protobuf/protoc-gen-go/generator/generator.go new file mode 100644 index 000000000..6f4a902b5 --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/generator/generator.go @@ -0,0 +1,2806 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/* + The code generator for the plugin for the Google protocol buffer compiler. + It generates Go code from the protocol buffer description files read by the + main routine. +*/ +package generator + +import ( + "bufio" + "bytes" + "compress/gzip" + "crypto/sha256" + "encoding/hex" + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/printer" + "go/token" + "log" + "os" + "path" + "sort" + "strconv" + "strings" + "unicode" + "unicode/utf8" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/protoc-gen-go/generator/internal/remap" + + "github.com/golang/protobuf/protoc-gen-go/descriptor" + plugin "github.com/golang/protobuf/protoc-gen-go/plugin" +) + +// generatedCodeVersion indicates a version of the generated code. +// It is incremented whenever an incompatibility between the generated code and +// proto package is introduced; the generated code references +// a constant, proto.ProtoPackageIsVersionN (where N is generatedCodeVersion). +const generatedCodeVersion = 3 + +// A Plugin provides functionality to add to the output during Go code generation, +// such as to produce RPC stubs. +type Plugin interface { + // Name identifies the plugin. + Name() string + // Init is called once after data structures are built but before + // code generation begins. + Init(g *Generator) + // Generate produces the code generated by the plugin for this file, + // except for the imports, by calling the generator's methods P, In, and Out. + Generate(file *FileDescriptor) + // GenerateImports produces the import declarations for this file. + // It is called after Generate. + GenerateImports(file *FileDescriptor) +} + +var plugins []Plugin + +// RegisterPlugin installs a (second-order) plugin to be run when the Go output is generated. +// It is typically called during initialization. +func RegisterPlugin(p Plugin) { + plugins = append(plugins, p) +} + +// A GoImportPath is the import path of a Go package. e.g., "google.golang.org/genproto/protobuf". +type GoImportPath string + +func (p GoImportPath) String() string { return strconv.Quote(string(p)) } + +// A GoPackageName is the name of a Go package. e.g., "protobuf". +type GoPackageName string + +// Each type we import as a protocol buffer (other than FileDescriptorProto) needs +// a pointer to the FileDescriptorProto that represents it. These types achieve that +// wrapping by placing each Proto inside a struct with the pointer to its File. The +// structs have the same names as their contents, with "Proto" removed. +// FileDescriptor is used to store the things that it points to. + +// The file and package name method are common to messages and enums. +type common struct { + file *FileDescriptor // File this object comes from. +} + +// GoImportPath is the import path of the Go package containing the type. +func (c *common) GoImportPath() GoImportPath { + return c.file.importPath +} + +func (c *common) File() *FileDescriptor { return c.file } + +func fileIsProto3(file *descriptor.FileDescriptorProto) bool { + return file.GetSyntax() == "proto3" +} + +func (c *common) proto3() bool { return fileIsProto3(c.file.FileDescriptorProto) } + +// Descriptor represents a protocol buffer message. +type Descriptor struct { + common + *descriptor.DescriptorProto + parent *Descriptor // The containing message, if any. + nested []*Descriptor // Inner messages, if any. + enums []*EnumDescriptor // Inner enums, if any. + ext []*ExtensionDescriptor // Extensions, if any. + typename []string // Cached typename vector. + index int // The index into the container, whether the file or another message. + path string // The SourceCodeInfo path as comma-separated integers. + group bool +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (d *Descriptor) TypeName() []string { + if d.typename != nil { + return d.typename + } + n := 0 + for parent := d; parent != nil; parent = parent.parent { + n++ + } + s := make([]string, n) + for parent := d; parent != nil; parent = parent.parent { + n-- + s[n] = parent.GetName() + } + d.typename = s + return s +} + +// EnumDescriptor describes an enum. If it's at top level, its parent will be nil. +// Otherwise it will be the descriptor of the message in which it is defined. +type EnumDescriptor struct { + common + *descriptor.EnumDescriptorProto + parent *Descriptor // The containing message, if any. + typename []string // Cached typename vector. + index int // The index into the container, whether the file or a message. + path string // The SourceCodeInfo path as comma-separated integers. +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (e *EnumDescriptor) TypeName() (s []string) { + if e.typename != nil { + return e.typename + } + name := e.GetName() + if e.parent == nil { + s = make([]string, 1) + } else { + pname := e.parent.TypeName() + s = make([]string, len(pname)+1) + copy(s, pname) + } + s[len(s)-1] = name + e.typename = s + return s +} + +// Everything but the last element of the full type name, CamelCased. +// The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... . +func (e *EnumDescriptor) prefix() string { + if e.parent == nil { + // If the enum is not part of a message, the prefix is just the type name. + return CamelCase(*e.Name) + "_" + } + typeName := e.TypeName() + return CamelCaseSlice(typeName[0:len(typeName)-1]) + "_" +} + +// The integer value of the named constant in this enumerated type. +func (e *EnumDescriptor) integerValueAsString(name string) string { + for _, c := range e.Value { + if c.GetName() == name { + return fmt.Sprint(c.GetNumber()) + } + } + log.Fatal("cannot find value for enum constant") + return "" +} + +// ExtensionDescriptor describes an extension. If it's at top level, its parent will be nil. +// Otherwise it will be the descriptor of the message in which it is defined. +type ExtensionDescriptor struct { + common + *descriptor.FieldDescriptorProto + parent *Descriptor // The containing message, if any. +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (e *ExtensionDescriptor) TypeName() (s []string) { + name := e.GetName() + if e.parent == nil { + // top-level extension + s = make([]string, 1) + } else { + pname := e.parent.TypeName() + s = make([]string, len(pname)+1) + copy(s, pname) + } + s[len(s)-1] = name + return s +} + +// DescName returns the variable name used for the generated descriptor. +func (e *ExtensionDescriptor) DescName() string { + // The full type name. + typeName := e.TypeName() + // Each scope of the extension is individually CamelCased, and all are joined with "_" with an "E_" prefix. + for i, s := range typeName { + typeName[i] = CamelCase(s) + } + return "E_" + strings.Join(typeName, "_") +} + +// ImportedDescriptor describes a type that has been publicly imported from another file. +type ImportedDescriptor struct { + common + o Object +} + +func (id *ImportedDescriptor) TypeName() []string { return id.o.TypeName() } + +// FileDescriptor describes an protocol buffer descriptor file (.proto). +// It includes slices of all the messages and enums defined within it. +// Those slices are constructed by WrapTypes. +type FileDescriptor struct { + *descriptor.FileDescriptorProto + desc []*Descriptor // All the messages defined in this file. + enum []*EnumDescriptor // All the enums defined in this file. + ext []*ExtensionDescriptor // All the top-level extensions defined in this file. + imp []*ImportedDescriptor // All types defined in files publicly imported by this file. + + // Comments, stored as a map of path (comma-separated integers) to the comment. + comments map[string]*descriptor.SourceCodeInfo_Location + + // The full list of symbols that are exported, + // as a map from the exported object to its symbols. + // This is used for supporting public imports. + exported map[Object][]symbol + + importPath GoImportPath // Import path of this file's package. + packageName GoPackageName // Name of this file's Go package. + + proto3 bool // whether to generate proto3 code for this file +} + +// VarName is the variable name we'll use in the generated code to refer +// to the compressed bytes of this descriptor. It is not exported, so +// it is only valid inside the generated package. +func (d *FileDescriptor) VarName() string { + h := sha256.Sum256([]byte(d.GetName())) + return fmt.Sprintf("fileDescriptor_%s", hex.EncodeToString(h[:8])) +} + +// goPackageOption interprets the file's go_package option. +// If there is no go_package, it returns ("", "", false). +// If there's a simple name, it returns ("", pkg, true). +// If the option implies an import path, it returns (impPath, pkg, true). +func (d *FileDescriptor) goPackageOption() (impPath GoImportPath, pkg GoPackageName, ok bool) { + opt := d.GetOptions().GetGoPackage() + if opt == "" { + return "", "", false + } + // A semicolon-delimited suffix delimits the import path and package name. + sc := strings.Index(opt, ";") + if sc >= 0 { + return GoImportPath(opt[:sc]), cleanPackageName(opt[sc+1:]), true + } + // The presence of a slash implies there's an import path. + slash := strings.LastIndex(opt, "/") + if slash >= 0 { + return GoImportPath(opt), cleanPackageName(opt[slash+1:]), true + } + return "", cleanPackageName(opt), true +} + +// goFileName returns the output name for the generated Go file. +func (d *FileDescriptor) goFileName(pathType pathType) string { + name := *d.Name + if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" { + name = name[:len(name)-len(ext)] + } + name += ".pb.go" + + if pathType == pathTypeSourceRelative { + return name + } + + // Does the file have a "go_package" option? + // If it does, it may override the filename. + if impPath, _, ok := d.goPackageOption(); ok && impPath != "" { + // Replace the existing dirname with the declared import path. + _, name = path.Split(name) + name = path.Join(string(impPath), name) + return name + } + + return name +} + +func (d *FileDescriptor) addExport(obj Object, sym symbol) { + d.exported[obj] = append(d.exported[obj], sym) +} + +// symbol is an interface representing an exported Go symbol. +type symbol interface { + // GenerateAlias should generate an appropriate alias + // for the symbol from the named package. + GenerateAlias(g *Generator, filename string, pkg GoPackageName) +} + +type messageSymbol struct { + sym string + hasExtensions, isMessageSet bool + oneofTypes []string +} + +type getterSymbol struct { + name string + typ string + typeName string // canonical name in proto world; empty for proto.Message and similar + genType bool // whether typ contains a generated type (message/group/enum) +} + +func (ms *messageSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) { + g.P("// ", ms.sym, " from public import ", filename) + g.P("type ", ms.sym, " = ", pkg, ".", ms.sym) + for _, name := range ms.oneofTypes { + g.P("type ", name, " = ", pkg, ".", name) + } +} + +type enumSymbol struct { + name string + proto3 bool // Whether this came from a proto3 file. +} + +func (es enumSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) { + s := es.name + g.P("// ", s, " from public import ", filename) + g.P("type ", s, " = ", pkg, ".", s) + g.P("var ", s, "_name = ", pkg, ".", s, "_name") + g.P("var ", s, "_value = ", pkg, ".", s, "_value") +} + +type constOrVarSymbol struct { + sym string + typ string // either "const" or "var" + cast string // if non-empty, a type cast is required (used for enums) +} + +func (cs constOrVarSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) { + v := string(pkg) + "." + cs.sym + if cs.cast != "" { + v = cs.cast + "(" + v + ")" + } + g.P(cs.typ, " ", cs.sym, " = ", v) +} + +// Object is an interface abstracting the abilities shared by enums, messages, extensions and imported objects. +type Object interface { + GoImportPath() GoImportPath + TypeName() []string + File() *FileDescriptor +} + +// Generator is the type whose methods generate the output, stored in the associated response structure. +type Generator struct { + *bytes.Buffer + + Request *plugin.CodeGeneratorRequest // The input. + Response *plugin.CodeGeneratorResponse // The output. + + Param map[string]string // Command-line parameters. + PackageImportPath string // Go import path of the package we're generating code for + ImportPrefix string // String to prefix to imported package file names. + ImportMap map[string]string // Mapping from .proto file name to import path + + Pkg map[string]string // The names under which we import support packages + + outputImportPath GoImportPath // Package we're generating code for. + allFiles []*FileDescriptor // All files in the tree + allFilesByName map[string]*FileDescriptor // All files by filename. + genFiles []*FileDescriptor // Those files we will generate output for. + file *FileDescriptor // The file we are compiling now. + packageNames map[GoImportPath]GoPackageName // Imported package names in the current file. + usedPackages map[GoImportPath]bool // Packages used in current file. + usedPackageNames map[GoPackageName]bool // Package names used in the current file. + addedImports map[GoImportPath]bool // Additional imports to emit. + typeNameToObject map[string]Object // Key is a fully-qualified name in input syntax. + init []string // Lines to emit in the init function. + indent string + pathType pathType // How to generate output filenames. + writeOutput bool + annotateCode bool // whether to store annotations + annotations []*descriptor.GeneratedCodeInfo_Annotation // annotations to store +} + +type pathType int + +const ( + pathTypeImport pathType = iota + pathTypeSourceRelative +) + +// New creates a new generator and allocates the request and response protobufs. +func New() *Generator { + g := new(Generator) + g.Buffer = new(bytes.Buffer) + g.Request = new(plugin.CodeGeneratorRequest) + g.Response = new(plugin.CodeGeneratorResponse) + return g +} + +// Error reports a problem, including an error, and exits the program. +func (g *Generator) Error(err error, msgs ...string) { + s := strings.Join(msgs, " ") + ":" + err.Error() + log.Print("protoc-gen-go: error:", s) + os.Exit(1) +} + +// Fail reports a problem and exits the program. +func (g *Generator) Fail(msgs ...string) { + s := strings.Join(msgs, " ") + log.Print("protoc-gen-go: error:", s) + os.Exit(1) +} + +// CommandLineParameters breaks the comma-separated list of key=value pairs +// in the parameter (a member of the request protobuf) into a key/value map. +// It then sets file name mappings defined by those entries. +func (g *Generator) CommandLineParameters(parameter string) { + g.Param = make(map[string]string) + for _, p := range strings.Split(parameter, ",") { + if i := strings.Index(p, "="); i < 0 { + g.Param[p] = "" + } else { + g.Param[p[0:i]] = p[i+1:] + } + } + + g.ImportMap = make(map[string]string) + pluginList := "none" // Default list of plugin names to enable (empty means all). + for k, v := range g.Param { + switch k { + case "import_prefix": + g.ImportPrefix = v + case "import_path": + g.PackageImportPath = v + case "paths": + switch v { + case "import": + g.pathType = pathTypeImport + case "source_relative": + g.pathType = pathTypeSourceRelative + default: + g.Fail(fmt.Sprintf(`Unknown path type %q: want "import" or "source_relative".`, v)) + } + case "plugins": + pluginList = v + case "annotate_code": + if v == "true" { + g.annotateCode = true + } + default: + if len(k) > 0 && k[0] == 'M' { + g.ImportMap[k[1:]] = v + } + } + } + if pluginList != "" { + // Amend the set of plugins. + enabled := make(map[string]bool) + for _, name := range strings.Split(pluginList, "+") { + enabled[name] = true + } + var nplugins []Plugin + for _, p := range plugins { + if enabled[p.Name()] { + nplugins = append(nplugins, p) + } + } + plugins = nplugins + } +} + +// DefaultPackageName returns the package name printed for the object. +// If its file is in a different package, it returns the package name we're using for this file, plus ".". +// Otherwise it returns the empty string. +func (g *Generator) DefaultPackageName(obj Object) string { + importPath := obj.GoImportPath() + if importPath == g.outputImportPath { + return "" + } + return string(g.GoPackageName(importPath)) + "." +} + +// GoPackageName returns the name used for a package. +func (g *Generator) GoPackageName(importPath GoImportPath) GoPackageName { + if name, ok := g.packageNames[importPath]; ok { + return name + } + name := cleanPackageName(baseName(string(importPath))) + for i, orig := 1, name; g.usedPackageNames[name] || isGoPredeclaredIdentifier[string(name)]; i++ { + name = orig + GoPackageName(strconv.Itoa(i)) + } + g.packageNames[importPath] = name + g.usedPackageNames[name] = true + return name +} + +// AddImport adds a package to the generated file's import section. +// It returns the name used for the package. +func (g *Generator) AddImport(importPath GoImportPath) GoPackageName { + g.addedImports[importPath] = true + return g.GoPackageName(importPath) +} + +var globalPackageNames = map[GoPackageName]bool{ + "fmt": true, + "math": true, + "proto": true, +} + +// Create and remember a guaranteed unique package name. Pkg is the candidate name. +// The FileDescriptor parameter is unused. +func RegisterUniquePackageName(pkg string, f *FileDescriptor) string { + name := cleanPackageName(pkg) + for i, orig := 1, name; globalPackageNames[name]; i++ { + name = orig + GoPackageName(strconv.Itoa(i)) + } + globalPackageNames[name] = true + return string(name) +} + +var isGoKeyword = map[string]bool{ + "break": true, + "case": true, + "chan": true, + "const": true, + "continue": true, + "default": true, + "else": true, + "defer": true, + "fallthrough": true, + "for": true, + "func": true, + "go": true, + "goto": true, + "if": true, + "import": true, + "interface": true, + "map": true, + "package": true, + "range": true, + "return": true, + "select": true, + "struct": true, + "switch": true, + "type": true, + "var": true, +} + +var isGoPredeclaredIdentifier = map[string]bool{ + "append": true, + "bool": true, + "byte": true, + "cap": true, + "close": true, + "complex": true, + "complex128": true, + "complex64": true, + "copy": true, + "delete": true, + "error": true, + "false": true, + "float32": true, + "float64": true, + "imag": true, + "int": true, + "int16": true, + "int32": true, + "int64": true, + "int8": true, + "iota": true, + "len": true, + "make": true, + "new": true, + "nil": true, + "panic": true, + "print": true, + "println": true, + "real": true, + "recover": true, + "rune": true, + "string": true, + "true": true, + "uint": true, + "uint16": true, + "uint32": true, + "uint64": true, + "uint8": true, + "uintptr": true, +} + +func cleanPackageName(name string) GoPackageName { + name = strings.Map(badToUnderscore, name) + // Identifier must not be keyword or predeclared identifier: insert _. + if isGoKeyword[name] { + name = "_" + name + } + // Identifier must not begin with digit: insert _. + if r, _ := utf8.DecodeRuneInString(name); unicode.IsDigit(r) { + name = "_" + name + } + return GoPackageName(name) +} + +// defaultGoPackage returns the package name to use, +// derived from the import path of the package we're building code for. +func (g *Generator) defaultGoPackage() GoPackageName { + p := g.PackageImportPath + if i := strings.LastIndex(p, "/"); i >= 0 { + p = p[i+1:] + } + return cleanPackageName(p) +} + +// SetPackageNames sets the package name for this run. +// The package name must agree across all files being generated. +// It also defines unique package names for all imported files. +func (g *Generator) SetPackageNames() { + g.outputImportPath = g.genFiles[0].importPath + + defaultPackageNames := make(map[GoImportPath]GoPackageName) + for _, f := range g.genFiles { + if _, p, ok := f.goPackageOption(); ok { + defaultPackageNames[f.importPath] = p + } + } + for _, f := range g.genFiles { + if _, p, ok := f.goPackageOption(); ok { + // Source file: option go_package = "quux/bar"; + f.packageName = p + } else if p, ok := defaultPackageNames[f.importPath]; ok { + // A go_package option in another file in the same package. + // + // This is a poor choice in general, since every source file should + // contain a go_package option. Supported mainly for historical + // compatibility. + f.packageName = p + } else if p := g.defaultGoPackage(); p != "" { + // Command-line: import_path=quux/bar. + // + // The import_path flag sets a package name for files which don't + // contain a go_package option. + f.packageName = p + } else if p := f.GetPackage(); p != "" { + // Source file: package quux.bar; + f.packageName = cleanPackageName(p) + } else { + // Source filename. + f.packageName = cleanPackageName(baseName(f.GetName())) + } + } + + // Check that all files have a consistent package name and import path. + for _, f := range g.genFiles[1:] { + if a, b := g.genFiles[0].importPath, f.importPath; a != b { + g.Fail(fmt.Sprintf("inconsistent package import paths: %v, %v", a, b)) + } + if a, b := g.genFiles[0].packageName, f.packageName; a != b { + g.Fail(fmt.Sprintf("inconsistent package names: %v, %v", a, b)) + } + } + + // Names of support packages. These never vary (if there are conflicts, + // we rename the conflicting package), so this could be removed someday. + g.Pkg = map[string]string{ + "fmt": "fmt", + "math": "math", + "proto": "proto", + } +} + +// WrapTypes walks the incoming data, wrapping DescriptorProtos, EnumDescriptorProtos +// and FileDescriptorProtos into file-referenced objects within the Generator. +// It also creates the list of files to generate and so should be called before GenerateAllFiles. +func (g *Generator) WrapTypes() { + g.allFiles = make([]*FileDescriptor, 0, len(g.Request.ProtoFile)) + g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles)) + genFileNames := make(map[string]bool) + for _, n := range g.Request.FileToGenerate { + genFileNames[n] = true + } + for _, f := range g.Request.ProtoFile { + fd := &FileDescriptor{ + FileDescriptorProto: f, + exported: make(map[Object][]symbol), + proto3: fileIsProto3(f), + } + // The import path may be set in a number of ways. + if substitution, ok := g.ImportMap[f.GetName()]; ok { + // Command-line: M=foo.proto=quux/bar. + // + // Explicit mapping of source file to import path. + fd.importPath = GoImportPath(substitution) + } else if genFileNames[f.GetName()] && g.PackageImportPath != "" { + // Command-line: import_path=quux/bar. + // + // The import_path flag sets the import path for every file that + // we generate code for. + fd.importPath = GoImportPath(g.PackageImportPath) + } else if p, _, _ := fd.goPackageOption(); p != "" { + // Source file: option go_package = "quux/bar"; + // + // The go_package option sets the import path. Most users should use this. + fd.importPath = p + } else { + // Source filename. + // + // Last resort when nothing else is available. + fd.importPath = GoImportPath(path.Dir(f.GetName())) + } + // We must wrap the descriptors before we wrap the enums + fd.desc = wrapDescriptors(fd) + g.buildNestedDescriptors(fd.desc) + fd.enum = wrapEnumDescriptors(fd, fd.desc) + g.buildNestedEnums(fd.desc, fd.enum) + fd.ext = wrapExtensions(fd) + extractComments(fd) + g.allFiles = append(g.allFiles, fd) + g.allFilesByName[f.GetName()] = fd + } + for _, fd := range g.allFiles { + fd.imp = wrapImported(fd, g) + } + + g.genFiles = make([]*FileDescriptor, 0, len(g.Request.FileToGenerate)) + for _, fileName := range g.Request.FileToGenerate { + fd := g.allFilesByName[fileName] + if fd == nil { + g.Fail("could not find file named", fileName) + } + g.genFiles = append(g.genFiles, fd) + } +} + +// Scan the descriptors in this file. For each one, build the slice of nested descriptors +func (g *Generator) buildNestedDescriptors(descs []*Descriptor) { + for _, desc := range descs { + if len(desc.NestedType) != 0 { + for _, nest := range descs { + if nest.parent == desc { + desc.nested = append(desc.nested, nest) + } + } + if len(desc.nested) != len(desc.NestedType) { + g.Fail("internal error: nesting failure for", desc.GetName()) + } + } + } +} + +func (g *Generator) buildNestedEnums(descs []*Descriptor, enums []*EnumDescriptor) { + for _, desc := range descs { + if len(desc.EnumType) != 0 { + for _, enum := range enums { + if enum.parent == desc { + desc.enums = append(desc.enums, enum) + } + } + if len(desc.enums) != len(desc.EnumType) { + g.Fail("internal error: enum nesting failure for", desc.GetName()) + } + } + } +} + +// Construct the Descriptor +func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *Descriptor { + d := &Descriptor{ + common: common{file}, + DescriptorProto: desc, + parent: parent, + index: index, + } + if parent == nil { + d.path = fmt.Sprintf("%d,%d", messagePath, index) + } else { + d.path = fmt.Sprintf("%s,%d,%d", parent.path, messageMessagePath, index) + } + + // The only way to distinguish a group from a message is whether + // the containing message has a TYPE_GROUP field that matches. + if parent != nil { + parts := d.TypeName() + if file.Package != nil { + parts = append([]string{*file.Package}, parts...) + } + exp := "." + strings.Join(parts, ".") + for _, field := range parent.Field { + if field.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP && field.GetTypeName() == exp { + d.group = true + break + } + } + } + + for _, field := range desc.Extension { + d.ext = append(d.ext, &ExtensionDescriptor{common{file}, field, d}) + } + + return d +} + +// Return a slice of all the Descriptors defined within this file +func wrapDescriptors(file *FileDescriptor) []*Descriptor { + sl := make([]*Descriptor, 0, len(file.MessageType)+10) + for i, desc := range file.MessageType { + sl = wrapThisDescriptor(sl, desc, nil, file, i) + } + return sl +} + +// Wrap this Descriptor, recursively +func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) []*Descriptor { + sl = append(sl, newDescriptor(desc, parent, file, index)) + me := sl[len(sl)-1] + for i, nested := range desc.NestedType { + sl = wrapThisDescriptor(sl, nested, me, file, i) + } + return sl +} + +// Construct the EnumDescriptor +func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *EnumDescriptor { + ed := &EnumDescriptor{ + common: common{file}, + EnumDescriptorProto: desc, + parent: parent, + index: index, + } + if parent == nil { + ed.path = fmt.Sprintf("%d,%d", enumPath, index) + } else { + ed.path = fmt.Sprintf("%s,%d,%d", parent.path, messageEnumPath, index) + } + return ed +} + +// Return a slice of all the EnumDescriptors defined within this file +func wrapEnumDescriptors(file *FileDescriptor, descs []*Descriptor) []*EnumDescriptor { + sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10) + // Top-level enums. + for i, enum := range file.EnumType { + sl = append(sl, newEnumDescriptor(enum, nil, file, i)) + } + // Enums within messages. Enums within embedded messages appear in the outer-most message. + for _, nested := range descs { + for i, enum := range nested.EnumType { + sl = append(sl, newEnumDescriptor(enum, nested, file, i)) + } + } + return sl +} + +// Return a slice of all the top-level ExtensionDescriptors defined within this file. +func wrapExtensions(file *FileDescriptor) []*ExtensionDescriptor { + var sl []*ExtensionDescriptor + for _, field := range file.Extension { + sl = append(sl, &ExtensionDescriptor{common{file}, field, nil}) + } + return sl +} + +// Return a slice of all the types that are publicly imported into this file. +func wrapImported(file *FileDescriptor, g *Generator) (sl []*ImportedDescriptor) { + for _, index := range file.PublicDependency { + df := g.fileByName(file.Dependency[index]) + for _, d := range df.desc { + if d.GetOptions().GetMapEntry() { + continue + } + sl = append(sl, &ImportedDescriptor{common{file}, d}) + } + for _, e := range df.enum { + sl = append(sl, &ImportedDescriptor{common{file}, e}) + } + for _, ext := range df.ext { + sl = append(sl, &ImportedDescriptor{common{file}, ext}) + } + } + return +} + +func extractComments(file *FileDescriptor) { + file.comments = make(map[string]*descriptor.SourceCodeInfo_Location) + for _, loc := range file.GetSourceCodeInfo().GetLocation() { + if loc.LeadingComments == nil { + continue + } + var p []string + for _, n := range loc.Path { + p = append(p, strconv.Itoa(int(n))) + } + file.comments[strings.Join(p, ",")] = loc + } +} + +// BuildTypeNameMap builds the map from fully qualified type names to objects. +// The key names for the map come from the input data, which puts a period at the beginning. +// It should be called after SetPackageNames and before GenerateAllFiles. +func (g *Generator) BuildTypeNameMap() { + g.typeNameToObject = make(map[string]Object) + for _, f := range g.allFiles { + // The names in this loop are defined by the proto world, not us, so the + // package name may be empty. If so, the dotted package name of X will + // be ".X"; otherwise it will be ".pkg.X". + dottedPkg := "." + f.GetPackage() + if dottedPkg != "." { + dottedPkg += "." + } + for _, enum := range f.enum { + name := dottedPkg + dottedSlice(enum.TypeName()) + g.typeNameToObject[name] = enum + } + for _, desc := range f.desc { + name := dottedPkg + dottedSlice(desc.TypeName()) + g.typeNameToObject[name] = desc + } + } +} + +// ObjectNamed, given a fully-qualified input type name as it appears in the input data, +// returns the descriptor for the message or enum with that name. +func (g *Generator) ObjectNamed(typeName string) Object { + o, ok := g.typeNameToObject[typeName] + if !ok { + g.Fail("can't find object with type", typeName) + } + return o +} + +// AnnotatedAtoms is a list of atoms (as consumed by P) that records the file name and proto AST path from which they originated. +type AnnotatedAtoms struct { + source string + path string + atoms []interface{} +} + +// Annotate records the file name and proto AST path of a list of atoms +// so that a later call to P can emit a link from each atom to its origin. +func Annotate(file *FileDescriptor, path string, atoms ...interface{}) *AnnotatedAtoms { + return &AnnotatedAtoms{source: *file.Name, path: path, atoms: atoms} +} + +// printAtom prints the (atomic, non-annotation) argument to the generated output. +func (g *Generator) printAtom(v interface{}) { + switch v := v.(type) { + case string: + g.WriteString(v) + case *string: + g.WriteString(*v) + case bool: + fmt.Fprint(g, v) + case *bool: + fmt.Fprint(g, *v) + case int: + fmt.Fprint(g, v) + case *int32: + fmt.Fprint(g, *v) + case *int64: + fmt.Fprint(g, *v) + case float64: + fmt.Fprint(g, v) + case *float64: + fmt.Fprint(g, *v) + case GoPackageName: + g.WriteString(string(v)) + case GoImportPath: + g.WriteString(strconv.Quote(string(v))) + default: + g.Fail(fmt.Sprintf("unknown type in printer: %T", v)) + } +} + +// P prints the arguments to the generated output. It handles strings and int32s, plus +// handling indirections because they may be *string, etc. Any inputs of type AnnotatedAtoms may emit +// annotations in a .meta file in addition to outputting the atoms themselves (if g.annotateCode +// is true). +func (g *Generator) P(str ...interface{}) { + if !g.writeOutput { + return + } + g.WriteString(g.indent) + for _, v := range str { + switch v := v.(type) { + case *AnnotatedAtoms: + begin := int32(g.Len()) + for _, v := range v.atoms { + g.printAtom(v) + } + if g.annotateCode { + end := int32(g.Len()) + var path []int32 + for _, token := range strings.Split(v.path, ",") { + val, err := strconv.ParseInt(token, 10, 32) + if err != nil { + g.Fail("could not parse proto AST path: ", err.Error()) + } + path = append(path, int32(val)) + } + g.annotations = append(g.annotations, &descriptor.GeneratedCodeInfo_Annotation{ + Path: path, + SourceFile: &v.source, + Begin: &begin, + End: &end, + }) + } + default: + g.printAtom(v) + } + } + g.WriteByte('\n') +} + +// addInitf stores the given statement to be printed inside the file's init function. +// The statement is given as a format specifier and arguments. +func (g *Generator) addInitf(stmt string, a ...interface{}) { + g.init = append(g.init, fmt.Sprintf(stmt, a...)) +} + +// In Indents the output one tab stop. +func (g *Generator) In() { g.indent += "\t" } + +// Out unindents the output one tab stop. +func (g *Generator) Out() { + if len(g.indent) > 0 { + g.indent = g.indent[1:] + } +} + +// GenerateAllFiles generates the output for all the files we're outputting. +func (g *Generator) GenerateAllFiles() { + // Initialize the plugins + for _, p := range plugins { + p.Init(g) + } + // Generate the output. The generator runs for every file, even the files + // that we don't generate output for, so that we can collate the full list + // of exported symbols to support public imports. + genFileMap := make(map[*FileDescriptor]bool, len(g.genFiles)) + for _, file := range g.genFiles { + genFileMap[file] = true + } + for _, file := range g.allFiles { + g.Reset() + g.annotations = nil + g.writeOutput = genFileMap[file] + g.generate(file) + if !g.writeOutput { + continue + } + fname := file.goFileName(g.pathType) + g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{ + Name: proto.String(fname), + Content: proto.String(g.String()), + }) + if g.annotateCode { + // Store the generated code annotations in text, as the protoc plugin protocol requires that + // strings contain valid UTF-8. + g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{ + Name: proto.String(file.goFileName(g.pathType) + ".meta"), + Content: proto.String(proto.CompactTextString(&descriptor.GeneratedCodeInfo{Annotation: g.annotations})), + }) + } + } +} + +// Run all the plugins associated with the file. +func (g *Generator) runPlugins(file *FileDescriptor) { + for _, p := range plugins { + p.Generate(file) + } +} + +// Fill the response protocol buffer with the generated output for all the files we're +// supposed to generate. +func (g *Generator) generate(file *FileDescriptor) { + g.file = file + g.usedPackages = make(map[GoImportPath]bool) + g.packageNames = make(map[GoImportPath]GoPackageName) + g.usedPackageNames = make(map[GoPackageName]bool) + g.addedImports = make(map[GoImportPath]bool) + for name := range globalPackageNames { + g.usedPackageNames[name] = true + } + + g.P("// This is a compile-time assertion to ensure that this generated file") + g.P("// is compatible with the proto package it is being compiled against.") + g.P("// A compilation error at this line likely means your copy of the") + g.P("// proto package needs to be updated.") + g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion, " // please upgrade the proto package") + g.P() + + for _, td := range g.file.imp { + g.generateImported(td) + } + for _, enum := range g.file.enum { + g.generateEnum(enum) + } + for _, desc := range g.file.desc { + // Don't generate virtual messages for maps. + if desc.GetOptions().GetMapEntry() { + continue + } + g.generateMessage(desc) + } + for _, ext := range g.file.ext { + g.generateExtension(ext) + } + g.generateInitFunction() + g.generateFileDescriptor(file) + + // Run the plugins before the imports so we know which imports are necessary. + g.runPlugins(file) + + // Generate header and imports last, though they appear first in the output. + rem := g.Buffer + remAnno := g.annotations + g.Buffer = new(bytes.Buffer) + g.annotations = nil + g.generateHeader() + g.generateImports() + if !g.writeOutput { + return + } + // Adjust the offsets for annotations displaced by the header and imports. + for _, anno := range remAnno { + *anno.Begin += int32(g.Len()) + *anno.End += int32(g.Len()) + g.annotations = append(g.annotations, anno) + } + g.Write(rem.Bytes()) + + // Reformat generated code and patch annotation locations. + fset := token.NewFileSet() + original := g.Bytes() + if g.annotateCode { + // make a copy independent of g; we'll need it after Reset. + original = append([]byte(nil), original...) + } + fileAST, err := parser.ParseFile(fset, "", original, parser.ParseComments) + if err != nil { + // Print out the bad code with line numbers. + // This should never happen in practice, but it can while changing generated code, + // so consider this a debugging aid. + var src bytes.Buffer + s := bufio.NewScanner(bytes.NewReader(original)) + for line := 1; s.Scan(); line++ { + fmt.Fprintf(&src, "%5d\t%s\n", line, s.Bytes()) + } + g.Fail("bad Go source code was generated:", err.Error(), "\n"+src.String()) + } + ast.SortImports(fset, fileAST) + g.Reset() + err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(g, fset, fileAST) + if err != nil { + g.Fail("generated Go source code could not be reformatted:", err.Error()) + } + if g.annotateCode { + m, err := remap.Compute(original, g.Bytes()) + if err != nil { + g.Fail("formatted generated Go source code could not be mapped back to the original code:", err.Error()) + } + for _, anno := range g.annotations { + new, ok := m.Find(int(*anno.Begin), int(*anno.End)) + if !ok { + g.Fail("span in formatted generated Go source code could not be mapped back to the original code") + } + *anno.Begin = int32(new.Pos) + *anno.End = int32(new.End) + } + } +} + +// Generate the header, including package definition +func (g *Generator) generateHeader() { + g.P("// Code generated by protoc-gen-go. DO NOT EDIT.") + if g.file.GetOptions().GetDeprecated() { + g.P("// ", g.file.Name, " is a deprecated file.") + } else { + g.P("// source: ", g.file.Name) + } + g.P() + g.PrintComments(strconv.Itoa(packagePath)) + g.P() + g.P("package ", g.file.packageName) + g.P() +} + +// deprecationComment is the standard comment added to deprecated +// messages, fields, enums, and enum values. +var deprecationComment = "// Deprecated: Do not use." + +// PrintComments prints any comments from the source .proto file. +// The path is a comma-separated list of integers. +// It returns an indication of whether any comments were printed. +// See descriptor.proto for its format. +func (g *Generator) PrintComments(path string) bool { + if !g.writeOutput { + return false + } + if c, ok := g.makeComments(path); ok { + g.P(c) + return true + } + return false +} + +// makeComments generates the comment string for the field, no "\n" at the end +func (g *Generator) makeComments(path string) (string, bool) { + loc, ok := g.file.comments[path] + if !ok { + return "", false + } + w := new(bytes.Buffer) + nl := "" + for _, line := range strings.Split(strings.TrimSuffix(loc.GetLeadingComments(), "\n"), "\n") { + fmt.Fprintf(w, "%s//%s", nl, line) + nl = "\n" + } + return w.String(), true +} + +func (g *Generator) fileByName(filename string) *FileDescriptor { + return g.allFilesByName[filename] +} + +// weak returns whether the ith import of the current file is a weak import. +func (g *Generator) weak(i int32) bool { + for _, j := range g.file.WeakDependency { + if j == i { + return true + } + } + return false +} + +// Generate the imports +func (g *Generator) generateImports() { + imports := make(map[GoImportPath]GoPackageName) + for i, s := range g.file.Dependency { + fd := g.fileByName(s) + importPath := fd.importPath + // Do not import our own package. + if importPath == g.file.importPath { + continue + } + // Do not import weak imports. + if g.weak(int32(i)) { + continue + } + // Do not import a package twice. + if _, ok := imports[importPath]; ok { + continue + } + // We need to import all the dependencies, even if we don't reference them, + // because other code and tools depend on having the full transitive closure + // of protocol buffer types in the binary. + packageName := g.GoPackageName(importPath) + if _, ok := g.usedPackages[importPath]; !ok { + packageName = "_" + } + imports[importPath] = packageName + } + for importPath := range g.addedImports { + imports[importPath] = g.GoPackageName(importPath) + } + // We almost always need a proto import. Rather than computing when we + // do, which is tricky when there's a plugin, just import it and + // reference it later. The same argument applies to the fmt and math packages. + g.P("import (") + g.P(g.Pkg["fmt"] + ` "fmt"`) + g.P(g.Pkg["math"] + ` "math"`) + g.P(g.Pkg["proto"]+" ", GoImportPath(g.ImportPrefix)+"github.com/golang/protobuf/proto") + for importPath, packageName := range imports { + g.P(packageName, " ", GoImportPath(g.ImportPrefix)+importPath) + } + g.P(")") + g.P() + // TODO: may need to worry about uniqueness across plugins + for _, p := range plugins { + p.GenerateImports(g.file) + g.P() + } + g.P("// Reference imports to suppress errors if they are not otherwise used.") + g.P("var _ = ", g.Pkg["proto"], ".Marshal") + g.P("var _ = ", g.Pkg["fmt"], ".Errorf") + g.P("var _ = ", g.Pkg["math"], ".Inf") + g.P() +} + +func (g *Generator) generateImported(id *ImportedDescriptor) { + df := id.o.File() + filename := *df.Name + if df.importPath == g.file.importPath { + // Don't generate type aliases for files in the same Go package as this one. + return + } + if !supportTypeAliases { + g.Fail(fmt.Sprintf("%s: public imports require at least go1.9", filename)) + } + g.usedPackages[df.importPath] = true + + for _, sym := range df.exported[id.o] { + sym.GenerateAlias(g, filename, g.GoPackageName(df.importPath)) + } + + g.P() +} + +// Generate the enum definitions for this EnumDescriptor. +func (g *Generator) generateEnum(enum *EnumDescriptor) { + // The full type name + typeName := enum.TypeName() + // The full type name, CamelCased. + ccTypeName := CamelCaseSlice(typeName) + ccPrefix := enum.prefix() + + deprecatedEnum := "" + if enum.GetOptions().GetDeprecated() { + deprecatedEnum = deprecationComment + } + g.PrintComments(enum.path) + g.P("type ", Annotate(enum.file, enum.path, ccTypeName), " int32", deprecatedEnum) + g.file.addExport(enum, enumSymbol{ccTypeName, enum.proto3()}) + g.P("const (") + for i, e := range enum.Value { + etorPath := fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i) + g.PrintComments(etorPath) + + deprecatedValue := "" + if e.GetOptions().GetDeprecated() { + deprecatedValue = deprecationComment + } + + name := ccPrefix + *e.Name + g.P(Annotate(enum.file, etorPath, name), " ", ccTypeName, " = ", e.Number, " ", deprecatedValue) + g.file.addExport(enum, constOrVarSymbol{name, "const", ccTypeName}) + } + g.P(")") + g.P() + g.P("var ", ccTypeName, "_name = map[int32]string{") + generated := make(map[int32]bool) // avoid duplicate values + for _, e := range enum.Value { + duplicate := "" + if _, present := generated[*e.Number]; present { + duplicate = "// Duplicate value: " + } + g.P(duplicate, e.Number, ": ", strconv.Quote(*e.Name), ",") + generated[*e.Number] = true + } + g.P("}") + g.P() + g.P("var ", ccTypeName, "_value = map[string]int32{") + for _, e := range enum.Value { + g.P(strconv.Quote(*e.Name), ": ", e.Number, ",") + } + g.P("}") + g.P() + + if !enum.proto3() { + g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {") + g.P("p := new(", ccTypeName, ")") + g.P("*p = x") + g.P("return p") + g.P("}") + g.P() + } + + g.P("func (x ", ccTypeName, ") String() string {") + g.P("return ", g.Pkg["proto"], ".EnumName(", ccTypeName, "_name, int32(x))") + g.P("}") + g.P() + + if !enum.proto3() { + g.P("func (x *", ccTypeName, ") UnmarshalJSON(data []byte) error {") + g.P("value, err := ", g.Pkg["proto"], ".UnmarshalJSONEnum(", ccTypeName, `_value, data, "`, ccTypeName, `")`) + g.P("if err != nil {") + g.P("return err") + g.P("}") + g.P("*x = ", ccTypeName, "(value)") + g.P("return nil") + g.P("}") + g.P() + } + + var indexes []string + for m := enum.parent; m != nil; m = m.parent { + // XXX: skip groups? + indexes = append([]string{strconv.Itoa(m.index)}, indexes...) + } + indexes = append(indexes, strconv.Itoa(enum.index)) + g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) {") + g.P("return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "}") + g.P("}") + g.P() + if enum.file.GetPackage() == "google.protobuf" && enum.GetName() == "NullValue" { + g.P("func (", ccTypeName, `) XXX_WellKnownType() string { return "`, enum.GetName(), `" }`) + g.P() + } + + g.generateEnumRegistration(enum) +} + +// The tag is a string like "varint,2,opt,name=fieldname,def=7" that +// identifies details of the field for the protocol buffer marshaling and unmarshaling +// code. The fields are: +// wire encoding +// protocol tag number +// opt,req,rep for optional, required, or repeated +// packed whether the encoding is "packed" (optional; repeated primitives only) +// name= the original declared name +// enum= the name of the enum type if it is an enum-typed field. +// proto3 if this field is in a proto3 message +// def= string representation of the default value, if any. +// The default value must be in a representation that can be used at run-time +// to generate the default value. Thus bools become 0 and 1, for instance. +func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptorProto, wiretype string) string { + optrepreq := "" + switch { + case isOptional(field): + optrepreq = "opt" + case isRequired(field): + optrepreq = "req" + case isRepeated(field): + optrepreq = "rep" + } + var defaultValue string + if dv := field.DefaultValue; dv != nil { // set means an explicit default + defaultValue = *dv + // Some types need tweaking. + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_BOOL: + if defaultValue == "true" { + defaultValue = "1" + } else { + defaultValue = "0" + } + case descriptor.FieldDescriptorProto_TYPE_STRING, + descriptor.FieldDescriptorProto_TYPE_BYTES: + // Nothing to do. Quoting is done for the whole tag. + case descriptor.FieldDescriptorProto_TYPE_ENUM: + // For enums we need to provide the integer constant. + obj := g.ObjectNamed(field.GetTypeName()) + if id, ok := obj.(*ImportedDescriptor); ok { + // It is an enum that was publicly imported. + // We need the underlying type. + obj = id.o + } + enum, ok := obj.(*EnumDescriptor) + if !ok { + log.Printf("obj is a %T", obj) + if id, ok := obj.(*ImportedDescriptor); ok { + log.Printf("id.o is a %T", id.o) + } + g.Fail("unknown enum type", CamelCaseSlice(obj.TypeName())) + } + defaultValue = enum.integerValueAsString(defaultValue) + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + if def := defaultValue; def != "inf" && def != "-inf" && def != "nan" { + if f, err := strconv.ParseFloat(defaultValue, 32); err == nil { + defaultValue = fmt.Sprint(float32(f)) + } + } + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + if def := defaultValue; def != "inf" && def != "-inf" && def != "nan" { + if f, err := strconv.ParseFloat(defaultValue, 64); err == nil { + defaultValue = fmt.Sprint(f) + } + } + } + defaultValue = ",def=" + defaultValue + } + enum := "" + if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM { + // We avoid using obj.GoPackageName(), because we want to use the + // original (proto-world) package name. + obj := g.ObjectNamed(field.GetTypeName()) + if id, ok := obj.(*ImportedDescriptor); ok { + obj = id.o + } + enum = ",enum=" + if pkg := obj.File().GetPackage(); pkg != "" { + enum += pkg + "." + } + enum += CamelCaseSlice(obj.TypeName()) + } + packed := "" + if (field.Options != nil && field.Options.GetPacked()) || + // Per https://developers.google.com/protocol-buffers/docs/proto3#simple: + // "In proto3, repeated fields of scalar numeric types use packed encoding by default." + (message.proto3() && (field.Options == nil || field.Options.Packed == nil) && + isRepeated(field) && isScalar(field)) { + packed = ",packed" + } + fieldName := field.GetName() + name := fieldName + if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP { + // We must use the type name for groups instead of + // the field name to preserve capitalization. + // type_name in FieldDescriptorProto is fully-qualified, + // but we only want the local part. + name = *field.TypeName + if i := strings.LastIndex(name, "."); i >= 0 { + name = name[i+1:] + } + } + if json := field.GetJsonName(); field.Extendee == nil && json != "" && json != name { + // TODO: escaping might be needed, in which case + // perhaps this should be in its own "json" tag. + name += ",json=" + json + } + name = ",name=" + name + if message.proto3() { + name += ",proto3" + } + oneof := "" + if field.OneofIndex != nil { + oneof = ",oneof" + } + return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s", + wiretype, + field.GetNumber(), + optrepreq, + packed, + name, + enum, + oneof, + defaultValue)) +} + +func needsStar(typ descriptor.FieldDescriptorProto_Type) bool { + switch typ { + case descriptor.FieldDescriptorProto_TYPE_GROUP: + return false + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + return false + case descriptor.FieldDescriptorProto_TYPE_BYTES: + return false + } + return true +} + +// TypeName is the printed name appropriate for an item. If the object is in the current file, +// TypeName drops the package name and underscores the rest. +// Otherwise the object is from another package; and the result is the underscored +// package name followed by the item name. +// The result always has an initial capital. +func (g *Generator) TypeName(obj Object) string { + return g.DefaultPackageName(obj) + CamelCaseSlice(obj.TypeName()) +} + +// GoType returns a string representing the type name, and the wire type +func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) { + // TODO: Options. + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + typ, wire = "float64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + typ, wire = "float32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_INT64: + typ, wire = "int64", "varint" + case descriptor.FieldDescriptorProto_TYPE_UINT64: + typ, wire = "uint64", "varint" + case descriptor.FieldDescriptorProto_TYPE_INT32: + typ, wire = "int32", "varint" + case descriptor.FieldDescriptorProto_TYPE_UINT32: + typ, wire = "uint32", "varint" + case descriptor.FieldDescriptorProto_TYPE_FIXED64: + typ, wire = "uint64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_FIXED32: + typ, wire = "uint32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_BOOL: + typ, wire = "bool", "varint" + case descriptor.FieldDescriptorProto_TYPE_STRING: + typ, wire = "string", "bytes" + case descriptor.FieldDescriptorProto_TYPE_GROUP: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = "*"+g.TypeName(desc), "group" + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = "*"+g.TypeName(desc), "bytes" + case descriptor.FieldDescriptorProto_TYPE_BYTES: + typ, wire = "[]byte", "bytes" + case descriptor.FieldDescriptorProto_TYPE_ENUM: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = g.TypeName(desc), "varint" + case descriptor.FieldDescriptorProto_TYPE_SFIXED32: + typ, wire = "int32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_SFIXED64: + typ, wire = "int64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_SINT32: + typ, wire = "int32", "zigzag32" + case descriptor.FieldDescriptorProto_TYPE_SINT64: + typ, wire = "int64", "zigzag64" + default: + g.Fail("unknown type for", field.GetName()) + } + if isRepeated(field) { + typ = "[]" + typ + } else if message != nil && message.proto3() { + return + } else if field.OneofIndex != nil && message != nil { + return + } else if needsStar(*field.Type) { + typ = "*" + typ + } + return +} + +func (g *Generator) RecordTypeUse(t string) { + if _, ok := g.typeNameToObject[t]; !ok { + return + } + importPath := g.ObjectNamed(t).GoImportPath() + if importPath == g.outputImportPath { + // Don't record use of objects in our package. + return + } + g.AddImport(importPath) + g.usedPackages[importPath] = true +} + +// Method names that may be generated. Fields with these names get an +// underscore appended. Any change to this set is a potential incompatible +// API change because it changes generated field names. +var methodNames = [...]string{ + "Reset", + "String", + "ProtoMessage", + "Marshal", + "Unmarshal", + "ExtensionRangeArray", + "ExtensionMap", + "Descriptor", +} + +// Names of messages in the `google.protobuf` package for which +// we will generate XXX_WellKnownType methods. +var wellKnownTypes = map[string]bool{ + "Any": true, + "Duration": true, + "Empty": true, + "Struct": true, + "Timestamp": true, + + "Value": true, + "ListValue": true, + "DoubleValue": true, + "FloatValue": true, + "Int64Value": true, + "UInt64Value": true, + "Int32Value": true, + "UInt32Value": true, + "BoolValue": true, + "StringValue": true, + "BytesValue": true, +} + +// getterDefault finds the default value for the field to return from a getter, +// regardless of if it's a built in default or explicit from the source. Returns e.g. "nil", `""`, "Default_MessageType_FieldName" +func (g *Generator) getterDefault(field *descriptor.FieldDescriptorProto, goMessageType string) string { + if isRepeated(field) { + return "nil" + } + if def := field.GetDefaultValue(); def != "" { + defaultConstant := g.defaultConstantName(goMessageType, field.GetName()) + if *field.Type != descriptor.FieldDescriptorProto_TYPE_BYTES { + return defaultConstant + } + return "append([]byte(nil), " + defaultConstant + "...)" + } + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_BOOL: + return "false" + case descriptor.FieldDescriptorProto_TYPE_STRING: + return `""` + case descriptor.FieldDescriptorProto_TYPE_GROUP, descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_BYTES: + return "nil" + case descriptor.FieldDescriptorProto_TYPE_ENUM: + obj := g.ObjectNamed(field.GetTypeName()) + var enum *EnumDescriptor + if id, ok := obj.(*ImportedDescriptor); ok { + // The enum type has been publicly imported. + enum, _ = id.o.(*EnumDescriptor) + } else { + enum, _ = obj.(*EnumDescriptor) + } + if enum == nil { + log.Printf("don't know how to generate getter for %s", field.GetName()) + return "nil" + } + if len(enum.Value) == 0 { + return "0 // empty enum" + } + first := enum.Value[0].GetName() + return g.DefaultPackageName(obj) + enum.prefix() + first + default: + return "0" + } +} + +// defaultConstantName builds the name of the default constant from the message +// type name and the untouched field name, e.g. "Default_MessageType_FieldName" +func (g *Generator) defaultConstantName(goMessageType, protoFieldName string) string { + return "Default_" + goMessageType + "_" + CamelCase(protoFieldName) +} + +// The different types of fields in a message and how to actually print them +// Most of the logic for generateMessage is in the methods of these types. +// +// Note that the content of the field is irrelevant, a simpleField can contain +// anything from a scalar to a group (which is just a message). +// +// Extension fields (and message sets) are however handled separately. +// +// simpleField - a field that is neiter weak nor oneof, possibly repeated +// oneofField - field containing list of subfields: +// - oneofSubField - a field within the oneof + +// msgCtx contains the context for the generator functions. +type msgCtx struct { + goName string // Go struct name of the message, e.g. MessageName + message *Descriptor // The descriptor for the message +} + +// fieldCommon contains data common to all types of fields. +type fieldCommon struct { + goName string // Go name of field, e.g. "FieldName" or "Descriptor_" + protoName string // Name of field in proto language, e.g. "field_name" or "descriptor" + getterName string // Name of the getter, e.g. "GetFieldName" or "GetDescriptor_" + goType string // The Go type as a string, e.g. "*int32" or "*OtherMessage" + tags string // The tag string/annotation for the type, e.g. `protobuf:"varint,8,opt,name=region_id,json=regionId"` + fullPath string // The full path of the field as used by Annotate etc, e.g. "4,0,2,0" +} + +// getProtoName gets the proto name of a field, e.g. "field_name" or "descriptor". +func (f *fieldCommon) getProtoName() string { + return f.protoName +} + +// getGoType returns the go type of the field as a string, e.g. "*int32". +func (f *fieldCommon) getGoType() string { + return f.goType +} + +// simpleField is not weak, not a oneof, not an extension. Can be required, optional or repeated. +type simpleField struct { + fieldCommon + protoTypeName string // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration" + protoType descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64 + deprecated string // Deprecation comment, if any, e.g. "// Deprecated: Do not use." + getterDef string // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName" + protoDef string // Default value as defined in the proto file, e.g "yoshi" or "5" + comment string // The full comment for the field, e.g. "// Useful information" +} + +// decl prints the declaration of the field in the struct (if any). +func (f *simpleField) decl(g *Generator, mc *msgCtx) { + g.P(f.comment, Annotate(mc.message.file, f.fullPath, f.goName), "\t", f.goType, "\t`", f.tags, "`", f.deprecated) +} + +// getter prints the getter for the field. +func (f *simpleField) getter(g *Generator, mc *msgCtx) { + star := "" + tname := f.goType + if needsStar(f.protoType) && tname[0] == '*' { + tname = tname[1:] + star = "*" + } + if f.deprecated != "" { + g.P(f.deprecated) + } + g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, f.fullPath, f.getterName), "() "+tname+" {") + if f.getterDef == "nil" { // Simpler getter + g.P("if m != nil {") + g.P("return m." + f.goName) + g.P("}") + g.P("return nil") + g.P("}") + g.P() + return + } + if mc.message.proto3() { + g.P("if m != nil {") + } else { + g.P("if m != nil && m." + f.goName + " != nil {") + } + g.P("return " + star + "m." + f.goName) + g.P("}") + g.P("return ", f.getterDef) + g.P("}") + g.P() +} + +// setter prints the setter method of the field. +func (f *simpleField) setter(g *Generator, mc *msgCtx) { + // No setter for regular fields yet +} + +// getProtoDef returns the default value explicitly stated in the proto file, e.g "yoshi" or "5". +func (f *simpleField) getProtoDef() string { + return f.protoDef +} + +// getProtoTypeName returns the protobuf type name for the field as returned by field.GetTypeName(), e.g. ".google.protobuf.Duration". +func (f *simpleField) getProtoTypeName() string { + return f.protoTypeName +} + +// getProtoType returns the *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64. +func (f *simpleField) getProtoType() descriptor.FieldDescriptorProto_Type { + return f.protoType +} + +// oneofSubFields are kept slize held by each oneofField. They do not appear in the top level slize of fields for the message. +type oneofSubField struct { + fieldCommon + protoTypeName string // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration" + protoType descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64 + oneofTypeName string // Type name of the enclosing struct, e.g. "MessageName_FieldName" + fieldNumber int // Actual field number, as defined in proto, e.g. 12 + getterDef string // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName" + protoDef string // Default value as defined in the proto file, e.g "yoshi" or "5" + deprecated string // Deprecation comment, if any. +} + +// typedNil prints a nil casted to the pointer to this field. +// - for XXX_OneofWrappers +func (f *oneofSubField) typedNil(g *Generator) { + g.P("(*", f.oneofTypeName, ")(nil),") +} + +// getProtoDef returns the default value explicitly stated in the proto file, e.g "yoshi" or "5". +func (f *oneofSubField) getProtoDef() string { + return f.protoDef +} + +// getProtoTypeName returns the protobuf type name for the field as returned by field.GetTypeName(), e.g. ".google.protobuf.Duration". +func (f *oneofSubField) getProtoTypeName() string { + return f.protoTypeName +} + +// getProtoType returns the *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64. +func (f *oneofSubField) getProtoType() descriptor.FieldDescriptorProto_Type { + return f.protoType +} + +// oneofField represents the oneof on top level. +// The alternative fields within the oneof are represented by oneofSubField. +type oneofField struct { + fieldCommon + subFields []*oneofSubField // All the possible oneof fields + comment string // The full comment for the field, e.g. "// Types that are valid to be assigned to MyOneof:\n\\" +} + +// decl prints the declaration of the field in the struct (if any). +func (f *oneofField) decl(g *Generator, mc *msgCtx) { + comment := f.comment + for _, sf := range f.subFields { + comment += "//\t*" + sf.oneofTypeName + "\n" + } + g.P(comment, Annotate(mc.message.file, f.fullPath, f.goName), " ", f.goType, " `", f.tags, "`") +} + +// getter for a oneof field will print additional discriminators and interfaces for the oneof, +// also it prints all the getters for the sub fields. +func (f *oneofField) getter(g *Generator, mc *msgCtx) { + // The discriminator type + g.P("type ", f.goType, " interface {") + g.P(f.goType, "()") + g.P("}") + g.P() + // The subField types, fulfilling the discriminator type contract + for _, sf := range f.subFields { + g.P("type ", Annotate(mc.message.file, sf.fullPath, sf.oneofTypeName), " struct {") + g.P(Annotate(mc.message.file, sf.fullPath, sf.goName), " ", sf.goType, " `", sf.tags, "`") + g.P("}") + g.P() + } + for _, sf := range f.subFields { + g.P("func (*", sf.oneofTypeName, ") ", f.goType, "() {}") + g.P() + } + // Getter for the oneof field + g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, f.fullPath, f.getterName), "() ", f.goType, " {") + g.P("if m != nil { return m.", f.goName, " }") + g.P("return nil") + g.P("}") + g.P() + // Getters for each oneof + for _, sf := range f.subFields { + if sf.deprecated != "" { + g.P(sf.deprecated) + } + g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, sf.fullPath, sf.getterName), "() "+sf.goType+" {") + g.P("if x, ok := m.", f.getterName, "().(*", sf.oneofTypeName, "); ok {") + g.P("return x.", sf.goName) + g.P("}") + g.P("return ", sf.getterDef) + g.P("}") + g.P() + } +} + +// setter prints the setter method of the field. +func (f *oneofField) setter(g *Generator, mc *msgCtx) { + // No setters for oneof yet +} + +// topLevelField interface implemented by all types of fields on the top level (not oneofSubField). +type topLevelField interface { + decl(g *Generator, mc *msgCtx) // print declaration within the struct + getter(g *Generator, mc *msgCtx) // print getter + setter(g *Generator, mc *msgCtx) // print setter if applicable +} + +// defField interface implemented by all types of fields that can have defaults (not oneofField, but instead oneofSubField). +type defField interface { + getProtoDef() string // default value explicitly stated in the proto file, e.g "yoshi" or "5" + getProtoName() string // proto name of a field, e.g. "field_name" or "descriptor" + getGoType() string // go type of the field as a string, e.g. "*int32" + getProtoTypeName() string // protobuf type name for the field, e.g. ".google.protobuf.Duration" + getProtoType() descriptor.FieldDescriptorProto_Type // *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64 +} + +// generateDefaultConstants adds constants for default values if needed, which is only if the default value is. +// explicit in the proto. +func (g *Generator) generateDefaultConstants(mc *msgCtx, topLevelFields []topLevelField) { + // Collect fields that can have defaults + dFields := []defField{} + for _, pf := range topLevelFields { + if f, ok := pf.(*oneofField); ok { + for _, osf := range f.subFields { + dFields = append(dFields, osf) + } + continue + } + dFields = append(dFields, pf.(defField)) + } + for _, df := range dFields { + def := df.getProtoDef() + if def == "" { + continue + } + fieldname := g.defaultConstantName(mc.goName, df.getProtoName()) + typename := df.getGoType() + if typename[0] == '*' { + typename = typename[1:] + } + kind := "const " + switch { + case typename == "bool": + case typename == "string": + def = strconv.Quote(def) + case typename == "[]byte": + def = "[]byte(" + strconv.Quote(unescape(def)) + ")" + kind = "var " + case def == "inf", def == "-inf", def == "nan": + // These names are known to, and defined by, the protocol language. + switch def { + case "inf": + def = "math.Inf(1)" + case "-inf": + def = "math.Inf(-1)" + case "nan": + def = "math.NaN()" + } + if df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_FLOAT { + def = "float32(" + def + ")" + } + kind = "var " + case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_FLOAT: + if f, err := strconv.ParseFloat(def, 32); err == nil { + def = fmt.Sprint(float32(f)) + } + case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_DOUBLE: + if f, err := strconv.ParseFloat(def, 64); err == nil { + def = fmt.Sprint(f) + } + case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_ENUM: + // Must be an enum. Need to construct the prefixed name. + obj := g.ObjectNamed(df.getProtoTypeName()) + var enum *EnumDescriptor + if id, ok := obj.(*ImportedDescriptor); ok { + // The enum type has been publicly imported. + enum, _ = id.o.(*EnumDescriptor) + } else { + enum, _ = obj.(*EnumDescriptor) + } + if enum == nil { + log.Printf("don't know how to generate constant for %s", fieldname) + continue + } + def = g.DefaultPackageName(obj) + enum.prefix() + def + } + g.P(kind, fieldname, " ", typename, " = ", def) + g.file.addExport(mc.message, constOrVarSymbol{fieldname, kind, ""}) + } + g.P() +} + +// generateInternalStructFields just adds the XXX_ fields to the message struct. +func (g *Generator) generateInternalStructFields(mc *msgCtx, topLevelFields []topLevelField) { + g.P("XXX_NoUnkeyedLiteral\tstruct{} `json:\"-\"`") // prevent unkeyed struct literals + if len(mc.message.ExtensionRange) > 0 { + messageset := "" + if opts := mc.message.Options; opts != nil && opts.GetMessageSetWireFormat() { + messageset = "protobuf_messageset:\"1\" " + } + g.P(g.Pkg["proto"], ".XXX_InternalExtensions `", messageset, "json:\"-\"`") + } + g.P("XXX_unrecognized\t[]byte `json:\"-\"`") + g.P("XXX_sizecache\tint32 `json:\"-\"`") + +} + +// generateOneofFuncs adds all the utility functions for oneof, including marshalling, unmarshalling and sizer. +func (g *Generator) generateOneofFuncs(mc *msgCtx, topLevelFields []topLevelField) { + ofields := []*oneofField{} + for _, f := range topLevelFields { + if o, ok := f.(*oneofField); ok { + ofields = append(ofields, o) + } + } + if len(ofields) == 0 { + return + } + + // OneofFuncs + g.P("// XXX_OneofWrappers is for the internal use of the proto package.") + g.P("func (*", mc.goName, ") XXX_OneofWrappers() []interface{} {") + g.P("return []interface{}{") + for _, of := range ofields { + for _, sf := range of.subFields { + sf.typedNil(g) + } + } + g.P("}") + g.P("}") + g.P() +} + +// generateMessageStruct adds the actual struct with it's members (but not methods) to the output. +func (g *Generator) generateMessageStruct(mc *msgCtx, topLevelFields []topLevelField) { + comments := g.PrintComments(mc.message.path) + + // Guarantee deprecation comments appear after user-provided comments. + if mc.message.GetOptions().GetDeprecated() { + if comments { + // Convention: Separate deprecation comments from original + // comments with an empty line. + g.P("//") + } + g.P(deprecationComment) + } + + g.P("type ", Annotate(mc.message.file, mc.message.path, mc.goName), " struct {") + for _, pf := range topLevelFields { + pf.decl(g, mc) + } + g.generateInternalStructFields(mc, topLevelFields) + g.P("}") +} + +// generateGetters adds getters for all fields, including oneofs and weak fields when applicable. +func (g *Generator) generateGetters(mc *msgCtx, topLevelFields []topLevelField) { + for _, pf := range topLevelFields { + pf.getter(g, mc) + } +} + +// generateSetters add setters for all fields, including oneofs and weak fields when applicable. +func (g *Generator) generateSetters(mc *msgCtx, topLevelFields []topLevelField) { + for _, pf := range topLevelFields { + pf.setter(g, mc) + } +} + +// generateCommonMethods adds methods to the message that are not on a per field basis. +func (g *Generator) generateCommonMethods(mc *msgCtx) { + // Reset, String and ProtoMessage methods. + g.P("func (m *", mc.goName, ") Reset() { *m = ", mc.goName, "{} }") + g.P("func (m *", mc.goName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }") + g.P("func (*", mc.goName, ") ProtoMessage() {}") + var indexes []string + for m := mc.message; m != nil; m = m.parent { + indexes = append([]string{strconv.Itoa(m.index)}, indexes...) + } + g.P("func (*", mc.goName, ") Descriptor() ([]byte, []int) {") + g.P("return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "}") + g.P("}") + g.P() + // TODO: Revisit the decision to use a XXX_WellKnownType method + // if we change proto.MessageName to work with multiple equivalents. + if mc.message.file.GetPackage() == "google.protobuf" && wellKnownTypes[mc.message.GetName()] { + g.P("func (*", mc.goName, `) XXX_WellKnownType() string { return "`, mc.message.GetName(), `" }`) + g.P() + } + + // Extension support methods + if len(mc.message.ExtensionRange) > 0 { + g.P() + g.P("var extRange_", mc.goName, " = []", g.Pkg["proto"], ".ExtensionRange{") + for _, r := range mc.message.ExtensionRange { + end := fmt.Sprint(*r.End - 1) // make range inclusive on both ends + g.P("{Start: ", r.Start, ", End: ", end, "},") + } + g.P("}") + g.P("func (*", mc.goName, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange {") + g.P("return extRange_", mc.goName) + g.P("}") + g.P() + } + + // TODO: It does not scale to keep adding another method for every + // operation on protos that we want to switch over to using the + // table-driven approach. Instead, we should only add a single method + // that allows getting access to the *InternalMessageInfo struct and then + // calling Unmarshal, Marshal, Merge, Size, and Discard directly on that. + + // Wrapper for table-driven marshaling and unmarshaling. + g.P("func (m *", mc.goName, ") XXX_Unmarshal(b []byte) error {") + g.P("return xxx_messageInfo_", mc.goName, ".Unmarshal(m, b)") + g.P("}") + + g.P("func (m *", mc.goName, ") XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {") + g.P("return xxx_messageInfo_", mc.goName, ".Marshal(b, m, deterministic)") + g.P("}") + + g.P("func (m *", mc.goName, ") XXX_Merge(src ", g.Pkg["proto"], ".Message) {") + g.P("xxx_messageInfo_", mc.goName, ".Merge(m, src)") + g.P("}") + + g.P("func (m *", mc.goName, ") XXX_Size() int {") // avoid name clash with "Size" field in some message + g.P("return xxx_messageInfo_", mc.goName, ".Size(m)") + g.P("}") + + g.P("func (m *", mc.goName, ") XXX_DiscardUnknown() {") + g.P("xxx_messageInfo_", mc.goName, ".DiscardUnknown(m)") + g.P("}") + + g.P("var xxx_messageInfo_", mc.goName, " ", g.Pkg["proto"], ".InternalMessageInfo") + g.P() +} + +// Generate the type, methods and default constant definitions for this Descriptor. +func (g *Generator) generateMessage(message *Descriptor) { + topLevelFields := []topLevelField{} + oFields := make(map[int32]*oneofField) + // The full type name + typeName := message.TypeName() + // The full type name, CamelCased. + goTypeName := CamelCaseSlice(typeName) + + usedNames := make(map[string]bool) + for _, n := range methodNames { + usedNames[n] = true + } + + // allocNames finds a conflict-free variation of the given strings, + // consistently mutating their suffixes. + // It returns the same number of strings. + allocNames := func(ns ...string) []string { + Loop: + for { + for _, n := range ns { + if usedNames[n] { + for i := range ns { + ns[i] += "_" + } + continue Loop + } + } + for _, n := range ns { + usedNames[n] = true + } + return ns + } + } + + mapFieldTypes := make(map[*descriptor.FieldDescriptorProto]string) // keep track of the map fields to be added later + + // Build a structure more suitable for generating the text in one pass + for i, field := range message.Field { + // Allocate the getter and the field at the same time so name + // collisions create field/method consistent names. + // TODO: This allocation occurs based on the order of the fields + // in the proto file, meaning that a change in the field + // ordering can change generated Method/Field names. + base := CamelCase(*field.Name) + ns := allocNames(base, "Get"+base) + fieldName, fieldGetterName := ns[0], ns[1] + typename, wiretype := g.GoType(message, field) + jsonName := *field.Name + tag := fmt.Sprintf("protobuf:%s json:%q", g.goTag(message, field, wiretype), jsonName+",omitempty") + + oneof := field.OneofIndex != nil + if oneof && oFields[*field.OneofIndex] == nil { + odp := message.OneofDecl[int(*field.OneofIndex)] + base := CamelCase(odp.GetName()) + fname := allocNames(base)[0] + + // This is the first field of a oneof we haven't seen before. + // Generate the union field. + oneofFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageOneofPath, *field.OneofIndex) + c, ok := g.makeComments(oneofFullPath) + if ok { + c += "\n//\n" + } + c += "// Types that are valid to be assigned to " + fname + ":\n" + // Generate the rest of this comment later, + // when we've computed any disambiguation. + + dname := "is" + goTypeName + "_" + fname + tag := `protobuf_oneof:"` + odp.GetName() + `"` + of := oneofField{ + fieldCommon: fieldCommon{ + goName: fname, + getterName: "Get"+fname, + goType: dname, + tags: tag, + protoName: odp.GetName(), + fullPath: oneofFullPath, + }, + comment: c, + } + topLevelFields = append(topLevelFields, &of) + oFields[*field.OneofIndex] = &of + } + + if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE { + desc := g.ObjectNamed(field.GetTypeName()) + if d, ok := desc.(*Descriptor); ok && d.GetOptions().GetMapEntry() { + // Figure out the Go types and tags for the key and value types. + keyField, valField := d.Field[0], d.Field[1] + keyType, keyWire := g.GoType(d, keyField) + valType, valWire := g.GoType(d, valField) + keyTag, valTag := g.goTag(d, keyField, keyWire), g.goTag(d, valField, valWire) + + // We don't use stars, except for message-typed values. + // Message and enum types are the only two possibly foreign types used in maps, + // so record their use. They are not permitted as map keys. + keyType = strings.TrimPrefix(keyType, "*") + switch *valField.Type { + case descriptor.FieldDescriptorProto_TYPE_ENUM: + valType = strings.TrimPrefix(valType, "*") + g.RecordTypeUse(valField.GetTypeName()) + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + g.RecordTypeUse(valField.GetTypeName()) + default: + valType = strings.TrimPrefix(valType, "*") + } + + typename = fmt.Sprintf("map[%s]%s", keyType, valType) + mapFieldTypes[field] = typename // record for the getter generation + + tag += fmt.Sprintf(" protobuf_key:%s protobuf_val:%s", keyTag, valTag) + } + } + + fieldDeprecated := "" + if field.GetOptions().GetDeprecated() { + fieldDeprecated = deprecationComment + } + + dvalue := g.getterDefault(field, goTypeName) + if oneof { + tname := goTypeName + "_" + fieldName + // It is possible for this to collide with a message or enum + // nested in this message. Check for collisions. + for { + ok := true + for _, desc := range message.nested { + if CamelCaseSlice(desc.TypeName()) == tname { + ok = false + break + } + } + for _, enum := range message.enums { + if CamelCaseSlice(enum.TypeName()) == tname { + ok = false + break + } + } + if !ok { + tname += "_" + continue + } + break + } + + oneofField := oFields[*field.OneofIndex] + tag := "protobuf:" + g.goTag(message, field, wiretype) + sf := oneofSubField{ + fieldCommon: fieldCommon{ + goName: fieldName, + getterName: fieldGetterName, + goType: typename, + tags: tag, + protoName: field.GetName(), + fullPath: fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i), + }, + protoTypeName: field.GetTypeName(), + fieldNumber: int(*field.Number), + protoType: *field.Type, + getterDef: dvalue, + protoDef: field.GetDefaultValue(), + oneofTypeName: tname, + deprecated: fieldDeprecated, + } + oneofField.subFields = append(oneofField.subFields, &sf) + g.RecordTypeUse(field.GetTypeName()) + continue + } + + fieldFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i) + c, ok := g.makeComments(fieldFullPath) + if ok { + c += "\n" + } + rf := simpleField{ + fieldCommon: fieldCommon{ + goName: fieldName, + getterName: fieldGetterName, + goType: typename, + tags: tag, + protoName: field.GetName(), + fullPath: fieldFullPath, + }, + protoTypeName: field.GetTypeName(), + protoType: *field.Type, + deprecated: fieldDeprecated, + getterDef: dvalue, + protoDef: field.GetDefaultValue(), + comment: c, + } + var pf topLevelField = &rf + + topLevelFields = append(topLevelFields, pf) + g.RecordTypeUse(field.GetTypeName()) + } + + mc := &msgCtx{ + goName: goTypeName, + message: message, + } + + g.generateMessageStruct(mc, topLevelFields) + g.P() + g.generateCommonMethods(mc) + g.P() + g.generateDefaultConstants(mc, topLevelFields) + g.P() + g.generateGetters(mc, topLevelFields) + g.P() + g.generateSetters(mc, topLevelFields) + g.P() + g.generateOneofFuncs(mc, topLevelFields) + g.P() + + var oneofTypes []string + for _, f := range topLevelFields { + if of, ok := f.(*oneofField); ok { + for _, osf := range of.subFields { + oneofTypes = append(oneofTypes, osf.oneofTypeName) + } + } + } + + opts := message.Options + ms := &messageSymbol{ + sym: goTypeName, + hasExtensions: len(message.ExtensionRange) > 0, + isMessageSet: opts != nil && opts.GetMessageSetWireFormat(), + oneofTypes: oneofTypes, + } + g.file.addExport(message, ms) + + for _, ext := range message.ext { + g.generateExtension(ext) + } + + fullName := strings.Join(message.TypeName(), ".") + if g.file.Package != nil { + fullName = *g.file.Package + "." + fullName + } + + g.addInitf("%s.RegisterType((*%s)(nil), %q)", g.Pkg["proto"], goTypeName, fullName) + // Register types for native map types. + for _, k := range mapFieldKeys(mapFieldTypes) { + fullName := strings.TrimPrefix(*k.TypeName, ".") + g.addInitf("%s.RegisterMapType((%s)(nil), %q)", g.Pkg["proto"], mapFieldTypes[k], fullName) + } + +} + +type byTypeName []*descriptor.FieldDescriptorProto + +func (a byTypeName) Len() int { return len(a) } +func (a byTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byTypeName) Less(i, j int) bool { return *a[i].TypeName < *a[j].TypeName } + +// mapFieldKeys returns the keys of m in a consistent order. +func mapFieldKeys(m map[*descriptor.FieldDescriptorProto]string) []*descriptor.FieldDescriptorProto { + keys := make([]*descriptor.FieldDescriptorProto, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Sort(byTypeName(keys)) + return keys +} + +var escapeChars = [256]byte{ + 'a': '\a', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', 'v': '\v', '\\': '\\', '"': '"', '\'': '\'', '?': '?', +} + +// unescape reverses the "C" escaping that protoc does for default values of bytes fields. +// It is best effort in that it effectively ignores malformed input. Seemingly invalid escape +// sequences are conveyed, unmodified, into the decoded result. +func unescape(s string) string { + // NB: Sadly, we can't use strconv.Unquote because protoc will escape both + // single and double quotes, but strconv.Unquote only allows one or the + // other (based on actual surrounding quotes of its input argument). + + var out []byte + for len(s) > 0 { + // regular character, or too short to be valid escape + if s[0] != '\\' || len(s) < 2 { + out = append(out, s[0]) + s = s[1:] + } else if c := escapeChars[s[1]]; c != 0 { + // escape sequence + out = append(out, c) + s = s[2:] + } else if s[1] == 'x' || s[1] == 'X' { + // hex escape, e.g. "\x80 + if len(s) < 4 { + // too short to be valid + out = append(out, s[:2]...) + s = s[2:] + continue + } + v, err := strconv.ParseUint(s[2:4], 16, 8) + if err != nil { + out = append(out, s[:4]...) + } else { + out = append(out, byte(v)) + } + s = s[4:] + } else if '0' <= s[1] && s[1] <= '7' { + // octal escape, can vary from 1 to 3 octal digits; e.g., "\0" "\40" or "\164" + // so consume up to 2 more bytes or up to end-of-string + n := len(s[1:]) - len(strings.TrimLeft(s[1:], "01234567")) + if n > 3 { + n = 3 + } + v, err := strconv.ParseUint(s[1:1+n], 8, 8) + if err != nil { + out = append(out, s[:1+n]...) + } else { + out = append(out, byte(v)) + } + s = s[1+n:] + } else { + // bad escape, just propagate the slash as-is + out = append(out, s[0]) + s = s[1:] + } + } + + return string(out) +} + +func (g *Generator) generateExtension(ext *ExtensionDescriptor) { + ccTypeName := ext.DescName() + + extObj := g.ObjectNamed(*ext.Extendee) + var extDesc *Descriptor + if id, ok := extObj.(*ImportedDescriptor); ok { + // This is extending a publicly imported message. + // We need the underlying type for goTag. + extDesc = id.o.(*Descriptor) + } else { + extDesc = extObj.(*Descriptor) + } + extendedType := "*" + g.TypeName(extObj) // always use the original + field := ext.FieldDescriptorProto + fieldType, wireType := g.GoType(ext.parent, field) + tag := g.goTag(extDesc, field, wireType) + g.RecordTypeUse(*ext.Extendee) + if n := ext.FieldDescriptorProto.TypeName; n != nil { + // foreign extension type + g.RecordTypeUse(*n) + } + + typeName := ext.TypeName() + + // Special case for proto2 message sets: If this extension is extending + // proto2.bridge.MessageSet, and its final name component is "message_set_extension", + // then drop that last component. + // + // TODO: This should be implemented in the text formatter rather than the generator. + // In addition, the situation for when to apply this special case is implemented + // differently in other languages: + // https://github.com/google/protobuf/blob/aff10976/src/google/protobuf/text_format.cc#L1560 + if extDesc.GetOptions().GetMessageSetWireFormat() && typeName[len(typeName)-1] == "message_set_extension" { + typeName = typeName[:len(typeName)-1] + } + + // For text formatting, the package must be exactly what the .proto file declares, + // ignoring overrides such as the go_package option, and with no dot/underscore mapping. + extName := strings.Join(typeName, ".") + if g.file.Package != nil { + extName = *g.file.Package + "." + extName + } + + g.P("var ", ccTypeName, " = &", g.Pkg["proto"], ".ExtensionDesc{") + g.P("ExtendedType: (", extendedType, ")(nil),") + g.P("ExtensionType: (", fieldType, ")(nil),") + g.P("Field: ", field.Number, ",") + g.P(`Name: "`, extName, `",`) + g.P("Tag: ", tag, ",") + g.P(`Filename: "`, g.file.GetName(), `",`) + + g.P("}") + g.P() + + g.addInitf("%s.RegisterExtension(%s)", g.Pkg["proto"], ext.DescName()) + + g.file.addExport(ext, constOrVarSymbol{ccTypeName, "var", ""}) +} + +func (g *Generator) generateInitFunction() { + if len(g.init) == 0 { + return + } + g.P("func init() {") + for _, l := range g.init { + g.P(l) + } + g.P("}") + g.init = nil +} + +func (g *Generator) generateFileDescriptor(file *FileDescriptor) { + // Make a copy and trim source_code_info data. + // TODO: Trim this more when we know exactly what we need. + pb := proto.Clone(file.FileDescriptorProto).(*descriptor.FileDescriptorProto) + pb.SourceCodeInfo = nil + + b, err := proto.Marshal(pb) + if err != nil { + g.Fail(err.Error()) + } + + var buf bytes.Buffer + w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression) + w.Write(b) + w.Close() + b = buf.Bytes() + + v := file.VarName() + g.P() + g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }") + g.P("var ", v, " = []byte{") + g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto") + for len(b) > 0 { + n := 16 + if n > len(b) { + n = len(b) + } + + s := "" + for _, c := range b[:n] { + s += fmt.Sprintf("0x%02x,", c) + } + g.P(s) + + b = b[n:] + } + g.P("}") +} + +func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) { + // // We always print the full (proto-world) package name here. + pkg := enum.File().GetPackage() + if pkg != "" { + pkg += "." + } + // The full type name + typeName := enum.TypeName() + // The full type name, CamelCased. + ccTypeName := CamelCaseSlice(typeName) + g.addInitf("%s.RegisterEnum(%q, %[3]s_name, %[3]s_value)", g.Pkg["proto"], pkg+ccTypeName, ccTypeName) +} + +// And now lots of helper functions. + +// Is c an ASCII lower-case letter? +func isASCIILower(c byte) bool { + return 'a' <= c && c <= 'z' +} + +// Is c an ASCII digit? +func isASCIIDigit(c byte) bool { + return '0' <= c && c <= '9' +} + +// CamelCase returns the CamelCased name. +// If there is an interior underscore followed by a lower case letter, +// drop the underscore and convert the letter to upper case. +// There is a remote possibility of this rewrite causing a name collision, +// but it's so remote we're prepared to pretend it's nonexistent - since the +// C++ generator lowercases names, it's extremely unlikely to have two fields +// with different capitalizations. +// In short, _my_field_name_2 becomes XMyFieldName_2. +func CamelCase(s string) string { + if s == "" { + return "" + } + t := make([]byte, 0, 32) + i := 0 + if s[0] == '_' { + // Need a capital letter; drop the '_'. + t = append(t, 'X') + i++ + } + // Invariant: if the next letter is lower case, it must be converted + // to upper case. + // That is, we process a word at a time, where words are marked by _ or + // upper case letter. Digits are treated as words. + for ; i < len(s); i++ { + c := s[i] + if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) { + continue // Skip the underscore in s. + } + if isASCIIDigit(c) { + t = append(t, c) + continue + } + // Assume we have a letter now - if not, it's a bogus identifier. + // The next word is a sequence of characters that must start upper case. + if isASCIILower(c) { + c ^= ' ' // Make it a capital letter. + } + t = append(t, c) // Guaranteed not lower case. + // Accept lower case sequence that follows. + for i+1 < len(s) && isASCIILower(s[i+1]) { + i++ + t = append(t, s[i]) + } + } + return string(t) +} + +// CamelCaseSlice is like CamelCase, but the argument is a slice of strings to +// be joined with "_". +func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) } + +// dottedSlice turns a sliced name into a dotted name. +func dottedSlice(elem []string) string { return strings.Join(elem, ".") } + +// Is this field optional? +func isOptional(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL +} + +// Is this field required? +func isRequired(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED +} + +// Is this field repeated? +func isRepeated(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED +} + +// Is this field a scalar numeric type? +func isScalar(field *descriptor.FieldDescriptorProto) bool { + if field.Type == nil { + return false + } + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE, + descriptor.FieldDescriptorProto_TYPE_FLOAT, + descriptor.FieldDescriptorProto_TYPE_INT64, + descriptor.FieldDescriptorProto_TYPE_UINT64, + descriptor.FieldDescriptorProto_TYPE_INT32, + descriptor.FieldDescriptorProto_TYPE_FIXED64, + descriptor.FieldDescriptorProto_TYPE_FIXED32, + descriptor.FieldDescriptorProto_TYPE_BOOL, + descriptor.FieldDescriptorProto_TYPE_UINT32, + descriptor.FieldDescriptorProto_TYPE_ENUM, + descriptor.FieldDescriptorProto_TYPE_SFIXED32, + descriptor.FieldDescriptorProto_TYPE_SFIXED64, + descriptor.FieldDescriptorProto_TYPE_SINT32, + descriptor.FieldDescriptorProto_TYPE_SINT64: + return true + default: + return false + } +} + +// badToUnderscore is the mapping function used to generate Go names from package names, +// which can be dotted in the input .proto file. It replaces non-identifier characters such as +// dot or dash with underscore. +func badToUnderscore(r rune) rune { + if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { + return r + } + return '_' +} + +// baseName returns the last path element of the name, with the last dotted suffix removed. +func baseName(name string) string { + // First, find the last element + if i := strings.LastIndex(name, "/"); i >= 0 { + name = name[i+1:] + } + // Now drop the suffix + if i := strings.LastIndex(name, "."); i >= 0 { + name = name[0:i] + } + return name +} + +// The SourceCodeInfo message describes the location of elements of a parsed +// .proto file by way of a "path", which is a sequence of integers that +// describe the route from a FileDescriptorProto to the relevant submessage. +// The path alternates between a field number of a repeated field, and an index +// into that repeated field. The constants below define the field numbers that +// are used. +// +// See descriptor.proto for more information about this. +const ( + // tag numbers in FileDescriptorProto + packagePath = 2 // package + messagePath = 4 // message_type + enumPath = 5 // enum_type + // tag numbers in DescriptorProto + messageFieldPath = 2 // field + messageMessagePath = 3 // nested_type + messageEnumPath = 4 // enum_type + messageOneofPath = 8 // oneof_decl + // tag numbers in EnumDescriptorProto + enumValuePath = 2 // value +) + +var supportTypeAliases bool + +func init() { + for _, tag := range build.Default.ReleaseTags { + if tag == "go1.9" { + supportTypeAliases = true + return + } + } +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/generator/internal/remap/remap.go b/vendor/github.com/golang/protobuf/protoc-gen-go/generator/internal/remap/remap.go new file mode 100644 index 000000000..a9b61036c --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/generator/internal/remap/remap.go @@ -0,0 +1,117 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2017 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/* +Package remap handles tracking the locations of Go tokens in a source text +across a rewrite by the Go formatter. +*/ +package remap + +import ( + "fmt" + "go/scanner" + "go/token" +) + +// A Location represents a span of byte offsets in the source text. +type Location struct { + Pos, End int // End is exclusive +} + +// A Map represents a mapping between token locations in an input source text +// and locations in the correspnding output text. +type Map map[Location]Location + +// Find reports whether the specified span is recorded by m, and if so returns +// the new location it was mapped to. If the input span was not found, the +// returned location is the same as the input. +func (m Map) Find(pos, end int) (Location, bool) { + key := Location{ + Pos: pos, + End: end, + } + if loc, ok := m[key]; ok { + return loc, true + } + return key, false +} + +func (m Map) add(opos, oend, npos, nend int) { + m[Location{Pos: opos, End: oend}] = Location{Pos: npos, End: nend} +} + +// Compute constructs a location mapping from input to output. An error is +// reported if any of the tokens of output cannot be mapped. +func Compute(input, output []byte) (Map, error) { + itok := tokenize(input) + otok := tokenize(output) + if len(itok) != len(otok) { + return nil, fmt.Errorf("wrong number of tokens, %d ≠ %d", len(itok), len(otok)) + } + m := make(Map) + for i, ti := range itok { + to := otok[i] + if ti.Token != to.Token { + return nil, fmt.Errorf("token %d type mismatch: %s ≠ %s", i+1, ti, to) + } + m.add(ti.pos, ti.end, to.pos, to.end) + } + return m, nil +} + +// tokinfo records the span and type of a source token. +type tokinfo struct { + pos, end int + token.Token +} + +func tokenize(src []byte) []tokinfo { + fs := token.NewFileSet() + var s scanner.Scanner + s.Init(fs.AddFile("src", fs.Base(), len(src)), src, nil, scanner.ScanComments) + var info []tokinfo + for { + pos, next, lit := s.Scan() + switch next { + case token.SEMICOLON: + continue + } + info = append(info, tokinfo{ + pos: int(pos - 1), + end: int(pos + token.Pos(len(lit)) - 1), + Token: next, + }) + if next == token.EOF { + break + } + } + return info +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go b/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go new file mode 100644 index 000000000..61bfc10e0 --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go @@ -0,0 +1,369 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/compiler/plugin.proto + +/* +Package plugin_go is a generated protocol buffer package. + +It is generated from these files: + google/protobuf/compiler/plugin.proto + +It has these top-level messages: + Version + CodeGeneratorRequest + CodeGeneratorResponse +*/ +package plugin_go + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// The version number of protocol compiler. +type Version struct { + Major *int32 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"` + Minor *int32 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"` + Patch *int32 `protobuf:"varint,3,opt,name=patch" json:"patch,omitempty"` + // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + // be empty for mainline stable releases. + Suffix *string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Version) Reset() { *m = Version{} } +func (m *Version) String() string { return proto.CompactTextString(m) } +func (*Version) ProtoMessage() {} +func (*Version) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (m *Version) Unmarshal(b []byte) error { + return xxx_messageInfo_Version.Unmarshal(m, b) +} +func (m *Version) Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Version.Marshal(b, m, deterministic) +} +func (dst *Version) XXX_Merge(src proto.Message) { + xxx_messageInfo_Version.Merge(dst, src) +} +func (m *Version) XXX_Size() int { + return xxx_messageInfo_Version.Size(m) +} +func (m *Version) XXX_DiscardUnknown() { + xxx_messageInfo_Version.DiscardUnknown(m) +} + +var xxx_messageInfo_Version proto.InternalMessageInfo + +func (m *Version) GetMajor() int32 { + if m != nil && m.Major != nil { + return *m.Major + } + return 0 +} + +func (m *Version) GetMinor() int32 { + if m != nil && m.Minor != nil { + return *m.Minor + } + return 0 +} + +func (m *Version) GetPatch() int32 { + if m != nil && m.Patch != nil { + return *m.Patch + } + return 0 +} + +func (m *Version) GetSuffix() string { + if m != nil && m.Suffix != nil { + return *m.Suffix + } + return "" +} + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +type CodeGeneratorRequest struct { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate,json=fileToGenerate" json:"file_to_generate,omitempty"` + // The generator parameter passed on the command-line. + Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"` + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + // + // Type names of fields and extensions in the FileDescriptorProto are always + // fully qualified. + ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file,json=protoFile" json:"proto_file,omitempty"` + // The version number of protocol compiler. + CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion" json:"compiler_version,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CodeGeneratorRequest) Reset() { *m = CodeGeneratorRequest{} } +func (m *CodeGeneratorRequest) String() string { return proto.CompactTextString(m) } +func (*CodeGeneratorRequest) ProtoMessage() {} +func (*CodeGeneratorRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } +func (m *CodeGeneratorRequest) Unmarshal(b []byte) error { + return xxx_messageInfo_CodeGeneratorRequest.Unmarshal(m, b) +} +func (m *CodeGeneratorRequest) Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CodeGeneratorRequest.Marshal(b, m, deterministic) +} +func (dst *CodeGeneratorRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CodeGeneratorRequest.Merge(dst, src) +} +func (m *CodeGeneratorRequest) XXX_Size() int { + return xxx_messageInfo_CodeGeneratorRequest.Size(m) +} +func (m *CodeGeneratorRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CodeGeneratorRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CodeGeneratorRequest proto.InternalMessageInfo + +func (m *CodeGeneratorRequest) GetFileToGenerate() []string { + if m != nil { + return m.FileToGenerate + } + return nil +} + +func (m *CodeGeneratorRequest) GetParameter() string { + if m != nil && m.Parameter != nil { + return *m.Parameter + } + return "" +} + +func (m *CodeGeneratorRequest) GetProtoFile() []*google_protobuf.FileDescriptorProto { + if m != nil { + return m.ProtoFile + } + return nil +} + +func (m *CodeGeneratorRequest) GetCompilerVersion() *Version { + if m != nil { + return m.CompilerVersion + } + return nil +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +type CodeGeneratorResponse struct { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + File []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CodeGeneratorResponse) Reset() { *m = CodeGeneratorResponse{} } +func (m *CodeGeneratorResponse) String() string { return proto.CompactTextString(m) } +func (*CodeGeneratorResponse) ProtoMessage() {} +func (*CodeGeneratorResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } +func (m *CodeGeneratorResponse) Unmarshal(b []byte) error { + return xxx_messageInfo_CodeGeneratorResponse.Unmarshal(m, b) +} +func (m *CodeGeneratorResponse) Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CodeGeneratorResponse.Marshal(b, m, deterministic) +} +func (dst *CodeGeneratorResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CodeGeneratorResponse.Merge(dst, src) +} +func (m *CodeGeneratorResponse) XXX_Size() int { + return xxx_messageInfo_CodeGeneratorResponse.Size(m) +} +func (m *CodeGeneratorResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CodeGeneratorResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CodeGeneratorResponse proto.InternalMessageInfo + +func (m *CodeGeneratorResponse) GetError() string { + if m != nil && m.Error != nil { + return *m.Error + } + return "" +} + +func (m *CodeGeneratorResponse) GetFile() []*CodeGeneratorResponse_File { + if m != nil { + return m.File + } + return nil +} + +// Represents a single generated file. +type CodeGeneratorResponse_File struct { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point,json=insertionPoint" json:"insertion_point,omitempty"` + // The file contents. + Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CodeGeneratorResponse_File) Reset() { *m = CodeGeneratorResponse_File{} } +func (m *CodeGeneratorResponse_File) String() string { return proto.CompactTextString(m) } +func (*CodeGeneratorResponse_File) ProtoMessage() {} +func (*CodeGeneratorResponse_File) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} } +func (m *CodeGeneratorResponse_File) Unmarshal(b []byte) error { + return xxx_messageInfo_CodeGeneratorResponse_File.Unmarshal(m, b) +} +func (m *CodeGeneratorResponse_File) Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CodeGeneratorResponse_File.Marshal(b, m, deterministic) +} +func (dst *CodeGeneratorResponse_File) XXX_Merge(src proto.Message) { + xxx_messageInfo_CodeGeneratorResponse_File.Merge(dst, src) +} +func (m *CodeGeneratorResponse_File) XXX_Size() int { + return xxx_messageInfo_CodeGeneratorResponse_File.Size(m) +} +func (m *CodeGeneratorResponse_File) XXX_DiscardUnknown() { + xxx_messageInfo_CodeGeneratorResponse_File.DiscardUnknown(m) +} + +var xxx_messageInfo_CodeGeneratorResponse_File proto.InternalMessageInfo + +func (m *CodeGeneratorResponse_File) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *CodeGeneratorResponse_File) GetInsertionPoint() string { + if m != nil && m.InsertionPoint != nil { + return *m.InsertionPoint + } + return "" +} + +func (m *CodeGeneratorResponse_File) GetContent() string { + if m != nil && m.Content != nil { + return *m.Content + } + return "" +} + +func init() { + proto.RegisterType((*Version)(nil), "google.protobuf.compiler.Version") + proto.RegisterType((*CodeGeneratorRequest)(nil), "google.protobuf.compiler.CodeGeneratorRequest") + proto.RegisterType((*CodeGeneratorResponse)(nil), "google.protobuf.compiler.CodeGeneratorResponse") + proto.RegisterType((*CodeGeneratorResponse_File)(nil), "google.protobuf.compiler.CodeGeneratorResponse.File") +} + +func init() { proto.RegisterFile("google/protobuf/compiler/plugin.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 417 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xcf, 0x6a, 0x14, 0x41, + 0x10, 0xc6, 0x19, 0x77, 0x63, 0x98, 0x8a, 0x64, 0x43, 0x13, 0xa5, 0x09, 0x39, 0x8c, 0x8b, 0xe2, + 0x5c, 0x32, 0x0b, 0xc1, 0x8b, 0x78, 0x4b, 0x44, 0x3d, 0x78, 0x58, 0x1a, 0xf1, 0x20, 0xc8, 0x30, + 0x99, 0xd4, 0x74, 0x5a, 0x66, 0xba, 0xc6, 0xee, 0x1e, 0xf1, 0x49, 0x7d, 0x0f, 0xdf, 0x40, 0xfa, + 0xcf, 0x24, 0xb2, 0xb8, 0xa7, 0xee, 0xef, 0x57, 0xd5, 0xd5, 0x55, 0x1f, 0x05, 0x2f, 0x25, 0x91, + 0xec, 0x71, 0x33, 0x1a, 0x72, 0x74, 0x33, 0x75, 0x9b, 0x96, 0x86, 0x51, 0xf5, 0x68, 0x36, 0x63, + 0x3f, 0x49, 0xa5, 0xab, 0x10, 0x60, 0x3c, 0xa6, 0x55, 0x73, 0x5a, 0x35, 0xa7, 0x9d, 0x15, 0xbb, + 0x05, 0x6e, 0xd1, 0xb6, 0x46, 0x8d, 0x8e, 0x4c, 0xcc, 0x5e, 0xb7, 0x70, 0xf8, 0x05, 0x8d, 0x55, + 0xa4, 0xd9, 0x29, 0x1c, 0x0c, 0xcd, 0x77, 0x32, 0x3c, 0x2b, 0xb2, 0xf2, 0x40, 0x44, 0x11, 0xa8, + 0xd2, 0x64, 0xf8, 0xa3, 0x44, 0xbd, 0xf0, 0x74, 0x6c, 0x5c, 0x7b, 0xc7, 0x17, 0x91, 0x06, 0xc1, + 0x9e, 0xc1, 0x63, 0x3b, 0x75, 0x9d, 0xfa, 0xc5, 0x97, 0x45, 0x56, 0xe6, 0x22, 0xa9, 0xf5, 0x9f, + 0x0c, 0x4e, 0xaf, 0xe9, 0x16, 0x3f, 0xa0, 0x46, 0xd3, 0x38, 0x32, 0x02, 0x7f, 0x4c, 0x68, 0x1d, + 0x2b, 0xe1, 0xa4, 0x53, 0x3d, 0xd6, 0x8e, 0x6a, 0x19, 0x63, 0xc8, 0xb3, 0x62, 0x51, 0xe6, 0xe2, + 0xd8, 0xf3, 0xcf, 0x94, 0x5e, 0x20, 0x3b, 0x87, 0x7c, 0x6c, 0x4c, 0x33, 0xa0, 0xc3, 0xd8, 0x4a, + 0x2e, 0x1e, 0x00, 0xbb, 0x06, 0x08, 0xe3, 0xd4, 0xfe, 0x15, 0x5f, 0x15, 0x8b, 0xf2, 0xe8, 0xf2, + 0x45, 0xb5, 0x6b, 0xcb, 0x7b, 0xd5, 0xe3, 0xbb, 0x7b, 0x03, 0xb6, 0x1e, 0x8b, 0x3c, 0x44, 0x7d, + 0x84, 0x7d, 0x82, 0x93, 0xd9, 0xb8, 0xfa, 0x67, 0xf4, 0x24, 0x8c, 0x77, 0x74, 0xf9, 0xbc, 0xda, + 0xe7, 0x70, 0x95, 0xcc, 0x13, 0xab, 0x99, 0x24, 0xb0, 0xfe, 0x9d, 0xc1, 0xd3, 0x9d, 0x99, 0xed, + 0x48, 0xda, 0xa2, 0xf7, 0x0e, 0x8d, 0x49, 0x3e, 0xe7, 0x22, 0x0a, 0xf6, 0x11, 0x96, 0xff, 0x34, + 0xff, 0x7a, 0xff, 0x8f, 0xff, 0x2d, 0x1a, 0x66, 0x13, 0xa1, 0xc2, 0xd9, 0x37, 0x58, 0x86, 0x79, + 0x18, 0x2c, 0x75, 0x33, 0x60, 0xfa, 0x26, 0xdc, 0xd9, 0x2b, 0x58, 0x29, 0x6d, 0xd1, 0x38, 0x45, + 0xba, 0x1e, 0x49, 0x69, 0x97, 0xcc, 0x3c, 0xbe, 0xc7, 0x5b, 0x4f, 0x19, 0x87, 0xc3, 0x96, 0xb4, + 0x43, 0xed, 0xf8, 0x2a, 0x24, 0xcc, 0xf2, 0x4a, 0xc2, 0x79, 0x4b, 0xc3, 0xde, 0xfe, 0xae, 0x9e, + 0x6c, 0xc3, 0x6e, 0x06, 0x7b, 0xed, 0xd7, 0x37, 0x52, 0xb9, 0xbb, 0xe9, 0xc6, 0x87, 0x37, 0x92, + 0xfa, 0x46, 0xcb, 0x87, 0x65, 0x0c, 0x97, 0xf6, 0x42, 0xa2, 0xbe, 0x90, 0x94, 0x56, 0xfa, 0x6d, + 0x3c, 0x6a, 0x49, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x15, 0x40, 0xc5, 0xfe, 0x02, 0x00, + 0x00, +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.golden b/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.golden new file mode 100644 index 000000000..8953d0ff8 --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.golden @@ -0,0 +1,83 @@ +// Code generated by protoc-gen-go. +// source: google/protobuf/compiler/plugin.proto +// DO NOT EDIT! + +package google_protobuf_compiler + +import proto "github.com/golang/protobuf/proto" +import "math" +import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference proto and math imports to suppress error if they are not otherwise used. +var _ = proto.GetString +var _ = math.Inf + +type CodeGeneratorRequest struct { + FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate" json:"file_to_generate,omitempty"` + Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"` + ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file" json:"proto_file,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (this *CodeGeneratorRequest) Reset() { *this = CodeGeneratorRequest{} } +func (this *CodeGeneratorRequest) String() string { return proto.CompactTextString(this) } +func (*CodeGeneratorRequest) ProtoMessage() {} + +func (this *CodeGeneratorRequest) GetParameter() string { + if this != nil && this.Parameter != nil { + return *this.Parameter + } + return "" +} + +type CodeGeneratorResponse struct { + Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + File []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (this *CodeGeneratorResponse) Reset() { *this = CodeGeneratorResponse{} } +func (this *CodeGeneratorResponse) String() string { return proto.CompactTextString(this) } +func (*CodeGeneratorResponse) ProtoMessage() {} + +func (this *CodeGeneratorResponse) GetError() string { + if this != nil && this.Error != nil { + return *this.Error + } + return "" +} + +type CodeGeneratorResponse_File struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point" json:"insertion_point,omitempty"` + Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (this *CodeGeneratorResponse_File) Reset() { *this = CodeGeneratorResponse_File{} } +func (this *CodeGeneratorResponse_File) String() string { return proto.CompactTextString(this) } +func (*CodeGeneratorResponse_File) ProtoMessage() {} + +func (this *CodeGeneratorResponse_File) GetName() string { + if this != nil && this.Name != nil { + return *this.Name + } + return "" +} + +func (this *CodeGeneratorResponse_File) GetInsertionPoint() string { + if this != nil && this.InsertionPoint != nil { + return *this.InsertionPoint + } + return "" +} + +func (this *CodeGeneratorResponse_File) GetContent() string { + if this != nil && this.Content != nil { + return *this.Content + } + return "" +} + +func init() { +} diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto b/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto new file mode 100644 index 000000000..5b5574529 --- /dev/null +++ b/vendor/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto @@ -0,0 +1,167 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to +// change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +option go_package = "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go"; + +import "google/protobuf/descriptor.proto"; + +// The version number of protocol compiler. +message Version { + optional int32 major = 1; + optional int32 minor = 2; + optional int32 patch = 3; + // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + // be empty for mainline stable releases. + optional string suffix = 4; +} + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + // + // Type names of fields and extensions in the FileDescriptorProto are always + // fully qualified. + repeated FileDescriptorProto proto_file = 15; + + // The version number of protocol compiler. + optional Version compiler_version = 3; + +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + } + repeated File file = 15; +} diff --git a/vendor/github.com/golang/protobuf/ptypes/any.go b/vendor/github.com/golang/protobuf/ptypes/any.go new file mode 100644 index 000000000..70276e8f5 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/any.go @@ -0,0 +1,141 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package ptypes + +// This file implements functions to marshal proto.Message to/from +// google.protobuf.Any message. + +import ( + "fmt" + "reflect" + "strings" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes/any" +) + +const googleApis = "type.googleapis.com/" + +// AnyMessageName returns the name of the message contained in a google.protobuf.Any message. +// +// Note that regular type assertions should be done using the Is +// function. AnyMessageName is provided for less common use cases like filtering a +// sequence of Any messages based on a set of allowed message type names. +func AnyMessageName(any *any.Any) (string, error) { + if any == nil { + return "", fmt.Errorf("message is nil") + } + slash := strings.LastIndex(any.TypeUrl, "/") + if slash < 0 { + return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) + } + return any.TypeUrl[slash+1:], nil +} + +// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any. +func MarshalAny(pb proto.Message) (*any.Any, error) { + value, err := proto.Marshal(pb) + if err != nil { + return nil, err + } + return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil +} + +// DynamicAny is a value that can be passed to UnmarshalAny to automatically +// allocate a proto.Message for the type specified in a google.protobuf.Any +// message. The allocated message is stored in the embedded proto.Message. +// +// Example: +// +// var x ptypes.DynamicAny +// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } +// fmt.Printf("unmarshaled message: %v", x.Message) +type DynamicAny struct { + proto.Message +} + +// Empty returns a new proto.Message of the type specified in a +// google.protobuf.Any message. It returns an error if corresponding message +// type isn't linked in. +func Empty(any *any.Any) (proto.Message, error) { + aname, err := AnyMessageName(any) + if err != nil { + return nil, err + } + + t := proto.MessageType(aname) + if t == nil { + return nil, fmt.Errorf("any: message type %q isn't linked in", aname) + } + return reflect.New(t.Elem()).Interface().(proto.Message), nil +} + +// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any +// message and places the decoded result in pb. It returns an error if type of +// contents of Any message does not match type of pb message. +// +// pb can be a proto.Message, or a *DynamicAny. +func UnmarshalAny(any *any.Any, pb proto.Message) error { + if d, ok := pb.(*DynamicAny); ok { + if d.Message == nil { + var err error + d.Message, err = Empty(any) + if err != nil { + return err + } + } + return UnmarshalAny(any, d.Message) + } + + aname, err := AnyMessageName(any) + if err != nil { + return err + } + + mname := proto.MessageName(pb) + if aname != mname { + return fmt.Errorf("mismatched message type: got %q want %q", aname, mname) + } + return proto.Unmarshal(any.Value, pb) +} + +// Is returns true if any value contains a given message type. +func Is(any *any.Any, pb proto.Message) bool { + // The following is equivalent to AnyMessageName(any) == proto.MessageName(pb), + // but it avoids scanning TypeUrl for the slash. + if any == nil { + return false + } + name := proto.MessageName(pb) + prefix := len(any.TypeUrl) - len(name) + return prefix >= 1 && any.TypeUrl[prefix-1] == '/' && any.TypeUrl[prefix:] == name +} diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go new file mode 100644 index 000000000..78ee52334 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go @@ -0,0 +1,200 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/any.proto + +package any + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := ptypes.MarshalAny(foo) +// ... +// foo := &pb.Foo{} +// if err := ptypes.UnmarshalAny(any, foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +type Any struct { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` + // Must be a valid serialized protocol buffer of the above specified type. + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Any) Reset() { *m = Any{} } +func (m *Any) String() string { return proto.CompactTextString(m) } +func (*Any) ProtoMessage() {} +func (*Any) Descriptor() ([]byte, []int) { + return fileDescriptor_b53526c13ae22eb4, []int{0} +} + +func (*Any) XXX_WellKnownType() string { return "Any" } + +func (m *Any) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Any.Unmarshal(m, b) +} +func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Any.Marshal(b, m, deterministic) +} +func (m *Any) XXX_Merge(src proto.Message) { + xxx_messageInfo_Any.Merge(m, src) +} +func (m *Any) XXX_Size() int { + return xxx_messageInfo_Any.Size(m) +} +func (m *Any) XXX_DiscardUnknown() { + xxx_messageInfo_Any.DiscardUnknown(m) +} + +var xxx_messageInfo_Any proto.InternalMessageInfo + +func (m *Any) GetTypeUrl() string { + if m != nil { + return m.TypeUrl + } + return "" +} + +func (m *Any) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func init() { + proto.RegisterType((*Any)(nil), "google.protobuf.Any") +} + +func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_b53526c13ae22eb4) } + +var fileDescriptor_b53526c13ae22eb4 = []byte{ + // 185 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f, + 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4, + 0x03, 0x73, 0x84, 0xf8, 0x21, 0x52, 0x7a, 0x30, 0x29, 0x25, 0x33, 0x2e, 0x66, 0xc7, 0xbc, 0x4a, + 0x21, 0x49, 0x2e, 0x8e, 0x92, 0xca, 0x82, 0xd4, 0xf8, 0xd2, 0xa2, 0x1c, 0x09, 0x46, 0x05, 0x46, + 0x0d, 0xce, 0x20, 0x76, 0x10, 0x3f, 0xb4, 0x28, 0x47, 0x48, 0x84, 0x8b, 0xb5, 0x2c, 0x31, 0xa7, + 0x34, 0x55, 0x82, 0x49, 0x81, 0x51, 0x83, 0x27, 0x08, 0xc2, 0x71, 0xca, 0xe7, 0x12, 0x4e, 0xce, + 0xcf, 0xd5, 0x43, 0x33, 0xce, 0x89, 0xc3, 0x31, 0xaf, 0x32, 0x00, 0xc4, 0x09, 0x60, 0x8c, 0x52, + 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, + 0x4b, 0x47, 0xb8, 0xa8, 0x00, 0x64, 0x7a, 0x31, 0xc8, 0x61, 0x8b, 0x98, 0x98, 0xdd, 0x03, 0x9c, + 0x56, 0x31, 0xc9, 0xb9, 0x43, 0x8c, 0x0a, 0x80, 0x2a, 0xd1, 0x0b, 0x4f, 0xcd, 0xc9, 0xf1, 0xce, + 0xcb, 0x2f, 0xcf, 0x0b, 0x01, 0x29, 0x4d, 0x62, 0x03, 0xeb, 0x35, 0x06, 0x04, 0x00, 0x00, 0xff, + 0xff, 0x13, 0xf8, 0xe8, 0x42, 0xdd, 0x00, 0x00, 0x00, +} diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.proto b/vendor/github.com/golang/protobuf/ptypes/any/any.proto new file mode 100644 index 000000000..493294255 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/any/any.proto @@ -0,0 +1,154 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/any"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := ptypes.MarshalAny(foo) +// ... +// foo := &pb.Foo{} +// if err := ptypes.UnmarshalAny(any, foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/vendor/github.com/golang/protobuf/ptypes/doc.go b/vendor/github.com/golang/protobuf/ptypes/doc.go new file mode 100644 index 000000000..c0d595da7 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/doc.go @@ -0,0 +1,35 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/* +Package ptypes contains code for interacting with well-known types. +*/ +package ptypes diff --git a/vendor/github.com/golang/protobuf/ptypes/duration.go b/vendor/github.com/golang/protobuf/ptypes/duration.go new file mode 100644 index 000000000..26d1ca2fb --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/duration.go @@ -0,0 +1,102 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package ptypes + +// This file implements conversions between google.protobuf.Duration +// and time.Duration. + +import ( + "errors" + "fmt" + "time" + + durpb "github.com/golang/protobuf/ptypes/duration" +) + +const ( + // Range of a durpb.Duration in seconds, as specified in + // google/protobuf/duration.proto. This is about 10,000 years in seconds. + maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) + minSeconds = -maxSeconds +) + +// validateDuration determines whether the durpb.Duration is valid according to the +// definition in google/protobuf/duration.proto. A valid durpb.Duration +// may still be too large to fit into a time.Duration (the range of durpb.Duration +// is about 10,000 years, and the range of time.Duration is about 290). +func validateDuration(d *durpb.Duration) error { + if d == nil { + return errors.New("duration: nil Duration") + } + if d.Seconds < minSeconds || d.Seconds > maxSeconds { + return fmt.Errorf("duration: %v: seconds out of range", d) + } + if d.Nanos <= -1e9 || d.Nanos >= 1e9 { + return fmt.Errorf("duration: %v: nanos out of range", d) + } + // Seconds and Nanos must have the same sign, unless d.Nanos is zero. + if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) { + return fmt.Errorf("duration: %v: seconds and nanos have different signs", d) + } + return nil +} + +// Duration converts a durpb.Duration to a time.Duration. Duration +// returns an error if the durpb.Duration is invalid or is too large to be +// represented in a time.Duration. +func Duration(p *durpb.Duration) (time.Duration, error) { + if err := validateDuration(p); err != nil { + return 0, err + } + d := time.Duration(p.Seconds) * time.Second + if int64(d/time.Second) != p.Seconds { + return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) + } + if p.Nanos != 0 { + d += time.Duration(p.Nanos) * time.Nanosecond + if (d < 0) != (p.Nanos < 0) { + return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) + } + } + return d, nil +} + +// DurationProto converts a time.Duration to a durpb.Duration. +func DurationProto(d time.Duration) *durpb.Duration { + nanos := d.Nanoseconds() + secs := nanos / 1e9 + nanos -= secs * 1e9 + return &durpb.Duration{ + Seconds: secs, + Nanos: int32(nanos), + } +} diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go new file mode 100644 index 000000000..0d681ee21 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go @@ -0,0 +1,161 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/duration.proto + +package duration + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// # Examples +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (durations.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// Example 3: Compute Duration from datetime.timedelta in Python. +// +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) +// +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// +// +type Duration struct { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Duration) Reset() { *m = Duration{} } +func (m *Duration) String() string { return proto.CompactTextString(m) } +func (*Duration) ProtoMessage() {} +func (*Duration) Descriptor() ([]byte, []int) { + return fileDescriptor_23597b2ebd7ac6c5, []int{0} +} + +func (*Duration) XXX_WellKnownType() string { return "Duration" } + +func (m *Duration) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Duration.Unmarshal(m, b) +} +func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Duration.Marshal(b, m, deterministic) +} +func (m *Duration) XXX_Merge(src proto.Message) { + xxx_messageInfo_Duration.Merge(m, src) +} +func (m *Duration) XXX_Size() int { + return xxx_messageInfo_Duration.Size(m) +} +func (m *Duration) XXX_DiscardUnknown() { + xxx_messageInfo_Duration.DiscardUnknown(m) +} + +var xxx_messageInfo_Duration proto.InternalMessageInfo + +func (m *Duration) GetSeconds() int64 { + if m != nil { + return m.Seconds + } + return 0 +} + +func (m *Duration) GetNanos() int32 { + if m != nil { + return m.Nanos + } + return 0 +} + +func init() { + proto.RegisterType((*Duration)(nil), "google.protobuf.Duration") +} + +func init() { proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_23597b2ebd7ac6c5) } + +var fileDescriptor_23597b2ebd7ac6c5 = []byte{ + // 190 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f, + 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a, + 0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x03, 0x8b, 0x08, 0xf1, 0x43, 0xe4, 0xf5, 0x60, 0xf2, 0x4a, 0x56, + 0x5c, 0x1c, 0x2e, 0x50, 0x25, 0x42, 0x12, 0x5c, 0xec, 0xc5, 0xa9, 0xc9, 0xf9, 0x79, 0x29, 0xc5, + 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x30, 0xae, 0x90, 0x08, 0x17, 0x6b, 0x5e, 0x62, 0x5e, + 0x7e, 0xb1, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x84, 0xe3, 0x54, 0xc3, 0x25, 0x9c, 0x9c, + 0x9f, 0xab, 0x87, 0x66, 0xa4, 0x13, 0x2f, 0xcc, 0xc0, 0x00, 0x90, 0x48, 0x00, 0x63, 0x94, 0x56, + 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e, + 0x3a, 0xc2, 0x7d, 0x05, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x70, 0x67, 0xfe, 0x60, 0x64, 0x5c, 0xc4, + 0xc4, 0xec, 0x1e, 0xe0, 0xb4, 0x8a, 0x49, 0xce, 0x1d, 0x62, 0x6e, 0x00, 0x54, 0xa9, 0x5e, 0x78, + 0x6a, 0x4e, 0x8e, 0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0x48, 0x4b, 0x12, 0x1b, 0xd8, 0x0c, 0x63, + 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x84, 0x30, 0xff, 0xf3, 0x00, 0x00, 0x00, +} diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto b/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto new file mode 100644 index 000000000..975fce41a --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto @@ -0,0 +1,117 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/duration"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DurationProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// # Examples +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (durations.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// Example 3: Compute Duration from datetime.timedelta in Python. +// +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) +// +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// +// +message Duration { + + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} diff --git a/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go b/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go new file mode 100644 index 000000000..33daa73dd --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go @@ -0,0 +1,336 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/struct.proto + +package structpb + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +type NullValue int32 + +const ( + // Null value. + NullValue_NULL_VALUE NullValue = 0 +) + +var NullValue_name = map[int32]string{ + 0: "NULL_VALUE", +} + +var NullValue_value = map[string]int32{ + "NULL_VALUE": 0, +} + +func (x NullValue) String() string { + return proto.EnumName(NullValue_name, int32(x)) +} + +func (NullValue) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_df322afd6c9fb402, []int{0} +} + +func (NullValue) XXX_WellKnownType() string { return "NullValue" } + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +type Struct struct { + // Unordered map of dynamically typed values. + Fields map[string]*Value `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Struct) Reset() { *m = Struct{} } +func (m *Struct) String() string { return proto.CompactTextString(m) } +func (*Struct) ProtoMessage() {} +func (*Struct) Descriptor() ([]byte, []int) { + return fileDescriptor_df322afd6c9fb402, []int{0} +} + +func (*Struct) XXX_WellKnownType() string { return "Struct" } + +func (m *Struct) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Struct.Unmarshal(m, b) +} +func (m *Struct) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Struct.Marshal(b, m, deterministic) +} +func (m *Struct) XXX_Merge(src proto.Message) { + xxx_messageInfo_Struct.Merge(m, src) +} +func (m *Struct) XXX_Size() int { + return xxx_messageInfo_Struct.Size(m) +} +func (m *Struct) XXX_DiscardUnknown() { + xxx_messageInfo_Struct.DiscardUnknown(m) +} + +var xxx_messageInfo_Struct proto.InternalMessageInfo + +func (m *Struct) GetFields() map[string]*Value { + if m != nil { + return m.Fields + } + return nil +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of that +// variants, absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +type Value struct { + // The kind of value. + // + // Types that are valid to be assigned to Kind: + // *Value_NullValue + // *Value_NumberValue + // *Value_StringValue + // *Value_BoolValue + // *Value_StructValue + // *Value_ListValue + Kind isValue_Kind `protobuf_oneof:"kind"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Value) Reset() { *m = Value{} } +func (m *Value) String() string { return proto.CompactTextString(m) } +func (*Value) ProtoMessage() {} +func (*Value) Descriptor() ([]byte, []int) { + return fileDescriptor_df322afd6c9fb402, []int{1} +} + +func (*Value) XXX_WellKnownType() string { return "Value" } + +func (m *Value) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Value.Unmarshal(m, b) +} +func (m *Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Value.Marshal(b, m, deterministic) +} +func (m *Value) XXX_Merge(src proto.Message) { + xxx_messageInfo_Value.Merge(m, src) +} +func (m *Value) XXX_Size() int { + return xxx_messageInfo_Value.Size(m) +} +func (m *Value) XXX_DiscardUnknown() { + xxx_messageInfo_Value.DiscardUnknown(m) +} + +var xxx_messageInfo_Value proto.InternalMessageInfo + +type isValue_Kind interface { + isValue_Kind() +} + +type Value_NullValue struct { + NullValue NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"` +} + +type Value_NumberValue struct { + NumberValue float64 `protobuf:"fixed64,2,opt,name=number_value,json=numberValue,proto3,oneof"` +} + +type Value_StringValue struct { + StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"` +} + +type Value_BoolValue struct { + BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"` +} + +type Value_StructValue struct { + StructValue *Struct `protobuf:"bytes,5,opt,name=struct_value,json=structValue,proto3,oneof"` +} + +type Value_ListValue struct { + ListValue *ListValue `protobuf:"bytes,6,opt,name=list_value,json=listValue,proto3,oneof"` +} + +func (*Value_NullValue) isValue_Kind() {} + +func (*Value_NumberValue) isValue_Kind() {} + +func (*Value_StringValue) isValue_Kind() {} + +func (*Value_BoolValue) isValue_Kind() {} + +func (*Value_StructValue) isValue_Kind() {} + +func (*Value_ListValue) isValue_Kind() {} + +func (m *Value) GetKind() isValue_Kind { + if m != nil { + return m.Kind + } + return nil +} + +func (m *Value) GetNullValue() NullValue { + if x, ok := m.GetKind().(*Value_NullValue); ok { + return x.NullValue + } + return NullValue_NULL_VALUE +} + +func (m *Value) GetNumberValue() float64 { + if x, ok := m.GetKind().(*Value_NumberValue); ok { + return x.NumberValue + } + return 0 +} + +func (m *Value) GetStringValue() string { + if x, ok := m.GetKind().(*Value_StringValue); ok { + return x.StringValue + } + return "" +} + +func (m *Value) GetBoolValue() bool { + if x, ok := m.GetKind().(*Value_BoolValue); ok { + return x.BoolValue + } + return false +} + +func (m *Value) GetStructValue() *Struct { + if x, ok := m.GetKind().(*Value_StructValue); ok { + return x.StructValue + } + return nil +} + +func (m *Value) GetListValue() *ListValue { + if x, ok := m.GetKind().(*Value_ListValue); ok { + return x.ListValue + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Value) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Value_NullValue)(nil), + (*Value_NumberValue)(nil), + (*Value_StringValue)(nil), + (*Value_BoolValue)(nil), + (*Value_StructValue)(nil), + (*Value_ListValue)(nil), + } +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +type ListValue struct { + // Repeated field of dynamically typed values. + Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListValue) Reset() { *m = ListValue{} } +func (m *ListValue) String() string { return proto.CompactTextString(m) } +func (*ListValue) ProtoMessage() {} +func (*ListValue) Descriptor() ([]byte, []int) { + return fileDescriptor_df322afd6c9fb402, []int{2} +} + +func (*ListValue) XXX_WellKnownType() string { return "ListValue" } + +func (m *ListValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ListValue.Unmarshal(m, b) +} +func (m *ListValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ListValue.Marshal(b, m, deterministic) +} +func (m *ListValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListValue.Merge(m, src) +} +func (m *ListValue) XXX_Size() int { + return xxx_messageInfo_ListValue.Size(m) +} +func (m *ListValue) XXX_DiscardUnknown() { + xxx_messageInfo_ListValue.DiscardUnknown(m) +} + +var xxx_messageInfo_ListValue proto.InternalMessageInfo + +func (m *ListValue) GetValues() []*Value { + if m != nil { + return m.Values + } + return nil +} + +func init() { + proto.RegisterEnum("google.protobuf.NullValue", NullValue_name, NullValue_value) + proto.RegisterType((*Struct)(nil), "google.protobuf.Struct") + proto.RegisterMapType((map[string]*Value)(nil), "google.protobuf.Struct.FieldsEntry") + proto.RegisterType((*Value)(nil), "google.protobuf.Value") + proto.RegisterType((*ListValue)(nil), "google.protobuf.ListValue") +} + +func init() { proto.RegisterFile("google/protobuf/struct.proto", fileDescriptor_df322afd6c9fb402) } + +var fileDescriptor_df322afd6c9fb402 = []byte{ + // 417 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x41, 0x8b, 0xd3, 0x40, + 0x14, 0xc7, 0x3b, 0xc9, 0x36, 0x98, 0x17, 0x59, 0x97, 0x11, 0xb4, 0xac, 0xa2, 0xa1, 0x7b, 0x09, + 0x22, 0x29, 0xd6, 0x8b, 0x18, 0x2f, 0x06, 0xd6, 0x5d, 0x30, 0x2c, 0x31, 0xba, 0x15, 0xbc, 0x94, + 0x26, 0x4d, 0x63, 0xe8, 0x74, 0x26, 0x24, 0x33, 0x4a, 0x8f, 0x7e, 0x0b, 0xcf, 0x1e, 0x3d, 0xfa, + 0xe9, 0x3c, 0xca, 0xcc, 0x24, 0xa9, 0xb4, 0xf4, 0x94, 0xbc, 0xf7, 0x7e, 0xef, 0x3f, 0xef, 0xff, + 0x66, 0xe0, 0x71, 0xc1, 0x58, 0x41, 0xf2, 0x49, 0x55, 0x33, 0xce, 0x52, 0xb1, 0x9a, 0x34, 0xbc, + 0x16, 0x19, 0xf7, 0x55, 0x8c, 0xef, 0xe9, 0xaa, 0xdf, 0x55, 0xc7, 0x3f, 0x11, 0x58, 0x1f, 0x15, + 0x81, 0x03, 0xb0, 0x56, 0x65, 0x4e, 0x96, 0xcd, 0x08, 0xb9, 0xa6, 0xe7, 0x4c, 0x2f, 0xfc, 0x3d, + 0xd8, 0xd7, 0xa0, 0xff, 0x4e, 0x51, 0x97, 0x94, 0xd7, 0xdb, 0xa4, 0x6d, 0x39, 0xff, 0x00, 0xce, + 0x7f, 0x69, 0x7c, 0x06, 0xe6, 0x3a, 0xdf, 0x8e, 0x90, 0x8b, 0x3c, 0x3b, 0x91, 0xbf, 0xf8, 0x39, + 0x0c, 0xbf, 0x2d, 0x88, 0xc8, 0x47, 0x86, 0x8b, 0x3c, 0x67, 0xfa, 0xe0, 0x40, 0x7c, 0x26, 0xab, + 0x89, 0x86, 0x5e, 0x1b, 0xaf, 0xd0, 0xf8, 0x8f, 0x01, 0x43, 0x95, 0xc4, 0x01, 0x00, 0x15, 0x84, + 0xcc, 0xb5, 0x80, 0x14, 0x3d, 0x9d, 0x9e, 0x1f, 0x08, 0xdc, 0x08, 0x42, 0x14, 0x7f, 0x3d, 0x48, + 0x6c, 0xda, 0x05, 0xf8, 0x02, 0xee, 0x52, 0xb1, 0x49, 0xf3, 0x7a, 0xbe, 0x3b, 0x1f, 0x5d, 0x0f, + 0x12, 0x47, 0x67, 0x7b, 0xa8, 0xe1, 0x75, 0x49, 0x8b, 0x16, 0x32, 0xe5, 0xe0, 0x12, 0xd2, 0x59, + 0x0d, 0x3d, 0x05, 0x48, 0x19, 0xeb, 0xc6, 0x38, 0x71, 0x91, 0x77, 0x47, 0x1e, 0x25, 0x73, 0x1a, + 0x78, 0xa3, 0x54, 0x44, 0xc6, 0x5b, 0x64, 0xa8, 0xac, 0x3e, 0x3c, 0xb2, 0xc7, 0x56, 0x5e, 0x64, + 0xbc, 0x77, 0x49, 0xca, 0xa6, 0xeb, 0xb5, 0x54, 0xef, 0xa1, 0xcb, 0xa8, 0x6c, 0x78, 0xef, 0x92, + 0x74, 0x41, 0x68, 0xc1, 0xc9, 0xba, 0xa4, 0xcb, 0x71, 0x00, 0x76, 0x4f, 0x60, 0x1f, 0x2c, 0x25, + 0xd6, 0xdd, 0xe8, 0xb1, 0xa5, 0xb7, 0xd4, 0xb3, 0x47, 0x60, 0xf7, 0x4b, 0xc4, 0xa7, 0x00, 0x37, + 0xb7, 0x51, 0x34, 0x9f, 0xbd, 0x8d, 0x6e, 0x2f, 0xcf, 0x06, 0xe1, 0x0f, 0x04, 0xf7, 0x33, 0xb6, + 0xd9, 0x97, 0x08, 0x1d, 0xed, 0x26, 0x96, 0x71, 0x8c, 0xbe, 0xbc, 0x28, 0x4a, 0xfe, 0x55, 0xa4, + 0x7e, 0xc6, 0x36, 0x93, 0x82, 0x91, 0x05, 0x2d, 0x76, 0x4f, 0xb1, 0xe2, 0xdb, 0x2a, 0x6f, 0xda, + 0x17, 0x19, 0xe8, 0x4f, 0x95, 0xfe, 0x45, 0xe8, 0x97, 0x61, 0x5e, 0xc5, 0xe1, 0x6f, 0xe3, 0xc9, + 0x95, 0x16, 0x8f, 0xbb, 0xf9, 0x3e, 0xe7, 0x84, 0xbc, 0xa7, 0xec, 0x3b, 0xfd, 0x24, 0x3b, 0x53, + 0x4b, 0x49, 0xbd, 0xfc, 0x17, 0x00, 0x00, 0xff, 0xff, 0xe8, 0x1b, 0x59, 0xf8, 0xe5, 0x02, 0x00, + 0x00, +} diff --git a/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto b/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto new file mode 100644 index 000000000..7d7808e7f --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto @@ -0,0 +1,96 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/struct;structpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "StructProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +message Struct { + // Unordered map of dynamically typed values. + map fields = 1; +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of that +// variants, absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +message Value { + // The kind of value. + oneof kind { + // Represents a null value. + NullValue null_value = 1; + // Represents a double value. + double number_value = 2; + // Represents a string value. + string string_value = 3; + // Represents a boolean value. + bool bool_value = 4; + // Represents a structured value. + Struct struct_value = 5; + // Represents a repeated `Value`. + ListValue list_value = 6; + } +} + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +enum NullValue { + // Null value. + NULL_VALUE = 0; +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +message ListValue { + // Repeated field of dynamically typed values. + repeated Value values = 1; +} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/vendor/github.com/golang/protobuf/ptypes/timestamp.go new file mode 100644 index 000000000..8da0df01a --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp.go @@ -0,0 +1,132 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2016 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package ptypes + +// This file implements operations on google.protobuf.Timestamp. + +import ( + "errors" + "fmt" + "time" + + tspb "github.com/golang/protobuf/ptypes/timestamp" +) + +const ( + // Seconds field of the earliest valid Timestamp. + // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). + minValidSeconds = -62135596800 + // Seconds field just after the latest valid Timestamp. + // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). + maxValidSeconds = 253402300800 +) + +// validateTimestamp determines whether a Timestamp is valid. +// A valid timestamp represents a time in the range +// [0001-01-01, 10000-01-01) and has a Nanos field +// in the range [0, 1e9). +// +// If the Timestamp is valid, validateTimestamp returns nil. +// Otherwise, it returns an error that describes +// the problem. +// +// Every valid Timestamp can be represented by a time.Time, but the converse is not true. +func validateTimestamp(ts *tspb.Timestamp) error { + if ts == nil { + return errors.New("timestamp: nil Timestamp") + } + if ts.Seconds < minValidSeconds { + return fmt.Errorf("timestamp: %v before 0001-01-01", ts) + } + if ts.Seconds >= maxValidSeconds { + return fmt.Errorf("timestamp: %v after 10000-01-01", ts) + } + if ts.Nanos < 0 || ts.Nanos >= 1e9 { + return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) + } + return nil +} + +// Timestamp converts a google.protobuf.Timestamp proto to a time.Time. +// It returns an error if the argument is invalid. +// +// Unlike most Go functions, if Timestamp returns an error, the first return value +// is not the zero time.Time. Instead, it is the value obtained from the +// time.Unix function when passed the contents of the Timestamp, in the UTC +// locale. This may or may not be a meaningful time; many invalid Timestamps +// do map to valid time.Times. +// +// A nil Timestamp returns an error. The first return value in that case is +// undefined. +func Timestamp(ts *tspb.Timestamp) (time.Time, error) { + // Don't return the zero value on error, because corresponds to a valid + // timestamp. Instead return whatever time.Unix gives us. + var t time.Time + if ts == nil { + t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp + } else { + t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() + } + return t, validateTimestamp(ts) +} + +// TimestampNow returns a google.protobuf.Timestamp for the current time. +func TimestampNow() *tspb.Timestamp { + ts, err := TimestampProto(time.Now()) + if err != nil { + panic("ptypes: time.Now() out of Timestamp range") + } + return ts +} + +// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. +// It returns an error if the resulting Timestamp is invalid. +func TimestampProto(t time.Time) (*tspb.Timestamp, error) { + ts := &tspb.Timestamp{ + Seconds: t.Unix(), + Nanos: int32(t.Nanosecond()), + } + if err := validateTimestamp(ts); err != nil { + return nil, err + } + return ts, nil +} + +// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid +// Timestamps, it returns an error message in parentheses. +func TimestampString(ts *tspb.Timestamp) string { + t, err := Timestamp(ts) + if err != nil { + return fmt.Sprintf("(%v)", err) + } + return t.Format(time.RFC3339Nano) +} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go new file mode 100644 index 000000000..31cd846de --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go @@ -0,0 +1,179 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/timestamp.proto + +package timestamp + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// A Timestamp represents a point in time independent of any time zone +// or calendar, represented as seconds and fractions of seconds at +// nanosecond resolution in UTC Epoch time. It is encoded using the +// Proleptic Gregorian Calendar which extends the Gregorian calendar +// backwards to year one. It is encoded assuming all minutes are 60 +// seconds long, i.e. leap seconds are "smeared" so that no leap second +// table is needed for interpretation. Range is from +// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. +// By restricting to that range, we ensure that we can convert to +// and from RFC 3339 date strings. +// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// +// Example 5: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) +// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one +// can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- +// ) to obtain a formatter capable of generating timestamps in this format. +// +// +type Timestamp struct { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Timestamp) Reset() { *m = Timestamp{} } +func (m *Timestamp) String() string { return proto.CompactTextString(m) } +func (*Timestamp) ProtoMessage() {} +func (*Timestamp) Descriptor() ([]byte, []int) { + return fileDescriptor_292007bbfe81227e, []int{0} +} + +func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" } + +func (m *Timestamp) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Timestamp.Unmarshal(m, b) +} +func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic) +} +func (m *Timestamp) XXX_Merge(src proto.Message) { + xxx_messageInfo_Timestamp.Merge(m, src) +} +func (m *Timestamp) XXX_Size() int { + return xxx_messageInfo_Timestamp.Size(m) +} +func (m *Timestamp) XXX_DiscardUnknown() { + xxx_messageInfo_Timestamp.DiscardUnknown(m) +} + +var xxx_messageInfo_Timestamp proto.InternalMessageInfo + +func (m *Timestamp) GetSeconds() int64 { + if m != nil { + return m.Seconds + } + return 0 +} + +func (m *Timestamp) GetNanos() int32 { + if m != nil { + return m.Nanos + } + return 0 +} + +func init() { + proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp") +} + +func init() { proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_292007bbfe81227e) } + +var fileDescriptor_292007bbfe81227e = []byte{ + // 191 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, + 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d, + 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x03, 0x0b, 0x09, 0xf1, 0x43, 0x14, 0xe8, 0xc1, 0x14, 0x28, + 0x59, 0x73, 0x71, 0x86, 0xc0, 0xd4, 0x08, 0x49, 0x70, 0xb1, 0x17, 0xa7, 0x26, 0xe7, 0xe7, 0xa5, + 0x14, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x30, 0x07, 0xc1, 0xb8, 0x42, 0x22, 0x5c, 0xac, 0x79, 0x89, + 0x79, 0xf9, 0xc5, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xac, 0x41, 0x10, 0x8e, 0x53, 0x1d, 0x97, 0x70, + 0x72, 0x7e, 0xae, 0x1e, 0x9a, 0x99, 0x4e, 0x7c, 0x70, 0x13, 0x03, 0x40, 0x42, 0x01, 0x8c, 0x51, + 0xda, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xe9, 0xf9, 0x39, 0x89, + 0x79, 0xe9, 0x08, 0x27, 0x16, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x23, 0x5c, 0xfa, 0x83, 0x91, 0x71, + 0x11, 0x13, 0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xc9, 0x01, 0x50, 0xb5, 0x7a, + 0xe1, 0xa9, 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x3d, 0x49, 0x6c, 0x60, 0x43, + 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x77, 0x4a, 0x07, 0xf7, 0x00, 0x00, 0x00, +} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto new file mode 100644 index 000000000..eafb3fa03 --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto @@ -0,0 +1,135 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/timestamp"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Timestamp represents a point in time independent of any time zone +// or calendar, represented as seconds and fractions of seconds at +// nanosecond resolution in UTC Epoch time. It is encoded using the +// Proleptic Gregorian Calendar which extends the Gregorian calendar +// backwards to year one. It is encoded assuming all minutes are 60 +// seconds long, i.e. leap seconds are "smeared" so that no leap second +// table is needed for interpretation. Range is from +// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. +// By restricting to that range, we ensure that we can convert to +// and from RFC 3339 date strings. +// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// +// Example 5: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) +// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one +// can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- +// ) to obtain a formatter capable of generating timestamps in this format. +// +// +message Timestamp { + + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go b/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go new file mode 100644 index 000000000..add19a1ad --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.pb.go @@ -0,0 +1,461 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: google/protobuf/wrappers.proto + +package wrappers + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +type DoubleValue struct { + // The double value. + Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DoubleValue) Reset() { *m = DoubleValue{} } +func (m *DoubleValue) String() string { return proto.CompactTextString(m) } +func (*DoubleValue) ProtoMessage() {} +func (*DoubleValue) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{0} +} + +func (*DoubleValue) XXX_WellKnownType() string { return "DoubleValue" } + +func (m *DoubleValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DoubleValue.Unmarshal(m, b) +} +func (m *DoubleValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DoubleValue.Marshal(b, m, deterministic) +} +func (m *DoubleValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_DoubleValue.Merge(m, src) +} +func (m *DoubleValue) XXX_Size() int { + return xxx_messageInfo_DoubleValue.Size(m) +} +func (m *DoubleValue) XXX_DiscardUnknown() { + xxx_messageInfo_DoubleValue.DiscardUnknown(m) +} + +var xxx_messageInfo_DoubleValue proto.InternalMessageInfo + +func (m *DoubleValue) GetValue() float64 { + if m != nil { + return m.Value + } + return 0 +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +type FloatValue struct { + // The float value. + Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FloatValue) Reset() { *m = FloatValue{} } +func (m *FloatValue) String() string { return proto.CompactTextString(m) } +func (*FloatValue) ProtoMessage() {} +func (*FloatValue) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{1} +} + +func (*FloatValue) XXX_WellKnownType() string { return "FloatValue" } + +func (m *FloatValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FloatValue.Unmarshal(m, b) +} +func (m *FloatValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FloatValue.Marshal(b, m, deterministic) +} +func (m *FloatValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_FloatValue.Merge(m, src) +} +func (m *FloatValue) XXX_Size() int { + return xxx_messageInfo_FloatValue.Size(m) +} +func (m *FloatValue) XXX_DiscardUnknown() { + xxx_messageInfo_FloatValue.DiscardUnknown(m) +} + +var xxx_messageInfo_FloatValue proto.InternalMessageInfo + +func (m *FloatValue) GetValue() float32 { + if m != nil { + return m.Value + } + return 0 +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +type Int64Value struct { + // The int64 value. + Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Int64Value) Reset() { *m = Int64Value{} } +func (m *Int64Value) String() string { return proto.CompactTextString(m) } +func (*Int64Value) ProtoMessage() {} +func (*Int64Value) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{2} +} + +func (*Int64Value) XXX_WellKnownType() string { return "Int64Value" } + +func (m *Int64Value) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Int64Value.Unmarshal(m, b) +} +func (m *Int64Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Int64Value.Marshal(b, m, deterministic) +} +func (m *Int64Value) XXX_Merge(src proto.Message) { + xxx_messageInfo_Int64Value.Merge(m, src) +} +func (m *Int64Value) XXX_Size() int { + return xxx_messageInfo_Int64Value.Size(m) +} +func (m *Int64Value) XXX_DiscardUnknown() { + xxx_messageInfo_Int64Value.DiscardUnknown(m) +} + +var xxx_messageInfo_Int64Value proto.InternalMessageInfo + +func (m *Int64Value) GetValue() int64 { + if m != nil { + return m.Value + } + return 0 +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +type UInt64Value struct { + // The uint64 value. + Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UInt64Value) Reset() { *m = UInt64Value{} } +func (m *UInt64Value) String() string { return proto.CompactTextString(m) } +func (*UInt64Value) ProtoMessage() {} +func (*UInt64Value) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{3} +} + +func (*UInt64Value) XXX_WellKnownType() string { return "UInt64Value" } + +func (m *UInt64Value) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UInt64Value.Unmarshal(m, b) +} +func (m *UInt64Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UInt64Value.Marshal(b, m, deterministic) +} +func (m *UInt64Value) XXX_Merge(src proto.Message) { + xxx_messageInfo_UInt64Value.Merge(m, src) +} +func (m *UInt64Value) XXX_Size() int { + return xxx_messageInfo_UInt64Value.Size(m) +} +func (m *UInt64Value) XXX_DiscardUnknown() { + xxx_messageInfo_UInt64Value.DiscardUnknown(m) +} + +var xxx_messageInfo_UInt64Value proto.InternalMessageInfo + +func (m *UInt64Value) GetValue() uint64 { + if m != nil { + return m.Value + } + return 0 +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +type Int32Value struct { + // The int32 value. + Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Int32Value) Reset() { *m = Int32Value{} } +func (m *Int32Value) String() string { return proto.CompactTextString(m) } +func (*Int32Value) ProtoMessage() {} +func (*Int32Value) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{4} +} + +func (*Int32Value) XXX_WellKnownType() string { return "Int32Value" } + +func (m *Int32Value) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Int32Value.Unmarshal(m, b) +} +func (m *Int32Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Int32Value.Marshal(b, m, deterministic) +} +func (m *Int32Value) XXX_Merge(src proto.Message) { + xxx_messageInfo_Int32Value.Merge(m, src) +} +func (m *Int32Value) XXX_Size() int { + return xxx_messageInfo_Int32Value.Size(m) +} +func (m *Int32Value) XXX_DiscardUnknown() { + xxx_messageInfo_Int32Value.DiscardUnknown(m) +} + +var xxx_messageInfo_Int32Value proto.InternalMessageInfo + +func (m *Int32Value) GetValue() int32 { + if m != nil { + return m.Value + } + return 0 +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +type UInt32Value struct { + // The uint32 value. + Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *UInt32Value) Reset() { *m = UInt32Value{} } +func (m *UInt32Value) String() string { return proto.CompactTextString(m) } +func (*UInt32Value) ProtoMessage() {} +func (*UInt32Value) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{5} +} + +func (*UInt32Value) XXX_WellKnownType() string { return "UInt32Value" } + +func (m *UInt32Value) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_UInt32Value.Unmarshal(m, b) +} +func (m *UInt32Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_UInt32Value.Marshal(b, m, deterministic) +} +func (m *UInt32Value) XXX_Merge(src proto.Message) { + xxx_messageInfo_UInt32Value.Merge(m, src) +} +func (m *UInt32Value) XXX_Size() int { + return xxx_messageInfo_UInt32Value.Size(m) +} +func (m *UInt32Value) XXX_DiscardUnknown() { + xxx_messageInfo_UInt32Value.DiscardUnknown(m) +} + +var xxx_messageInfo_UInt32Value proto.InternalMessageInfo + +func (m *UInt32Value) GetValue() uint32 { + if m != nil { + return m.Value + } + return 0 +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +type BoolValue struct { + // The bool value. + Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BoolValue) Reset() { *m = BoolValue{} } +func (m *BoolValue) String() string { return proto.CompactTextString(m) } +func (*BoolValue) ProtoMessage() {} +func (*BoolValue) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{6} +} + +func (*BoolValue) XXX_WellKnownType() string { return "BoolValue" } + +func (m *BoolValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BoolValue.Unmarshal(m, b) +} +func (m *BoolValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BoolValue.Marshal(b, m, deterministic) +} +func (m *BoolValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_BoolValue.Merge(m, src) +} +func (m *BoolValue) XXX_Size() int { + return xxx_messageInfo_BoolValue.Size(m) +} +func (m *BoolValue) XXX_DiscardUnknown() { + xxx_messageInfo_BoolValue.DiscardUnknown(m) +} + +var xxx_messageInfo_BoolValue proto.InternalMessageInfo + +func (m *BoolValue) GetValue() bool { + if m != nil { + return m.Value + } + return false +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +type StringValue struct { + // The string value. + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StringValue) Reset() { *m = StringValue{} } +func (m *StringValue) String() string { return proto.CompactTextString(m) } +func (*StringValue) ProtoMessage() {} +func (*StringValue) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{7} +} + +func (*StringValue) XXX_WellKnownType() string { return "StringValue" } + +func (m *StringValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StringValue.Unmarshal(m, b) +} +func (m *StringValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StringValue.Marshal(b, m, deterministic) +} +func (m *StringValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_StringValue.Merge(m, src) +} +func (m *StringValue) XXX_Size() int { + return xxx_messageInfo_StringValue.Size(m) +} +func (m *StringValue) XXX_DiscardUnknown() { + xxx_messageInfo_StringValue.DiscardUnknown(m) +} + +var xxx_messageInfo_StringValue proto.InternalMessageInfo + +func (m *StringValue) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +type BytesValue struct { + // The bytes value. + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BytesValue) Reset() { *m = BytesValue{} } +func (m *BytesValue) String() string { return proto.CompactTextString(m) } +func (*BytesValue) ProtoMessage() {} +func (*BytesValue) Descriptor() ([]byte, []int) { + return fileDescriptor_5377b62bda767935, []int{8} +} + +func (*BytesValue) XXX_WellKnownType() string { return "BytesValue" } + +func (m *BytesValue) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BytesValue.Unmarshal(m, b) +} +func (m *BytesValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BytesValue.Marshal(b, m, deterministic) +} +func (m *BytesValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_BytesValue.Merge(m, src) +} +func (m *BytesValue) XXX_Size() int { + return xxx_messageInfo_BytesValue.Size(m) +} +func (m *BytesValue) XXX_DiscardUnknown() { + xxx_messageInfo_BytesValue.DiscardUnknown(m) +} + +var xxx_messageInfo_BytesValue proto.InternalMessageInfo + +func (m *BytesValue) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func init() { + proto.RegisterType((*DoubleValue)(nil), "google.protobuf.DoubleValue") + proto.RegisterType((*FloatValue)(nil), "google.protobuf.FloatValue") + proto.RegisterType((*Int64Value)(nil), "google.protobuf.Int64Value") + proto.RegisterType((*UInt64Value)(nil), "google.protobuf.UInt64Value") + proto.RegisterType((*Int32Value)(nil), "google.protobuf.Int32Value") + proto.RegisterType((*UInt32Value)(nil), "google.protobuf.UInt32Value") + proto.RegisterType((*BoolValue)(nil), "google.protobuf.BoolValue") + proto.RegisterType((*StringValue)(nil), "google.protobuf.StringValue") + proto.RegisterType((*BytesValue)(nil), "google.protobuf.BytesValue") +} + +func init() { proto.RegisterFile("google/protobuf/wrappers.proto", fileDescriptor_5377b62bda767935) } + +var fileDescriptor_5377b62bda767935 = []byte{ + // 259 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f, + 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x2f, 0x4a, 0x2c, + 0x28, 0x48, 0x2d, 0x2a, 0xd6, 0x03, 0x8b, 0x08, 0xf1, 0x43, 0xe4, 0xf5, 0x60, 0xf2, 0x4a, 0xca, + 0x5c, 0xdc, 0x2e, 0xf9, 0xa5, 0x49, 0x39, 0xa9, 0x61, 0x89, 0x39, 0xa5, 0xa9, 0x42, 0x22, 0x5c, + 0xac, 0x65, 0x20, 0x86, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x63, 0x10, 0x84, 0xa3, 0xa4, 0xc4, 0xc5, + 0xe5, 0x96, 0x93, 0x9f, 0x58, 0x82, 0x45, 0x0d, 0x13, 0x92, 0x1a, 0xcf, 0xbc, 0x12, 0x33, 0x13, + 0x2c, 0x6a, 0x98, 0x61, 0x6a, 0x94, 0xb9, 0xb8, 0x43, 0x71, 0x29, 0x62, 0x41, 0x35, 0xc8, 0xd8, + 0x08, 0x8b, 0x1a, 0x56, 0x34, 0x83, 0xb0, 0x2a, 0xe2, 0x85, 0x29, 0x52, 0xe4, 0xe2, 0x74, 0xca, + 0xcf, 0xcf, 0xc1, 0xa2, 0x84, 0x03, 0xc9, 0x9c, 0xe0, 0x92, 0xa2, 0xcc, 0xbc, 0x74, 0x2c, 0x8a, + 0x38, 0x91, 0x1c, 0xe4, 0x54, 0x59, 0x92, 0x5a, 0x8c, 0x45, 0x0d, 0x0f, 0x54, 0x8d, 0x53, 0x0d, + 0x97, 0x70, 0x72, 0x7e, 0xae, 0x1e, 0x5a, 0xe8, 0x3a, 0xf1, 0x86, 0x43, 0x83, 0x3f, 0x00, 0x24, + 0x12, 0xc0, 0x18, 0xa5, 0x95, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, + 0x9e, 0x9f, 0x93, 0x98, 0x97, 0x8e, 0x88, 0xaa, 0x82, 0x92, 0xca, 0x82, 0xd4, 0x62, 0x78, 0x8c, + 0xfd, 0x60, 0x64, 0x5c, 0xc4, 0xc4, 0xec, 0x1e, 0xe0, 0xb4, 0x8a, 0x49, 0xce, 0x1d, 0x62, 0x6e, + 0x00, 0x54, 0xa9, 0x5e, 0x78, 0x6a, 0x4e, 0x8e, 0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0x48, 0x4b, + 0x12, 0x1b, 0xd8, 0x0c, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x19, 0x6c, 0xb9, 0xb8, 0xfe, + 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.proto b/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.proto new file mode 100644 index 000000000..01947639a --- /dev/null +++ b/vendor/github.com/golang/protobuf/ptypes/wrappers/wrappers.proto @@ -0,0 +1,118 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/wrappers"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "WrappersProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +message BytesValue { + // The bytes value. + bytes value = 1; +} diff --git a/vendor/github.com/google/go-querystring/LICENSE b/vendor/github.com/google/go-querystring/LICENSE new file mode 100644 index 000000000..ae121a1e4 --- /dev/null +++ b/vendor/github.com/google/go-querystring/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013 Google. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/google/go-querystring/query/encode.go b/vendor/github.com/google/go-querystring/query/encode.go new file mode 100644 index 000000000..37080b19b --- /dev/null +++ b/vendor/github.com/google/go-querystring/query/encode.go @@ -0,0 +1,320 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package query implements encoding of structs into URL query parameters. +// +// As a simple example: +// +// type Options struct { +// Query string `url:"q"` +// ShowAll bool `url:"all"` +// Page int `url:"page"` +// } +// +// opt := Options{ "foo", true, 2 } +// v, _ := query.Values(opt) +// fmt.Print(v.Encode()) // will output: "q=foo&all=true&page=2" +// +// The exact mapping between Go values and url.Values is described in the +// documentation for the Values() function. +package query + +import ( + "bytes" + "fmt" + "net/url" + "reflect" + "strconv" + "strings" + "time" +) + +var timeType = reflect.TypeOf(time.Time{}) + +var encoderType = reflect.TypeOf(new(Encoder)).Elem() + +// Encoder is an interface implemented by any type that wishes to encode +// itself into URL values in a non-standard way. +type Encoder interface { + EncodeValues(key string, v *url.Values) error +} + +// Values returns the url.Values encoding of v. +// +// Values expects to be passed a struct, and traverses it recursively using the +// following encoding rules. +// +// Each exported struct field is encoded as a URL parameter unless +// +// - the field's tag is "-", or +// - the field is empty and its tag specifies the "omitempty" option +// +// The empty values are false, 0, any nil pointer or interface value, any array +// slice, map, or string of length zero, and any time.Time that returns true +// for IsZero(). +// +// The URL parameter name defaults to the struct field name but can be +// specified in the struct field's tag value. The "url" key in the struct +// field's tag value is the key name, followed by an optional comma and +// options. For example: +// +// // Field is ignored by this package. +// Field int `url:"-"` +// +// // Field appears as URL parameter "myName". +// Field int `url:"myName"` +// +// // Field appears as URL parameter "myName" and the field is omitted if +// // its value is empty +// Field int `url:"myName,omitempty"` +// +// // Field appears as URL parameter "Field" (the default), but the field +// // is skipped if empty. Note the leading comma. +// Field int `url:",omitempty"` +// +// For encoding individual field values, the following type-dependent rules +// apply: +// +// Boolean values default to encoding as the strings "true" or "false". +// Including the "int" option signals that the field should be encoded as the +// strings "1" or "0". +// +// time.Time values default to encoding as RFC3339 timestamps. Including the +// "unix" option signals that the field should be encoded as a Unix time (see +// time.Unix()) +// +// Slice and Array values default to encoding as multiple URL values of the +// same name. Including the "comma" option signals that the field should be +// encoded as a single comma-delimited value. Including the "space" option +// similarly encodes the value as a single space-delimited string. Including +// the "semicolon" option will encode the value as a semicolon-delimited string. +// Including the "brackets" option signals that the multiple URL values should +// have "[]" appended to the value name. "numbered" will append a number to +// the end of each incidence of the value name, example: +// name0=value0&name1=value1, etc. +// +// Anonymous struct fields are usually encoded as if their inner exported +// fields were fields in the outer struct, subject to the standard Go +// visibility rules. An anonymous struct field with a name given in its URL +// tag is treated as having that name, rather than being anonymous. +// +// Non-nil pointer values are encoded as the value pointed to. +// +// Nested structs are encoded including parent fields in value names for +// scoping. e.g: +// +// "user[name]=acme&user[addr][postcode]=1234&user[addr][city]=SFO" +// +// All other values are encoded using their default string representation. +// +// Multiple fields that encode to the same URL parameter name will be included +// as multiple URL values of the same name. +func Values(v interface{}) (url.Values, error) { + values := make(url.Values) + val := reflect.ValueOf(v) + for val.Kind() == reflect.Ptr { + if val.IsNil() { + return values, nil + } + val = val.Elem() + } + + if v == nil { + return values, nil + } + + if val.Kind() != reflect.Struct { + return nil, fmt.Errorf("query: Values() expects struct input. Got %v", val.Kind()) + } + + err := reflectValue(values, val, "") + return values, err +} + +// reflectValue populates the values parameter from the struct fields in val. +// Embedded structs are followed recursively (using the rules defined in the +// Values function documentation) breadth-first. +func reflectValue(values url.Values, val reflect.Value, scope string) error { + var embedded []reflect.Value + + typ := val.Type() + for i := 0; i < typ.NumField(); i++ { + sf := typ.Field(i) + if sf.PkgPath != "" && !sf.Anonymous { // unexported + continue + } + + sv := val.Field(i) + tag := sf.Tag.Get("url") + if tag == "-" { + continue + } + name, opts := parseTag(tag) + if name == "" { + if sf.Anonymous && sv.Kind() == reflect.Struct { + // save embedded struct for later processing + embedded = append(embedded, sv) + continue + } + + name = sf.Name + } + + if scope != "" { + name = scope + "[" + name + "]" + } + + if opts.Contains("omitempty") && isEmptyValue(sv) { + continue + } + + if sv.Type().Implements(encoderType) { + if !reflect.Indirect(sv).IsValid() { + sv = reflect.New(sv.Type().Elem()) + } + + m := sv.Interface().(Encoder) + if err := m.EncodeValues(name, &values); err != nil { + return err + } + continue + } + + if sv.Kind() == reflect.Slice || sv.Kind() == reflect.Array { + var del byte + if opts.Contains("comma") { + del = ',' + } else if opts.Contains("space") { + del = ' ' + } else if opts.Contains("semicolon") { + del = ';' + } else if opts.Contains("brackets") { + name = name + "[]" + } + + if del != 0 { + s := new(bytes.Buffer) + first := true + for i := 0; i < sv.Len(); i++ { + if first { + first = false + } else { + s.WriteByte(del) + } + s.WriteString(valueString(sv.Index(i), opts)) + } + values.Add(name, s.String()) + } else { + for i := 0; i < sv.Len(); i++ { + k := name + if opts.Contains("numbered") { + k = fmt.Sprintf("%s%d", name, i) + } + values.Add(k, valueString(sv.Index(i), opts)) + } + } + continue + } + + for sv.Kind() == reflect.Ptr { + if sv.IsNil() { + break + } + sv = sv.Elem() + } + + if sv.Type() == timeType { + values.Add(name, valueString(sv, opts)) + continue + } + + if sv.Kind() == reflect.Struct { + reflectValue(values, sv, name) + continue + } + + values.Add(name, valueString(sv, opts)) + } + + for _, f := range embedded { + if err := reflectValue(values, f, scope); err != nil { + return err + } + } + + return nil +} + +// valueString returns the string representation of a value. +func valueString(v reflect.Value, opts tagOptions) string { + for v.Kind() == reflect.Ptr { + if v.IsNil() { + return "" + } + v = v.Elem() + } + + if v.Kind() == reflect.Bool && opts.Contains("int") { + if v.Bool() { + return "1" + } + return "0" + } + + if v.Type() == timeType { + t := v.Interface().(time.Time) + if opts.Contains("unix") { + return strconv.FormatInt(t.Unix(), 10) + } + return t.Format(time.RFC3339) + } + + return fmt.Sprint(v.Interface()) +} + +// isEmptyValue checks if a value should be considered empty for the purposes +// of omitting fields with the "omitempty" option. +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + + if v.Type() == timeType { + return v.Interface().(time.Time).IsZero() + } + + return false +} + +// tagOptions is the string following a comma in a struct field's "url" tag, or +// the empty string. It does not include the leading comma. +type tagOptions []string + +// parseTag splits a struct field's url tag into its name and comma-separated +// options. +func parseTag(tag string) (string, tagOptions) { + s := strings.Split(tag, ",") + return s[0], s[1:] +} + +// Contains checks whether the tagOptions contains the specified option. +func (o tagOptions) Contains(option string) bool { + for _, s := range o { + if s == option { + return true + } + } + return false +} diff --git a/vendor/github.com/google/uuid/.travis.yml b/vendor/github.com/google/uuid/.travis.yml new file mode 100644 index 000000000..d8156a60b --- /dev/null +++ b/vendor/github.com/google/uuid/.travis.yml @@ -0,0 +1,9 @@ +language: go + +go: + - 1.4.3 + - 1.5.3 + - tip + +script: + - go test -v ./... diff --git a/vendor/github.com/google/uuid/CONTRIBUTING.md b/vendor/github.com/google/uuid/CONTRIBUTING.md new file mode 100644 index 000000000..04fdf09f1 --- /dev/null +++ b/vendor/github.com/google/uuid/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# How to contribute + +We definitely welcome patches and contribution to this project! + +### Legal requirements + +In order to protect both you and ourselves, you will need to sign the +[Contributor License Agreement](https://cla.developers.google.com/clas). + +You may have already signed it for other Google projects. diff --git a/vendor/github.com/google/uuid/CONTRIBUTORS b/vendor/github.com/google/uuid/CONTRIBUTORS new file mode 100644 index 000000000..b4bb97f6b --- /dev/null +++ b/vendor/github.com/google/uuid/CONTRIBUTORS @@ -0,0 +1,9 @@ +Paul Borman +bmatsuo +shawnps +theory +jboverfelt +dsymonds +cd1 +wallclockbuilder +dansouza diff --git a/vendor/github.com/google/uuid/LICENSE b/vendor/github.com/google/uuid/LICENSE new file mode 100644 index 000000000..5dc68268d --- /dev/null +++ b/vendor/github.com/google/uuid/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009,2014 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/google/uuid/README.md b/vendor/github.com/google/uuid/README.md new file mode 100644 index 000000000..9d92c11f1 --- /dev/null +++ b/vendor/github.com/google/uuid/README.md @@ -0,0 +1,19 @@ +# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master) +The uuid package generates and inspects UUIDs based on +[RFC 4122](http://tools.ietf.org/html/rfc4122) +and DCE 1.1: Authentication and Security Services. + +This package is based on the github.com/pborman/uuid package (previously named +code.google.com/p/go-uuid). It differs from these earlier packages in that +a UUID is a 16 byte array rather than a byte slice. One loss due to this +change is the ability to represent an invalid UUID (vs a NIL UUID). + +###### Install +`go get github.com/google/uuid` + +###### Documentation +[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid) + +Full `go doc` style documentation for the package can be viewed online without +installing this package by using the GoDoc site here: +http://godoc.org/github.com/google/uuid diff --git a/vendor/github.com/google/uuid/dce.go b/vendor/github.com/google/uuid/dce.go new file mode 100644 index 000000000..fa820b9d3 --- /dev/null +++ b/vendor/github.com/google/uuid/dce.go @@ -0,0 +1,80 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" + "fmt" + "os" +) + +// A Domain represents a Version 2 domain +type Domain byte + +// Domain constants for DCE Security (Version 2) UUIDs. +const ( + Person = Domain(0) + Group = Domain(1) + Org = Domain(2) +) + +// NewDCESecurity returns a DCE Security (Version 2) UUID. +// +// The domain should be one of Person, Group or Org. +// On a POSIX system the id should be the users UID for the Person +// domain and the users GID for the Group. The meaning of id for +// the domain Org or on non-POSIX systems is site defined. +// +// For a given domain/id pair the same token may be returned for up to +// 7 minutes and 10 seconds. +func NewDCESecurity(domain Domain, id uint32) (UUID, error) { + uuid, err := NewUUID() + if err == nil { + uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 + uuid[9] = byte(domain) + binary.BigEndian.PutUint32(uuid[0:], id) + } + return uuid, err +} + +// NewDCEPerson returns a DCE Security (Version 2) UUID in the person +// domain with the id returned by os.Getuid. +// +// NewDCESecurity(Person, uint32(os.Getuid())) +func NewDCEPerson() (UUID, error) { + return NewDCESecurity(Person, uint32(os.Getuid())) +} + +// NewDCEGroup returns a DCE Security (Version 2) UUID in the group +// domain with the id returned by os.Getgid. +// +// NewDCESecurity(Group, uint32(os.Getgid())) +func NewDCEGroup() (UUID, error) { + return NewDCESecurity(Group, uint32(os.Getgid())) +} + +// Domain returns the domain for a Version 2 UUID. Domains are only defined +// for Version 2 UUIDs. +func (uuid UUID) Domain() Domain { + return Domain(uuid[9]) +} + +// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2 +// UUIDs. +func (uuid UUID) ID() uint32 { + return binary.BigEndian.Uint32(uuid[0:4]) +} + +func (d Domain) String() string { + switch d { + case Person: + return "Person" + case Group: + return "Group" + case Org: + return "Org" + } + return fmt.Sprintf("Domain%d", int(d)) +} diff --git a/vendor/github.com/google/uuid/doc.go b/vendor/github.com/google/uuid/doc.go new file mode 100644 index 000000000..5b8a4b9af --- /dev/null +++ b/vendor/github.com/google/uuid/doc.go @@ -0,0 +1,12 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package uuid generates and inspects UUIDs. +// +// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security +// Services. +// +// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to +// maps or compared directly. +package uuid diff --git a/vendor/github.com/google/uuid/go.mod b/vendor/github.com/google/uuid/go.mod new file mode 100644 index 000000000..fc84cd79d --- /dev/null +++ b/vendor/github.com/google/uuid/go.mod @@ -0,0 +1 @@ +module github.com/google/uuid diff --git a/vendor/github.com/google/uuid/hash.go b/vendor/github.com/google/uuid/hash.go new file mode 100644 index 000000000..b17461631 --- /dev/null +++ b/vendor/github.com/google/uuid/hash.go @@ -0,0 +1,53 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "crypto/md5" + "crypto/sha1" + "hash" +) + +// Well known namespace IDs and UUIDs +var ( + NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) + Nil UUID // empty UUID, all zeros +) + +// NewHash returns a new UUID derived from the hash of space concatenated with +// data generated by h. The hash should be at least 16 byte in length. The +// first 16 bytes of the hash are used to form the UUID. The version of the +// UUID will be the lower 4 bits of version. NewHash is used to implement +// NewMD5 and NewSHA1. +func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { + h.Reset() + h.Write(space[:]) + h.Write(data) + s := h.Sum(nil) + var uuid UUID + copy(uuid[:], s) + uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) + uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant + return uuid +} + +// NewMD5 returns a new MD5 (Version 3) UUID based on the +// supplied name space and data. It is the same as calling: +// +// NewHash(md5.New(), space, data, 3) +func NewMD5(space UUID, data []byte) UUID { + return NewHash(md5.New(), space, data, 3) +} + +// NewSHA1 returns a new SHA1 (Version 5) UUID based on the +// supplied name space and data. It is the same as calling: +// +// NewHash(sha1.New(), space, data, 5) +func NewSHA1(space UUID, data []byte) UUID { + return NewHash(sha1.New(), space, data, 5) +} diff --git a/vendor/github.com/google/uuid/marshal.go b/vendor/github.com/google/uuid/marshal.go new file mode 100644 index 000000000..7f9e0c6c0 --- /dev/null +++ b/vendor/github.com/google/uuid/marshal.go @@ -0,0 +1,37 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "fmt" + +// MarshalText implements encoding.TextMarshaler. +func (uuid UUID) MarshalText() ([]byte, error) { + var js [36]byte + encodeHex(js[:], uuid) + return js[:], nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (uuid *UUID) UnmarshalText(data []byte) error { + id, err := ParseBytes(data) + if err == nil { + *uuid = id + } + return err +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (uuid UUID) MarshalBinary() ([]byte, error) { + return uuid[:], nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (uuid *UUID) UnmarshalBinary(data []byte) error { + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + copy(uuid[:], data) + return nil +} diff --git a/vendor/github.com/google/uuid/node.go b/vendor/github.com/google/uuid/node.go new file mode 100644 index 000000000..d651a2b06 --- /dev/null +++ b/vendor/github.com/google/uuid/node.go @@ -0,0 +1,90 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "sync" +) + +var ( + nodeMu sync.Mutex + ifname string // name of interface being used + nodeID [6]byte // hardware for version 1 UUIDs + zeroID [6]byte // nodeID with only 0's +) + +// NodeInterface returns the name of the interface from which the NodeID was +// derived. The interface "user" is returned if the NodeID was set by +// SetNodeID. +func NodeInterface() string { + defer nodeMu.Unlock() + nodeMu.Lock() + return ifname +} + +// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. +// If name is "" then the first usable interface found will be used or a random +// Node ID will be generated. If a named interface cannot be found then false +// is returned. +// +// SetNodeInterface never fails when name is "". +func SetNodeInterface(name string) bool { + defer nodeMu.Unlock() + nodeMu.Lock() + return setNodeInterface(name) +} + +func setNodeInterface(name string) bool { + iname, addr := getHardwareInterface(name) // null implementation for js + if iname != "" && addr != nil { + ifname = iname + copy(nodeID[:], addr) + return true + } + + // We found no interfaces with a valid hardware address. If name + // does not specify a specific interface generate a random Node ID + // (section 4.1.6) + if name == "" { + ifname = "random" + randomBits(nodeID[:]) + return true + } + return false +} + +// NodeID returns a slice of a copy of the current Node ID, setting the Node ID +// if not already set. +func NodeID() []byte { + defer nodeMu.Unlock() + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + nid := nodeID + return nid[:] +} + +// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes +// of id are used. If id is less than 6 bytes then false is returned and the +// Node ID is not set. +func SetNodeID(id []byte) bool { + if len(id) < 6 { + return false + } + defer nodeMu.Unlock() + nodeMu.Lock() + copy(nodeID[:], id) + ifname = "user" + return true +} + +// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is +// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. +func (uuid UUID) NodeID() []byte { + var node [6]byte + copy(node[:], uuid[10:]) + return node[:] +} diff --git a/vendor/github.com/google/uuid/node_js.go b/vendor/github.com/google/uuid/node_js.go new file mode 100644 index 000000000..24b78edc9 --- /dev/null +++ b/vendor/github.com/google/uuid/node_js.go @@ -0,0 +1,12 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build js + +package uuid + +// getHardwareInterface returns nil values for the JS version of the code. +// This remvoves the "net" dependency, because it is not used in the browser. +// Using the "net" library inflates the size of the transpiled JS code by 673k bytes. +func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/vendor/github.com/google/uuid/node_net.go b/vendor/github.com/google/uuid/node_net.go new file mode 100644 index 000000000..0cbbcddbd --- /dev/null +++ b/vendor/github.com/google/uuid/node_net.go @@ -0,0 +1,33 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !js + +package uuid + +import "net" + +var interfaces []net.Interface // cached list of interfaces + +// getHardwareInterface returns the name and hardware address of interface name. +// If name is "" then the name and hardware address of one of the system's +// interfaces is returned. If no interfaces are found (name does not exist or +// there are no interfaces) then "", nil is returned. +// +// Only addresses of at least 6 bytes are returned. +func getHardwareInterface(name string) (string, []byte) { + if interfaces == nil { + var err error + interfaces, err = net.Interfaces() + if err != nil { + return "", nil + } + } + for _, ifs := range interfaces { + if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { + return ifs.Name, ifs.HardwareAddr + } + } + return "", nil +} diff --git a/vendor/github.com/google/uuid/sql.go b/vendor/github.com/google/uuid/sql.go new file mode 100644 index 000000000..f326b54db --- /dev/null +++ b/vendor/github.com/google/uuid/sql.go @@ -0,0 +1,59 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "database/sql/driver" + "fmt" +) + +// Scan implements sql.Scanner so UUIDs can be read from databases transparently +// Currently, database types that map to string and []byte are supported. Please +// consult database-specific driver documentation for matching types. +func (uuid *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case nil: + return nil + + case string: + // if an empty UUID comes from a table, we return a null UUID + if src == "" { + return nil + } + + // see Parse for required string format + u, err := Parse(src) + if err != nil { + return fmt.Errorf("Scan: %v", err) + } + + *uuid = u + + case []byte: + // if an empty UUID comes from a table, we return a null UUID + if len(src) == 0 { + return nil + } + + // assumes a simple slice of bytes if 16 bytes + // otherwise attempts to parse + if len(src) != 16 { + return uuid.Scan(string(src)) + } + copy((*uuid)[:], src) + + default: + return fmt.Errorf("Scan: unable to scan type %T into UUID", src) + } + + return nil +} + +// Value implements sql.Valuer so that UUIDs can be written to databases +// transparently. Currently, UUIDs map to strings. Please consult +// database-specific driver documentation for matching types. +func (uuid UUID) Value() (driver.Value, error) { + return uuid.String(), nil +} diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go new file mode 100644 index 000000000..e6ef06cdc --- /dev/null +++ b/vendor/github.com/google/uuid/time.go @@ -0,0 +1,123 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" + "sync" + "time" +) + +// A Time represents a time as the number of 100's of nanoseconds since 15 Oct +// 1582. +type Time int64 + +const ( + lillian = 2299160 // Julian day of 15 Oct 1582 + unix = 2440587 // Julian day of 1 Jan 1970 + epoch = unix - lillian // Days between epochs + g1582 = epoch * 86400 // seconds between epochs + g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs +) + +var ( + timeMu sync.Mutex + lasttime uint64 // last time we returned + clockSeq uint16 // clock sequence for this run + + timeNow = time.Now // for testing +) + +// UnixTime converts t the number of seconds and nanoseconds using the Unix +// epoch of 1 Jan 1970. +func (t Time) UnixTime() (sec, nsec int64) { + sec = int64(t - g1582ns100) + nsec = (sec % 10000000) * 100 + sec /= 10000000 + return sec, nsec +} + +// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and +// clock sequence as well as adjusting the clock sequence as needed. An error +// is returned if the current time cannot be determined. +func GetTime() (Time, uint16, error) { + defer timeMu.Unlock() + timeMu.Lock() + return getTime() +} + +func getTime() (Time, uint16, error) { + t := timeNow() + + // If we don't have a clock sequence already, set one. + if clockSeq == 0 { + setClockSequence(-1) + } + now := uint64(t.UnixNano()/100) + g1582ns100 + + // If time has gone backwards with this clock sequence then we + // increment the clock sequence + if now <= lasttime { + clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000 + } + lasttime = now + return Time(now), clockSeq, nil +} + +// ClockSequence returns the current clock sequence, generating one if not +// already set. The clock sequence is only used for Version 1 UUIDs. +// +// The uuid package does not use global static storage for the clock sequence or +// the last time a UUID was generated. Unless SetClockSequence is used, a new +// random clock sequence is generated the first time a clock sequence is +// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) +func ClockSequence() int { + defer timeMu.Unlock() + timeMu.Lock() + return clockSequence() +} + +func clockSequence() int { + if clockSeq == 0 { + setClockSequence(-1) + } + return int(clockSeq & 0x3fff) +} + +// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to +// -1 causes a new sequence to be generated. +func SetClockSequence(seq int) { + defer timeMu.Unlock() + timeMu.Lock() + setClockSequence(seq) +} + +func setClockSequence(seq int) { + if seq == -1 { + var b [2]byte + randomBits(b[:]) // clock sequence + seq = int(b[0])<<8 | int(b[1]) + } + oldSeq := clockSeq + clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant + if oldSeq != clockSeq { + lasttime = 0 + } +} + +// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in +// uuid. The time is only defined for version 1 and 2 UUIDs. +func (uuid UUID) Time() Time { + time := int64(binary.BigEndian.Uint32(uuid[0:4])) + time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 + time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 + return Time(time) +} + +// ClockSequence returns the clock sequence encoded in uuid. +// The clock sequence is only well defined for version 1 and 2 UUIDs. +func (uuid UUID) ClockSequence() int { + return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff +} diff --git a/vendor/github.com/google/uuid/util.go b/vendor/github.com/google/uuid/util.go new file mode 100644 index 000000000..5ea6c7378 --- /dev/null +++ b/vendor/github.com/google/uuid/util.go @@ -0,0 +1,43 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// randomBits completely fills slice b with random data. +func randomBits(b []byte) { + if _, err := io.ReadFull(rander, b); err != nil { + panic(err.Error()) // rand should never fail + } +} + +// xvalues returns the value of a byte as a hexadecimal digit or 255. +var xvalues = [256]byte{ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +} + +// xtob converts hex characters x1 and x2 into a byte. +func xtob(x1, x2 byte) (byte, bool) { + b1 := xvalues[x1] + b2 := xvalues[x2] + return (b1 << 4) | b2, b1 != 255 && b2 != 255 +} diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go new file mode 100644 index 000000000..524404cc5 --- /dev/null +++ b/vendor/github.com/google/uuid/uuid.go @@ -0,0 +1,245 @@ +// Copyright 2018 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "crypto/rand" + "encoding/hex" + "errors" + "fmt" + "io" + "strings" +) + +// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC +// 4122. +type UUID [16]byte + +// A Version represents a UUID's version. +type Version byte + +// A Variant represents a UUID's variant. +type Variant byte + +// Constants returned by Variant. +const ( + Invalid = Variant(iota) // Invalid UUID + RFC4122 // The variant specified in RFC4122 + Reserved // Reserved, NCS backward compatibility. + Microsoft // Reserved, Microsoft Corporation backward compatibility. + Future // Reserved for future definition. +) + +var rander = rand.Reader // random function + +// Parse decodes s into a UUID or returns an error. Both the standard UUID +// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the +// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex +// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. +func Parse(s string) (UUID, error) { + var uuid UUID + switch len(s) { + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36: + + // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36 + 9: + if strings.ToLower(s[:9]) != "urn:uuid:" { + return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + + // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} + case 36 + 2: + s = s[1:] + + // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + case 32: + var ok bool + for i := range uuid { + uuid[i], ok = xtob(s[i*2], s[i*2+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + } + return uuid, nil + default: + return uuid, fmt.Errorf("invalid UUID length: %d", len(s)) + } + // s is now at least 36 bytes long + // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34} { + v, ok := xtob(s[x], s[x+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + uuid[i] = v + } + return uuid, nil +} + +// ParseBytes is like Parse, except it parses a byte slice instead of a string. +func ParseBytes(b []byte) (UUID, error) { + var uuid UUID + switch len(b) { + case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) { + return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) + } + b = b[9:] + case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} + b = b[1:] + case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + var ok bool + for i := 0; i < 32; i += 2 { + uuid[i/2], ok = xtob(b[i], b[i+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + } + return uuid, nil + default: + return uuid, fmt.Errorf("invalid UUID length: %d", len(b)) + } + // s is now at least 36 bytes long + // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34} { + v, ok := xtob(b[x], b[x+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + uuid[i] = v + } + return uuid, nil +} + +// MustParse is like Parse but panics if the string cannot be parsed. +// It simplifies safe initialization of global variables holding compiled UUIDs. +func MustParse(s string) UUID { + uuid, err := Parse(s) + if err != nil { + panic(`uuid: Parse(` + s + `): ` + err.Error()) + } + return uuid +} + +// FromBytes creates a new UUID from a byte slice. Returns an error if the slice +// does not have a length of 16. The bytes are copied from the slice. +func FromBytes(b []byte) (uuid UUID, err error) { + err = uuid.UnmarshalBinary(b) + return uuid, err +} + +// Must returns uuid if err is nil and panics otherwise. +func Must(uuid UUID, err error) UUID { + if err != nil { + panic(err) + } + return uuid +} + +// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// , or "" if uuid is invalid. +func (uuid UUID) String() string { + var buf [36]byte + encodeHex(buf[:], uuid) + return string(buf[:]) +} + +// URN returns the RFC 2141 URN form of uuid, +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. +func (uuid UUID) URN() string { + var buf [36 + 9]byte + copy(buf[:], "urn:uuid:") + encodeHex(buf[9:], uuid) + return string(buf[:]) +} + +func encodeHex(dst []byte, uuid UUID) { + hex.Encode(dst, uuid[:4]) + dst[8] = '-' + hex.Encode(dst[9:13], uuid[4:6]) + dst[13] = '-' + hex.Encode(dst[14:18], uuid[6:8]) + dst[18] = '-' + hex.Encode(dst[19:23], uuid[8:10]) + dst[23] = '-' + hex.Encode(dst[24:], uuid[10:]) +} + +// Variant returns the variant encoded in uuid. +func (uuid UUID) Variant() Variant { + switch { + case (uuid[8] & 0xc0) == 0x80: + return RFC4122 + case (uuid[8] & 0xe0) == 0xc0: + return Microsoft + case (uuid[8] & 0xe0) == 0xe0: + return Future + default: + return Reserved + } +} + +// Version returns the version of uuid. +func (uuid UUID) Version() Version { + return Version(uuid[6] >> 4) +} + +func (v Version) String() string { + if v > 15 { + return fmt.Sprintf("BAD_VERSION_%d", v) + } + return fmt.Sprintf("VERSION_%d", v) +} + +func (v Variant) String() string { + switch v { + case RFC4122: + return "RFC4122" + case Reserved: + return "Reserved" + case Microsoft: + return "Microsoft" + case Future: + return "Future" + case Invalid: + return "Invalid" + } + return fmt.Sprintf("BadVariant%d", int(v)) +} + +// SetRand sets the random number generator to r, which implements io.Reader. +// If r.Read returns an error when the package requests random data then +// a panic will be issued. +// +// Calling SetRand with nil sets the random number generator to the default +// generator. +func SetRand(r io.Reader) { + if r == nil { + rander = rand.Reader + return + } + rander = r +} diff --git a/vendor/github.com/google/uuid/version1.go b/vendor/github.com/google/uuid/version1.go new file mode 100644 index 000000000..199a1ac65 --- /dev/null +++ b/vendor/github.com/google/uuid/version1.go @@ -0,0 +1,44 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" +) + +// NewUUID returns a Version 1 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewUUID returns nil. If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewUUID returns nil and an error. +// +// In most cases, New should be used. +func NewUUID() (UUID, error) { + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + nodeMu.Unlock() + + var uuid UUID + now, seq, err := GetTime() + if err != nil { + return uuid, err + } + + timeLow := uint32(now & 0xffffffff) + timeMid := uint16((now >> 32) & 0xffff) + timeHi := uint16((now >> 48) & 0x0fff) + timeHi |= 0x1000 // Version 1 + + binary.BigEndian.PutUint32(uuid[0:], timeLow) + binary.BigEndian.PutUint16(uuid[4:], timeMid) + binary.BigEndian.PutUint16(uuid[6:], timeHi) + binary.BigEndian.PutUint16(uuid[8:], seq) + copy(uuid[10:], nodeID[:]) + + return uuid, nil +} diff --git a/vendor/github.com/google/uuid/version4.go b/vendor/github.com/google/uuid/version4.go new file mode 100644 index 000000000..84af91c9f --- /dev/null +++ b/vendor/github.com/google/uuid/version4.go @@ -0,0 +1,38 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "io" + +// New creates a new random UUID or panics. New is equivalent to +// the expression +// +// uuid.Must(uuid.NewRandom()) +func New() UUID { + return Must(NewRandom()) +} + +// NewRandom returns a Random (Version 4) UUID. +// +// The strength of the UUIDs is based on the strength of the crypto/rand +// package. +// +// A note about uniqueness derived from the UUID Wikipedia entry: +// +// Randomly generated UUIDs have 122 random bits. One's annual risk of being +// hit by a meteorite is estimated to be one chance in 17 billion, that +// means the probability is about 0.00000000006 (6 × 10−11), +// equivalent to the odds of creating a few tens of trillions of UUIDs in a +// year and having one duplicate. +func NewRandom() (UUID, error) { + var uuid UUID + _, err := io.ReadFull(rander, uuid[:]) + if err != nil { + return Nil, err + } + uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 + uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 + return uuid, nil +} diff --git a/vendor/github.com/googleapis/gax-go/v2/LICENSE b/vendor/github.com/googleapis/gax-go/v2/LICENSE new file mode 100644 index 000000000..6d16b6578 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/LICENSE @@ -0,0 +1,27 @@ +Copyright 2016, Google Inc. +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/googleapis/gax-go/v2/call_option.go b/vendor/github.com/googleapis/gax-go/v2/call_option.go new file mode 100644 index 000000000..b1d53dd19 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/call_option.go @@ -0,0 +1,161 @@ +// Copyright 2016, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package gax + +import ( + "math/rand" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// CallOption is an option used by Invoke to control behaviors of RPC calls. +// CallOption works by modifying relevant fields of CallSettings. +type CallOption interface { + // Resolve applies the option by modifying cs. + Resolve(cs *CallSettings) +} + +// Retryer is used by Invoke to determine retry behavior. +type Retryer interface { + // Retry reports whether a request should be retriedand how long to pause before retrying + // if the previous attempt returned with err. Invoke never calls Retry with nil error. + Retry(err error) (pause time.Duration, shouldRetry bool) +} + +type retryerOption func() Retryer + +func (o retryerOption) Resolve(s *CallSettings) { + s.Retry = o +} + +// WithRetry sets CallSettings.Retry to fn. +func WithRetry(fn func() Retryer) CallOption { + return retryerOption(fn) +} + +// OnCodes returns a Retryer that retries if and only if +// the previous attempt returns a GRPC error whose error code is stored in cc. +// Pause times between retries are specified by bo. +// +// bo is only used for its parameters; each Retryer has its own copy. +func OnCodes(cc []codes.Code, bo Backoff) Retryer { + return &boRetryer{ + backoff: bo, + codes: append([]codes.Code(nil), cc...), + } +} + +type boRetryer struct { + backoff Backoff + codes []codes.Code +} + +func (r *boRetryer) Retry(err error) (time.Duration, bool) { + st, ok := status.FromError(err) + if !ok { + return 0, false + } + c := st.Code() + for _, rc := range r.codes { + if c == rc { + return r.backoff.Pause(), true + } + } + return 0, false +} + +// Backoff implements exponential backoff. +// The wait time between retries is a random value between 0 and the "retry envelope". +// The envelope starts at Initial and increases by the factor of Multiplier every retry, +// but is capped at Max. +type Backoff struct { + // Initial is the initial value of the retry envelope, defaults to 1 second. + Initial time.Duration + + // Max is the maximum value of the retry envelope, defaults to 30 seconds. + Max time.Duration + + // Multiplier is the factor by which the retry envelope increases. + // It should be greater than 1 and defaults to 2. + Multiplier float64 + + // cur is the current retry envelope + cur time.Duration +} + +// Pause returns the next time.Duration that the caller should use to backoff. +func (bo *Backoff) Pause() time.Duration { + if bo.Initial == 0 { + bo.Initial = time.Second + } + if bo.cur == 0 { + bo.cur = bo.Initial + } + if bo.Max == 0 { + bo.Max = 30 * time.Second + } + if bo.Multiplier < 1 { + bo.Multiplier = 2 + } + // Select a duration between 1ns and the current max. It might seem + // counterintuitive to have so much jitter, but + // https://www.awsarchitectureblog.com/2015/03/backoff.html argues that + // that is the best strategy. + d := time.Duration(1 + rand.Int63n(int64(bo.cur))) + bo.cur = time.Duration(float64(bo.cur) * bo.Multiplier) + if bo.cur > bo.Max { + bo.cur = bo.Max + } + return d +} + +type grpcOpt []grpc.CallOption + +func (o grpcOpt) Resolve(s *CallSettings) { + s.GRPC = o +} + +// WithGRPCOptions allows passing gRPC call options during client creation. +func WithGRPCOptions(opt ...grpc.CallOption) CallOption { + return grpcOpt(append([]grpc.CallOption(nil), opt...)) +} + +// CallSettings allow fine-grained control over how calls are made. +type CallSettings struct { + // Retry returns a Retryer to be used to control retry logic of a method call. + // If Retry is nil or the returned Retryer is nil, the call will not be retried. + Retry func() Retryer + + // CallOptions to be forwarded to GRPC. + GRPC []grpc.CallOption +} diff --git a/vendor/github.com/googleapis/gax-go/v2/gax.go b/vendor/github.com/googleapis/gax-go/v2/gax.go new file mode 100644 index 000000000..3fd1b0b84 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/gax.go @@ -0,0 +1,39 @@ +// Copyright 2016, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Package gax contains a set of modules which aid the development of APIs +// for clients and servers based on gRPC and Google API conventions. +// +// Application code will rarely need to use this library directly. +// However, code generated automatically from API definition files can use it +// to simplify code generation and to provide more convenient and idiomatic API surfaces. +package gax + +// Version specifies the gax-go version being used. +const Version = "2.0.4" diff --git a/vendor/github.com/googleapis/gax-go/v2/go.mod b/vendor/github.com/googleapis/gax-go/v2/go.mod new file mode 100644 index 000000000..9cdfaf447 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/go.mod @@ -0,0 +1,3 @@ +module github.com/googleapis/gax-go/v2 + +require google.golang.org/grpc v1.19.0 diff --git a/vendor/github.com/googleapis/gax-go/v2/go.sum b/vendor/github.com/googleapis/gax-go/v2/go.sum new file mode 100644 index 000000000..7fa23ecf9 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/go.sum @@ -0,0 +1,25 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522 h1:Ve1ORMCxvRmSXBwJK+t3Oy+V2vRW2OetUQBq4rJIkZE= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/googleapis/gax-go/v2/header.go b/vendor/github.com/googleapis/gax-go/v2/header.go new file mode 100644 index 000000000..139371a0b --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/header.go @@ -0,0 +1,53 @@ +// Copyright 2018, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package gax + +import "bytes" + +// XGoogHeader is for use by the Google Cloud Libraries only. +// +// XGoogHeader formats key-value pairs. +// The resulting string is suitable for x-goog-api-client header. +func XGoogHeader(keyval ...string) string { + if len(keyval) == 0 { + return "" + } + if len(keyval)%2 != 0 { + panic("gax.Header: odd argument count") + } + var buf bytes.Buffer + for i := 0; i < len(keyval); i += 2 { + buf.WriteByte(' ') + buf.WriteString(keyval[i]) + buf.WriteByte('/') + buf.WriteString(keyval[i+1]) + } + return buf.String()[1:] +} diff --git a/vendor/github.com/googleapis/gax-go/v2/invoke.go b/vendor/github.com/googleapis/gax-go/v2/invoke.go new file mode 100644 index 000000000..fe31dd004 --- /dev/null +++ b/vendor/github.com/googleapis/gax-go/v2/invoke.go @@ -0,0 +1,99 @@ +// Copyright 2016, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package gax + +import ( + "context" + "strings" + "time" +) + +// APICall is a user defined call stub. +type APICall func(context.Context, CallSettings) error + +// Invoke calls the given APICall, +// performing retries as specified by opts, if any. +func Invoke(ctx context.Context, call APICall, opts ...CallOption) error { + var settings CallSettings + for _, opt := range opts { + opt.Resolve(&settings) + } + return invoke(ctx, call, settings, Sleep) +} + +// Sleep is similar to time.Sleep, but it can be interrupted by ctx.Done() closing. +// If interrupted, Sleep returns ctx.Err(). +func Sleep(ctx context.Context, d time.Duration) error { + t := time.NewTimer(d) + select { + case <-ctx.Done(): + t.Stop() + return ctx.Err() + case <-t.C: + return nil + } +} + +type sleeper func(ctx context.Context, d time.Duration) error + +// invoke implements Invoke, taking an additional sleeper argument for testing. +func invoke(ctx context.Context, call APICall, settings CallSettings, sp sleeper) error { + var retryer Retryer + for { + err := call(ctx, settings) + if err == nil { + return nil + } + if settings.Retry == nil { + return err + } + // Never retry permanent certificate errors. (e.x. if ca-certificates + // are not installed). We should only make very few, targeted + // exceptions: many (other) status=Unavailable should be retried, such + // as if there's a network hiccup, or the internet goes out for a + // minute. This is also why here we are doing string parsing instead of + // simply making Unavailable a non-retried code elsewhere. + if strings.Contains(err.Error(), "x509: certificate signed by unknown authority") { + return err + } + if retryer == nil { + if r := settings.Retry(); r != nil { + retryer = r + } else { + return err + } + } + if d, ok := retryer.Retry(err); !ok { + return err + } else if err = sp(ctx, d); err != nil { + return err + } + } +} diff --git a/vendor/github.com/gophercloud/gophercloud/.gitignore b/vendor/github.com/gophercloud/gophercloud/.gitignore new file mode 100644 index 000000000..dd91ed205 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/.gitignore @@ -0,0 +1,3 @@ +**/*.swp +.idea +.vscode diff --git a/vendor/github.com/gophercloud/gophercloud/.travis.yml b/vendor/github.com/gophercloud/gophercloud/.travis.yml new file mode 100644 index 000000000..9153a00fc --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/.travis.yml @@ -0,0 +1,25 @@ +language: go +sudo: false +install: +- GO111MODULE=off go get golang.org/x/crypto/ssh +- GO111MODULE=off go get -v -tags 'fixtures acceptance' ./... +- GO111MODULE=off go get github.com/wadey/gocovmerge +- GO111MODULE=off go get github.com/mattn/goveralls +- GO111MODULE=off go get golang.org/x/tools/cmd/goimports +go: +- "1.10" +- "1.11" +- "1.12" +- "tip" +env: + global: + - secure: "xSQsAG5wlL9emjbCdxzz/hYQsSpJ/bABO1kkbwMSISVcJ3Nk0u4ywF+LS4bgeOnwPfmFvNTOqVDu3RwEvMeWXSI76t1piCPcObutb2faKLVD/hLoAS76gYX+Z8yGWGHrSB7Do5vTPj1ERe2UljdrnsSeOXzoDwFxYRaZLX4bBOB4AyoGvRniil5QXPATiA1tsWX1VMicj8a4F8X+xeESzjt1Q5Iy31e7vkptu71bhvXCaoo5QhYwT+pLR9dN0S1b7Ro0KVvkRefmr1lUOSYd2e74h6Lc34tC1h3uYZCS4h47t7v5cOXvMNxinEj2C51RvbjvZI1RLVdkuAEJD1Iz4+Ote46nXbZ//6XRZMZz/YxQ13l7ux1PFjgEB6HAapmF5Xd8PRsgeTU9LRJxpiTJ3P5QJ3leS1va8qnziM5kYipj/Rn+V8g2ad/rgkRox9LSiR9VYZD2Pe45YCb1mTKSl2aIJnV7nkOqsShY5LNB4JZSg7xIffA+9YVDktw8dJlATjZqt7WvJJ49g6A61mIUV4C15q2JPGKTkZzDiG81NtmS7hFa7k0yaE2ELgYocbcuyUcAahhxntYTC0i23nJmEHVNiZmBO3u7EgpWe4KGVfumU+lt12tIn5b3dZRBBUk3QakKKozSK1QPHGpk/AZGrhu7H6l8to6IICKWtDcyMPQ=" + - GO111MODULE=on +before_script: +- go vet ./... +script: +- ./script/coverage +- ./script/unittest +- ./script/format +after_success: +- $HOME/gopath/bin/goveralls -service=travis-ci -coverprofile=cover.out diff --git a/vendor/github.com/gophercloud/gophercloud/.zuul.yaml b/vendor/github.com/gophercloud/gophercloud/.zuul.yaml new file mode 100644 index 000000000..135e3b203 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/.zuul.yaml @@ -0,0 +1,114 @@ +- job: + name: gophercloud-unittest + parent: golang-test + description: | + Run gophercloud unit test + run: .zuul/playbooks/gophercloud-unittest/run.yaml + nodeset: ubuntu-xenial-ut + +- job: + name: gophercloud-acceptance-test + parent: golang-test + description: | + Run gophercloud acceptance test on master branch + run: .zuul/playbooks/gophercloud-acceptance-test/run.yaml + +- job: + name: gophercloud-acceptance-test-ironic + parent: golang-test + description: | + Run gophercloud ironic acceptance test on master branch + run: .zuul/playbooks/gophercloud-acceptance-test-ironic/run.yaml + +- job: + name: gophercloud-acceptance-test-stein + parent: gophercloud-acceptance-test + description: | + Run gophercloud acceptance test on stein branch + vars: + global_env: + OS_BRANCH: stable/stein + +- job: + name: gophercloud-acceptance-test-rocky + parent: gophercloud-acceptance-test + description: | + Run gophercloud acceptance test on rocky branch + vars: + global_env: + OS_BRANCH: stable/rocky + +- job: + name: gophercloud-acceptance-test-queens + parent: gophercloud-acceptance-test + description: | + Run gophercloud acceptance test on queens branch + vars: + global_env: + OS_BRANCH: stable/queens + +- job: + name: gophercloud-acceptance-test-pike + parent: gophercloud-acceptance-test + description: | + Run gophercloud acceptance test on pike branch + vars: + global_env: + OS_BRANCH: stable/pike + +- job: + name: gophercloud-acceptance-test-ocata + parent: gophercloud-acceptance-test + description: | + Run gophercloud acceptance test on ocata branch + vars: + global_env: + OS_BRANCH: stable/ocata + +- job: + name: gophercloud-acceptance-test-newton + parent: gophercloud-acceptance-test + description: | + Run gophercloud acceptance test on newton branch + vars: + global_env: + OS_BRANCH: stable/newton + +- job: + name: gophercloud-acceptance-test-mitaka + parent: gophercloud-acceptance-test + description: | + Run gophercloud acceptance test on mitaka branch + vars: + global_env: + OS_BRANCH: stable/mitaka + nodeset: ubuntu-trusty + +- project: + name: gophercloud/gophercloud + check: + jobs: + - gophercloud-unittest + - gophercloud-acceptance-test + - gophercloud-acceptance-test-ironic + recheck-mitaka: + jobs: + - gophercloud-acceptance-test-mitaka + recheck-newton: + jobs: + - gophercloud-acceptance-test-newton + recheck-ocata: + jobs: + - gophercloud-acceptance-test-ocata + recheck-pike: + jobs: + - gophercloud-acceptance-test-pike + recheck-queens: + jobs: + - gophercloud-acceptance-test-queens + recheck-rocky: + jobs: + - gophercloud-acceptance-test-rocky + recheck-stein: + jobs: + - gophercloud-acceptance-test-stein diff --git a/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md b/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md new file mode 100644 index 000000000..d0b120de1 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md @@ -0,0 +1,69 @@ +## 0.4.0 (Unreleased) + +## 0.3.0 (July 31, 2019) + +IMPROVEMENTS + +* Added `baremetal/apiversions.List` [GH-1577](https://github.com/gophercloud/gophercloud/pull/1577) +* Added `baremetal/apiversions.Get` [GH-1577](https://github.com/gophercloud/gophercloud/pull/1577) +* Added `compute/v2/extensions/servergroups.CreateOpts.Policy` [GH-1636](https://github.com/gophercloud/gophercloud/pull/1636) +* Added `identity/v3/extensions/trusts.Create` [GH-1644](https://github.com/gophercloud/gophercloud/pull/1644) +* Added `identity/v3/extensions/trusts.Delete` [GH-1644](https://github.com/gophercloud/gophercloud/pull/1644) +* Added `CreatedAt` and `UpdatedAt` to `networking/v2/extensions/layer3/floatingips.FloatingIP` [GH-1647](https://github.com/gophercloud/gophercloud/issues/1646) +* Added `CreatedAt` and `UpdatedAt` to `networking/v2/extensions/security/groups.SecGroup` [GH-1654](https://github.com/gophercloud/gophercloud/issues/1654) +* Added `CreatedAt` and `UpdatedAt` to `networking/v2/networks.Network` [GH-1657](https://github.com/gophercloud/gophercloud/issues/1657) +* Added `keymanager/v1/containers.CreateSecretRef` [GH-1659](https://github.com/gophercloud/gophercloud/issues/1659) +* Added `keymanager/v1/containers.DeleteSecretRef` [GH-1659](https://github.com/gophercloud/gophercloud/issues/1659) +* Added `sharedfilesystems/v2/shares.GetMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) +* Added `sharedfilesystems/v2/shares.GetMetadatum` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) +* Added `sharedfilesystems/v2/shares.SetMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) +* Added `sharedfilesystems/v2/shares.UpdateMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) +* Added `sharedfilesystems/v2/shares.DeleteMetadatum` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656) +* Added `sharedfilesystems/v2/sharetypes.IDFromName` [GH-1662](https://github.com/gophercloud/gophercloud/issues/1662) + + + +BUG FIXES + +* Changed `baremetal/v1/nodes.CleanStep.Args` from `map[string]string` to `map[string]interface{}` [GH-1638](https://github.com/gophercloud/gophercloud/pull/1638) +* Removed `URLPath` and `ExpectedCodes` from `loadbalancer/v2/monitors.ToMonitorCreateMap` since Octavia now provides default values when these fields are not specified [GH-1640](https://github.com/gophercloud/gophercloud/pull/1540) + + +## 0.2.0 (June 17, 2019) + +IMPROVEMENTS + +* Added `networking/v2/extensions/qos/rules.ListBandwidthLimitRules` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584) +* Added `networking/v2/extensions/qos/rules.GetBandwidthLimitRule` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584) +* Added `networking/v2/extensions/qos/rules.CreateBandwidthLimitRule` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584) +* Added `networking/v2/extensions/qos/rules.UpdateBandwidthLimitRule` [GH-1589](https://github.com/gophercloud/gophercloud/pull/1589) +* Added `networking/v2/extensions/qos/rules.DeleteBandwidthLimitRule` [GH-1590](https://github.com/gophercloud/gophercloud/pull/1590) +* Added `networking/v2/extensions/qos/policies.List` [GH-1591](https://github.com/gophercloud/gophercloud/pull/1591) +* Added `networking/v2/extensions/qos/policies.Get` [GH-1593](https://github.com/gophercloud/gophercloud/pull/1593) +* Added `networking/v2/extensions/qos/rules.ListDSCPMarkingRules` [GH-1594](https://github.com/gophercloud/gophercloud/pull/1594) +* Added `networking/v2/extensions/qos/policies.Create` [GH-1595](https://github.com/gophercloud/gophercloud/pull/1595) +* Added `compute/v2/extensions/diagnostics.Get` [GH-1592](https://github.com/gophercloud/gophercloud/pull/1592) +* Added `networking/v2/extensions/qos/policies.Update` [GH-1603](https://github.com/gophercloud/gophercloud/pull/1603) +* Added `networking/v2/extensions/qos/policies.Delete` [GH-1603](https://github.com/gophercloud/gophercloud/pull/1603) +* Added `networking/v2/extensions/qos/rules.CreateDSCPMarkingRule` [GH-1605](https://github.com/gophercloud/gophercloud/pull/1605) +* Added `networking/v2/extensions/qos/rules.UpdateDSCPMarkingRule` [GH-1605](https://github.com/gophercloud/gophercloud/pull/1605) +* Added `networking/v2/extensions/qos/rules.GetDSCPMarkingRule` [GH-1609](https://github.com/gophercloud/gophercloud/pull/1609) +* Added `networking/v2/extensions/qos/rules.DeleteDSCPMarkingRule` [GH-1609](https://github.com/gophercloud/gophercloud/pull/1609) +* Added `networking/v2/extensions/qos/rules.ListMinimumBandwidthRules` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615) +* Added `networking/v2/extensions/qos/rules.GetMinimumBandwidthRule` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615) +* Added `networking/v2/extensions/qos/rules.CreateMinimumBandwidthRule` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615) +* Added `Hostname` to `baremetalintrospection/v1/introspection.Data` [GH-1627](https://github.com/gophercloud/gophercloud/pull/1627) +* Added `networking/v2/extensions/qos/rules.UpdateMinimumBandwidthRule` [GH-1624](https://github.com/gophercloud/gophercloud/pull/1624) +* Added `networking/v2/extensions/qos/rules.DeleteMinimumBandwidthRule` [GH-1624](https://github.com/gophercloud/gophercloud/pull/1624) +* Added `networking/v2/extensions/qos/ruletypes.GetRuleType` [GH-1625](https://github.com/gophercloud/gophercloud/pull/1625) +* Added `Extra` to `baremetalintrospection/v1/introspection.Data` [GH-1611](https://github.com/gophercloud/gophercloud/pull/1611) +* Added `blockstorage/extensions/volumeactions.SetImageMetadata` [GH-1621](https://github.com/gophercloud/gophercloud/pull/1621) + +BUG FIXES + +* Updated `networking/v2/extensions/qos/rules.UpdateBandwidthLimitRule` to use return code 200 [GH-1606](https://github.com/gophercloud/gophercloud/pull/1606) +* Fixed bug in `compute/v2/extensions/schedulerhints.SchedulerHints.Query` where contents will now be marshalled to a string [GH-1620](https://github.com/gophercloud/gophercloud/pull/1620) + +## 0.1.0 (May 27, 2019) + +Initial tagged release. diff --git a/vendor/github.com/gophercloud/gophercloud/LICENSE b/vendor/github.com/gophercloud/gophercloud/LICENSE new file mode 100644 index 000000000..fbbbc9e4c --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/LICENSE @@ -0,0 +1,191 @@ +Copyright 2012-2013 Rackspace, 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. + +------ + + 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 diff --git a/vendor/github.com/gophercloud/gophercloud/README.md b/vendor/github.com/gophercloud/gophercloud/README.md new file mode 100644 index 000000000..ad29041d9 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/README.md @@ -0,0 +1,159 @@ +# Gophercloud: an OpenStack SDK for Go +[![Build Status](https://travis-ci.org/gophercloud/gophercloud.svg?branch=master)](https://travis-ci.org/gophercloud/gophercloud) +[![Coverage Status](https://coveralls.io/repos/github/gophercloud/gophercloud/badge.svg?branch=master)](https://coveralls.io/github/gophercloud/gophercloud?branch=master) + +Gophercloud is an OpenStack Go SDK. + +## Useful links + +* [Reference documentation](http://godoc.org/github.com/gophercloud/gophercloud) +* [Effective Go](https://golang.org/doc/effective_go.html) + +## How to install + +Before installing, you need to ensure that your [GOPATH environment variable](https://golang.org/doc/code.html#GOPATH) +is pointing to an appropriate directory where you want to install Gophercloud: + +```bash +mkdir $HOME/go +export GOPATH=$HOME/go +``` + +To protect yourself against changes in your dependencies, we highly recommend choosing a +[dependency management solution](https://github.com/golang/go/wiki/PackageManagementTools) for +your projects, such as [godep](https://github.com/tools/godep). Once this is set up, you can install +Gophercloud as a dependency like so: + +```bash +go get github.com/gophercloud/gophercloud + +# Edit your code to import relevant packages from "github.com/gophercloud/gophercloud" + +godep save ./... +``` + +This will install all the source files you need into a `Godeps/_workspace` directory, which is +referenceable from your own source files when you use the `godep go` command. + +## Getting started + +### Credentials + +Because you'll be hitting an API, you will need to retrieve your OpenStack +credentials and either store them as environment variables or in your local Go +files. The first method is recommended because it decouples credential +information from source code, allowing you to push the latter to your version +control system without any security risk. + +You will need to retrieve the following: + +* username +* password +* a valid Keystone identity URL + +For users that have the OpenStack dashboard installed, there's a shortcut. If +you visit the `project/access_and_security` path in Horizon and click on the +"Download OpenStack RC File" button at the top right hand corner, you will +download a bash file that exports all of your access details to environment +variables. To execute the file, run `source admin-openrc.sh` and you will be +prompted for your password. + +### Authentication + +Once you have access to your credentials, you can begin plugging them into +Gophercloud. The next step is authentication, and this is handled by a base +"Provider" struct. To get one, you can either pass in your credentials +explicitly, or tell Gophercloud to use environment variables: + +```go +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack" + "github.com/gophercloud/gophercloud/openstack/utils" +) + +// Option 1: Pass in the values yourself +opts := gophercloud.AuthOptions{ + IdentityEndpoint: "https://openstack.example.com:5000/v2.0", + Username: "{username}", + Password: "{password}", +} + +// Option 2: Use a utility function to retrieve all your environment variables +opts, err := openstack.AuthOptionsFromEnv() +``` + +Once you have the `opts` variable, you can pass it in and get back a +`ProviderClient` struct: + +```go +provider, err := openstack.AuthenticatedClient(opts) +``` + +The `ProviderClient` is the top-level client that all of your OpenStack services +derive from. The provider contains all of the authentication details that allow +your Go code to access the API - such as the base URL and token ID. + +### Provision a server + +Once we have a base Provider, we inject it as a dependency into each OpenStack +service. In order to work with the Compute API, we need a Compute service +client; which can be created like so: + +```go +client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{ + Region: os.Getenv("OS_REGION_NAME"), +}) +``` + +We then use this `client` for any Compute API operation we want. In our case, +we want to provision a new server - so we invoke the `Create` method and pass +in the flavor ID (hardware specification) and image ID (operating system) we're +interested in: + +```go +import "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" + +server, err := servers.Create(client, servers.CreateOpts{ + Name: "My new server!", + FlavorRef: "flavor_id", + ImageRef: "image_id", +}).Extract() +``` + +The above code sample creates a new server with the parameters, and embodies the +new resource in the `server` variable (a +[`servers.Server`](http://godoc.org/github.com/gophercloud/gophercloud) struct). + +## Advanced Usage + +Have a look at the [FAQ](./docs/FAQ.md) for some tips on customizing the way Gophercloud works. + +## Backwards-Compatibility Guarantees + +None. Vendor it and write tests covering the parts you use. + +## Contributing + +See the [contributing guide](./.github/CONTRIBUTING.md). + +## Help and feedback + +If you're struggling with something or have spotted a potential bug, feel free +to submit an issue to our [bug tracker](https://github.com/gophercloud/gophercloud/issues). + +## Thank You + +We'd like to extend special thanks and appreciation to the following: + +### OpenLab + + + +OpenLab is providing a full CI environment to test each PR and merge for a variety of OpenStack releases. + +### VEXXHOST + + + +VEXXHOST is providing their services to assist with the development and testing of Gophercloud. diff --git a/vendor/github.com/gophercloud/gophercloud/auth_options.go b/vendor/github.com/gophercloud/gophercloud/auth_options.go new file mode 100644 index 000000000..5ffa8d1e0 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/auth_options.go @@ -0,0 +1,437 @@ +package gophercloud + +/* +AuthOptions stores information needed to authenticate to an OpenStack Cloud. +You can populate one manually, or use a provider's AuthOptionsFromEnv() function +to read relevant information from the standard environment variables. Pass one +to a provider's AuthenticatedClient function to authenticate and obtain a +ProviderClient representing an active session on that provider. + +Its fields are the union of those recognized by each identity implementation and +provider. + +An example of manually providing authentication information: + + opts := gophercloud.AuthOptions{ + IdentityEndpoint: "https://openstack.example.com:5000/v2.0", + Username: "{username}", + Password: "{password}", + TenantID: "{tenant_id}", + } + + provider, err := openstack.AuthenticatedClient(opts) + +An example of using AuthOptionsFromEnv(), where the environment variables can +be read from a file, such as a standard openrc file: + + opts, err := openstack.AuthOptionsFromEnv() + provider, err := openstack.AuthenticatedClient(opts) +*/ +type AuthOptions struct { + // IdentityEndpoint specifies the HTTP endpoint that is required to work with + // the Identity API of the appropriate version. While it's ultimately needed by + // all of the identity services, it will often be populated by a provider-level + // function. + // + // The IdentityEndpoint is typically referred to as the "auth_url" or + // "OS_AUTH_URL" in the information provided by the cloud operator. + IdentityEndpoint string `json:"-"` + + // Username is required if using Identity V2 API. Consult with your provider's + // control panel to discover your account's username. In Identity V3, either + // UserID or a combination of Username and DomainID or DomainName are needed. + Username string `json:"username,omitempty"` + UserID string `json:"-"` + + Password string `json:"password,omitempty"` + + // At most one of DomainID and DomainName must be provided if using Username + // with Identity V3. Otherwise, either are optional. + DomainID string `json:"-"` + DomainName string `json:"name,omitempty"` + + // The TenantID and TenantName fields are optional for the Identity V2 API. + // The same fields are known as project_id and project_name in the Identity + // V3 API, but are collected as TenantID and TenantName here in both cases. + // Some providers allow you to specify a TenantName instead of the TenantId. + // Some require both. Your provider's authentication policies will determine + // how these fields influence authentication. + // If DomainID or DomainName are provided, they will also apply to TenantName. + // It is not currently possible to authenticate with Username and a Domain + // and scope to a Project in a different Domain by using TenantName. To + // accomplish that, the ProjectID will need to be provided as the TenantID + // option. + TenantID string `json:"tenantId,omitempty"` + TenantName string `json:"tenantName,omitempty"` + + // AllowReauth should be set to true if you grant permission for Gophercloud to + // cache your credentials in memory, and to allow Gophercloud to attempt to + // re-authenticate automatically if/when your token expires. If you set it to + // false, it will not cache these settings, but re-authentication will not be + // possible. This setting defaults to false. + // + // NOTE: The reauth function will try to re-authenticate endlessly if left + // unchecked. The way to limit the number of attempts is to provide a custom + // HTTP client to the provider client and provide a transport that implements + // the RoundTripper interface and stores the number of failed retries. For an + // example of this, see here: + // https://github.com/rackspace/rack/blob/1.0.0/auth/clients.go#L311 + AllowReauth bool `json:"-"` + + // TokenID allows users to authenticate (possibly as another user) with an + // authentication token ID. + TokenID string `json:"-"` + + // Scope determines the scoping of the authentication request. + Scope *AuthScope `json:"-"` + + // Authentication through Application Credentials requires supplying name, project and secret + // For project we can use TenantID + ApplicationCredentialID string `json:"-"` + ApplicationCredentialName string `json:"-"` + ApplicationCredentialSecret string `json:"-"` +} + +// AuthScope allows a created token to be limited to a specific domain or project. +type AuthScope struct { + ProjectID string + ProjectName string + DomainID string + DomainName string +} + +// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder +// interface in the v2 tokens package +func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) { + // Populate the request map. + authMap := make(map[string]interface{}) + + if opts.Username != "" { + if opts.Password != "" { + authMap["passwordCredentials"] = map[string]interface{}{ + "username": opts.Username, + "password": opts.Password, + } + } else { + return nil, ErrMissingInput{Argument: "Password"} + } + } else if opts.TokenID != "" { + authMap["token"] = map[string]interface{}{ + "id": opts.TokenID, + } + } else { + return nil, ErrMissingInput{Argument: "Username"} + } + + if opts.TenantID != "" { + authMap["tenantId"] = opts.TenantID + } + if opts.TenantName != "" { + authMap["tenantName"] = opts.TenantName + } + + return map[string]interface{}{"auth": authMap}, nil +} + +func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) { + type domainReq struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + } + + type projectReq struct { + Domain *domainReq `json:"domain,omitempty"` + Name *string `json:"name,omitempty"` + ID *string `json:"id,omitempty"` + } + + type userReq struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Password string `json:"password,omitempty"` + Domain *domainReq `json:"domain,omitempty"` + } + + type passwordReq struct { + User userReq `json:"user"` + } + + type tokenReq struct { + ID string `json:"id"` + } + + type applicationCredentialReq struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + User *userReq `json:"user,omitempty"` + Secret *string `json:"secret,omitempty"` + } + + type identityReq struct { + Methods []string `json:"methods"` + Password *passwordReq `json:"password,omitempty"` + Token *tokenReq `json:"token,omitempty"` + ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"` + } + + type authReq struct { + Identity identityReq `json:"identity"` + } + + type request struct { + Auth authReq `json:"auth"` + } + + // Populate the request structure based on the provided arguments. Create and return an error + // if insufficient or incompatible information is present. + var req request + + if opts.Password == "" { + if opts.TokenID != "" { + // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication + // parameters. + if opts.Username != "" { + return nil, ErrUsernameWithToken{} + } + if opts.UserID != "" { + return nil, ErrUserIDWithToken{} + } + if opts.DomainID != "" { + return nil, ErrDomainIDWithToken{} + } + if opts.DomainName != "" { + return nil, ErrDomainNameWithToken{} + } + + // Configure the request for Token authentication. + req.Auth.Identity.Methods = []string{"token"} + req.Auth.Identity.Token = &tokenReq{ + ID: opts.TokenID, + } + + } else if opts.ApplicationCredentialID != "" { + // Configure the request for ApplicationCredentialID authentication. + // https://github.com/openstack/keystoneauth/blob/stable/rocky/keystoneauth1/identity/v3/application_credential.py#L48-L67 + // There are three kinds of possible application_credential requests + // 1. application_credential id + secret + // 2. application_credential name + secret + user_id + // 3. application_credential name + secret + username + domain_id / domain_name + if opts.ApplicationCredentialSecret == "" { + return nil, ErrAppCredMissingSecret{} + } + req.Auth.Identity.Methods = []string{"application_credential"} + req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{ + ID: &opts.ApplicationCredentialID, + Secret: &opts.ApplicationCredentialSecret, + } + } else if opts.ApplicationCredentialName != "" { + if opts.ApplicationCredentialSecret == "" { + return nil, ErrAppCredMissingSecret{} + } + + var userRequest *userReq + + if opts.UserID != "" { + // UserID could be used without the domain information + userRequest = &userReq{ + ID: &opts.UserID, + } + } + + if userRequest == nil && opts.Username == "" { + // Make sure that Username or UserID are provided + return nil, ErrUsernameOrUserID{} + } + + if userRequest == nil && opts.DomainID != "" { + userRequest = &userReq{ + Name: &opts.Username, + Domain: &domainReq{ID: &opts.DomainID}, + } + } + + if userRequest == nil && opts.DomainName != "" { + userRequest = &userReq{ + Name: &opts.Username, + Domain: &domainReq{Name: &opts.DomainName}, + } + } + + // Make sure that DomainID or DomainName are provided among Username + if userRequest == nil { + return nil, ErrDomainIDOrDomainName{} + } + + req.Auth.Identity.Methods = []string{"application_credential"} + req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{ + Name: &opts.ApplicationCredentialName, + User: userRequest, + Secret: &opts.ApplicationCredentialSecret, + } + } else { + // If no password or token ID or ApplicationCredential are available, authentication can't continue. + return nil, ErrMissingPassword{} + } + } else { + // Password authentication. + req.Auth.Identity.Methods = []string{"password"} + + // At least one of Username and UserID must be specified. + if opts.Username == "" && opts.UserID == "" { + return nil, ErrUsernameOrUserID{} + } + + if opts.Username != "" { + // If Username is provided, UserID may not be provided. + if opts.UserID != "" { + return nil, ErrUsernameOrUserID{} + } + + // Either DomainID or DomainName must also be specified. + if opts.DomainID == "" && opts.DomainName == "" { + return nil, ErrDomainIDOrDomainName{} + } + + if opts.DomainID != "" { + if opts.DomainName != "" { + return nil, ErrDomainIDOrDomainName{} + } + + // Configure the request for Username and Password authentication with a DomainID. + req.Auth.Identity.Password = &passwordReq{ + User: userReq{ + Name: &opts.Username, + Password: opts.Password, + Domain: &domainReq{ID: &opts.DomainID}, + }, + } + } + + if opts.DomainName != "" { + // Configure the request for Username and Password authentication with a DomainName. + req.Auth.Identity.Password = &passwordReq{ + User: userReq{ + Name: &opts.Username, + Password: opts.Password, + Domain: &domainReq{Name: &opts.DomainName}, + }, + } + } + } + + if opts.UserID != "" { + // If UserID is specified, neither DomainID nor DomainName may be. + if opts.DomainID != "" { + return nil, ErrDomainIDWithUserID{} + } + if opts.DomainName != "" { + return nil, ErrDomainNameWithUserID{} + } + + // Configure the request for UserID and Password authentication. + req.Auth.Identity.Password = &passwordReq{ + User: userReq{ID: &opts.UserID, Password: opts.Password}, + } + } + } + + b, err := BuildRequestBody(req, "") + if err != nil { + return nil, err + } + + if len(scope) != 0 { + b["auth"].(map[string]interface{})["scope"] = scope + } + + return b, nil +} + +func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { + // For backwards compatibility. + // If AuthOptions.Scope was not set, try to determine it. + // This works well for common scenarios. + if opts.Scope == nil { + opts.Scope = new(AuthScope) + if opts.TenantID != "" { + opts.Scope.ProjectID = opts.TenantID + } else { + if opts.TenantName != "" { + opts.Scope.ProjectName = opts.TenantName + opts.Scope.DomainID = opts.DomainID + opts.Scope.DomainName = opts.DomainName + } + } + } + + if opts.Scope.ProjectName != "" { + // ProjectName provided: either DomainID or DomainName must also be supplied. + // ProjectID may not be supplied. + if opts.Scope.DomainID == "" && opts.Scope.DomainName == "" { + return nil, ErrScopeDomainIDOrDomainName{} + } + if opts.Scope.ProjectID != "" { + return nil, ErrScopeProjectIDOrProjectName{} + } + + if opts.Scope.DomainID != "" { + // ProjectName + DomainID + return map[string]interface{}{ + "project": map[string]interface{}{ + "name": &opts.Scope.ProjectName, + "domain": map[string]interface{}{"id": &opts.Scope.DomainID}, + }, + }, nil + } + + if opts.Scope.DomainName != "" { + // ProjectName + DomainName + return map[string]interface{}{ + "project": map[string]interface{}{ + "name": &opts.Scope.ProjectName, + "domain": map[string]interface{}{"name": &opts.Scope.DomainName}, + }, + }, nil + } + } else if opts.Scope.ProjectID != "" { + // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided. + if opts.Scope.DomainID != "" { + return nil, ErrScopeProjectIDAlone{} + } + if opts.Scope.DomainName != "" { + return nil, ErrScopeProjectIDAlone{} + } + + // ProjectID + return map[string]interface{}{ + "project": map[string]interface{}{ + "id": &opts.Scope.ProjectID, + }, + }, nil + } else if opts.Scope.DomainID != "" { + // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. + if opts.Scope.DomainName != "" { + return nil, ErrScopeDomainIDOrDomainName{} + } + + // DomainID + return map[string]interface{}{ + "domain": map[string]interface{}{ + "id": &opts.Scope.DomainID, + }, + }, nil + } else if opts.Scope.DomainName != "" { + // DomainName + return map[string]interface{}{ + "domain": map[string]interface{}{ + "name": &opts.Scope.DomainName, + }, + }, nil + } + + return nil, nil +} + +func (opts AuthOptions) CanReauth() bool { + return opts.AllowReauth +} diff --git a/vendor/github.com/gophercloud/gophercloud/auth_result.go b/vendor/github.com/gophercloud/gophercloud/auth_result.go new file mode 100644 index 000000000..2e4699b97 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/auth_result.go @@ -0,0 +1,52 @@ +package gophercloud + +/* +AuthResult is the result from the request that was used to obtain a provider +client's Keystone token. It is returned from ProviderClient.GetAuthResult(). + +The following types satisfy this interface: + + github.com/gophercloud/gophercloud/openstack/identity/v2/tokens.CreateResult + github.com/gophercloud/gophercloud/openstack/identity/v3/tokens.CreateResult + +Usage example: + + import ( + "github.com/gophercloud/gophercloud" + tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens" + tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens" + ) + + func GetAuthenticatedUserID(providerClient *gophercloud.ProviderClient) (string, error) { + r := providerClient.GetAuthResult() + if r == nil { + //ProviderClient did not use openstack.Authenticate(), e.g. because token + //was set manually with ProviderClient.SetToken() + return "", errors.New("no AuthResult available") + } + switch r := r.(type) { + case tokens2.CreateResult: + u, err := r.ExtractUser() + if err != nil { + return "", err + } + return u.ID, nil + case tokens3.CreateResult: + u, err := r.ExtractUser() + if err != nil { + return "", err + } + return u.ID, nil + default: + panic(fmt.Sprintf("got unexpected AuthResult type %t", r)) + } + } + +Both implementing types share a lot of methods by name, like ExtractUser() in +this example. But those methods cannot be part of the AuthResult interface +because the return types are different (in this case, type tokens2.User vs. +type tokens3.User). +*/ +type AuthResult interface { + ExtractTokenID() (string, error) +} diff --git a/vendor/github.com/gophercloud/gophercloud/doc.go b/vendor/github.com/gophercloud/gophercloud/doc.go new file mode 100644 index 000000000..953ca822a --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/doc.go @@ -0,0 +1,110 @@ +/* +Package gophercloud provides a multi-vendor interface to OpenStack-compatible +clouds. The library has a three-level hierarchy: providers, services, and +resources. + +Authenticating with Providers + +Provider structs represent the cloud providers that offer and manage a +collection of services. You will generally want to create one Provider +client per OpenStack cloud. + + It is now recommended to use the `clientconfig` package found at + https://github.com/gophercloud/utils/tree/master/openstack/clientconfig + for all authentication purposes. + + The below documentation is still relevant. clientconfig simply implements + the below and presents it in an easier and more flexible way. + +Use your OpenStack credentials to create a Provider client. The +IdentityEndpoint is typically refered to as "auth_url" or "OS_AUTH_URL" in +information provided by the cloud operator. Additionally, the cloud may refer to +TenantID or TenantName as project_id and project_name. Credentials are +specified like so: + + opts := gophercloud.AuthOptions{ + IdentityEndpoint: "https://openstack.example.com:5000/v2.0", + Username: "{username}", + Password: "{password}", + TenantID: "{tenant_id}", + } + + provider, err := openstack.AuthenticatedClient(opts) + +You can authenticate with a token by doing: + + opts := gophercloud.AuthOptions{ + IdentityEndpoint: "https://openstack.example.com:5000/v2.0", + TokenID: "{token_id}", + TenantID: "{tenant_id}", + } + + provider, err := openstack.AuthenticatedClient(opts) + +You may also use the openstack.AuthOptionsFromEnv() helper function. This +function reads in standard environment variables frequently found in an +OpenStack `openrc` file. Again note that Gophercloud currently uses "tenant" +instead of "project". + + opts, err := openstack.AuthOptionsFromEnv() + provider, err := openstack.AuthenticatedClient(opts) + +Service Clients + +Service structs are specific to a provider and handle all of the logic and +operations for a particular OpenStack service. Examples of services include: +Compute, Object Storage, Block Storage. In order to define one, you need to +pass in the parent provider, like so: + + opts := gophercloud.EndpointOpts{Region: "RegionOne"} + + client, err := openstack.NewComputeV2(provider, opts) + +Resources + +Resource structs are the domain models that services make use of in order +to work with and represent the state of API resources: + + server, err := servers.Get(client, "{serverId}").Extract() + +Intermediate Result structs are returned for API operations, which allow +generic access to the HTTP headers, response body, and any errors associated +with the network transaction. To turn a result into a usable resource struct, +you must call the Extract method which is chained to the response, or an +Extract function from an applicable extension: + + result := servers.Get(client, "{serverId}") + + // Attempt to extract the disk configuration from the OS-DCF disk config + // extension: + config, err := diskconfig.ExtractGet(result) + +All requests that enumerate a collection return a Pager struct that is used to +iterate through the results one page at a time. Use the EachPage method on that +Pager to handle each successive Page in a closure, then use the appropriate +extraction method from that request's package to interpret that Page as a slice +of results: + + err := servers.List(client, nil).EachPage(func (page pagination.Page) (bool, error) { + s, err := servers.ExtractServers(page) + if err != nil { + return false, err + } + + // Handle the []servers.Server slice. + + // Return "false" or an error to prematurely stop fetching new pages. + return true, nil + }) + +If you want to obtain the entire collection of pages without doing any +intermediary processing on each page, you can use the AllPages method: + + allPages, err := servers.List(client, nil).AllPages() + allServers, err := servers.ExtractServers(allPages) + +This top-level package contains utility functions and data types that are used +throughout the provider and service packages. Of particular note for end users +are the AuthOptions and EndpointOpts structs. +*/ +package gophercloud diff --git a/vendor/github.com/gophercloud/gophercloud/endpoint_search.go b/vendor/github.com/gophercloud/gophercloud/endpoint_search.go new file mode 100644 index 000000000..2fbc3c97f --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/endpoint_search.go @@ -0,0 +1,76 @@ +package gophercloud + +// Availability indicates to whom a specific service endpoint is accessible: +// the internet at large, internal networks only, or only to administrators. +// Different identity services use different terminology for these. Identity v2 +// lists them as different kinds of URLs within the service catalog ("adminURL", +// "internalURL", and "publicURL"), while v3 lists them as "Interfaces" in an +// endpoint's response. +type Availability string + +const ( + // AvailabilityAdmin indicates that an endpoint is only available to + // administrators. + AvailabilityAdmin Availability = "admin" + + // AvailabilityPublic indicates that an endpoint is available to everyone on + // the internet. + AvailabilityPublic Availability = "public" + + // AvailabilityInternal indicates that an endpoint is only available within + // the cluster's internal network. + AvailabilityInternal Availability = "internal" +) + +// EndpointOpts specifies search criteria used by queries against an +// OpenStack service catalog. The options must contain enough information to +// unambiguously identify one, and only one, endpoint within the catalog. +// +// Usually, these are passed to service client factory functions in a provider +// package, like "openstack.NewComputeV2()". +type EndpointOpts struct { + // Type [required] is the service type for the client (e.g., "compute", + // "object-store"). Generally, this will be supplied by the service client + // function, but a user-given value will be honored if provided. + Type string + + // Name [optional] is the service name for the client (e.g., "nova") as it + // appears in the service catalog. Services can have the same Type but a + // different Name, which is why both Type and Name are sometimes needed. + Name string + + // Region [required] is the geographic region in which the endpoint resides, + // generally specifying which datacenter should house your resources. + // Required only for services that span multiple regions. + Region string + + // Availability [optional] is the visibility of the endpoint to be returned. + // Valid types include the constants AvailabilityPublic, AvailabilityInternal, + // or AvailabilityAdmin from this package. + // + // Availability is not required, and defaults to AvailabilityPublic. Not all + // providers or services offer all Availability options. + Availability Availability +} + +/* +EndpointLocator is an internal function to be used by provider implementations. + +It provides an implementation that locates a single endpoint from a service +catalog for a specific ProviderClient based on user-provided EndpointOpts. The +provider then uses it to discover related ServiceClients. +*/ +type EndpointLocator func(EndpointOpts) (string, error) + +// ApplyDefaults is an internal method to be used by provider implementations. +// +// It sets EndpointOpts fields if not already set, including a default type. +// Currently, EndpointOpts.Availability defaults to the public endpoint. +func (eo *EndpointOpts) ApplyDefaults(t string) { + if eo.Type == "" { + eo.Type = t + } + if eo.Availability == "" { + eo.Availability = AvailabilityPublic + } +} diff --git a/vendor/github.com/gophercloud/gophercloud/errors.go b/vendor/github.com/gophercloud/gophercloud/errors.go new file mode 100644 index 000000000..0bcb3af7f --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/errors.go @@ -0,0 +1,471 @@ +package gophercloud + +import ( + "fmt" + "strings" +) + +// BaseError is an error type that all other error types embed. +type BaseError struct { + DefaultErrString string + Info string +} + +func (e BaseError) Error() string { + e.DefaultErrString = "An error occurred while executing a Gophercloud request." + return e.choseErrString() +} + +func (e BaseError) choseErrString() string { + if e.Info != "" { + return e.Info + } + return e.DefaultErrString +} + +// ErrMissingInput is the error when input is required in a particular +// situation but not provided by the user +type ErrMissingInput struct { + BaseError + Argument string +} + +func (e ErrMissingInput) Error() string { + e.DefaultErrString = fmt.Sprintf("Missing input for argument [%s]", e.Argument) + return e.choseErrString() +} + +// ErrInvalidInput is an error type used for most non-HTTP Gophercloud errors. +type ErrInvalidInput struct { + ErrMissingInput + Value interface{} +} + +func (e ErrInvalidInput) Error() string { + e.DefaultErrString = fmt.Sprintf("Invalid input provided for argument [%s]: [%+v]", e.Argument, e.Value) + return e.choseErrString() +} + +// ErrMissingEnvironmentVariable is the error when environment variable is required +// in a particular situation but not provided by the user +type ErrMissingEnvironmentVariable struct { + BaseError + EnvironmentVariable string +} + +func (e ErrMissingEnvironmentVariable) Error() string { + e.DefaultErrString = fmt.Sprintf("Missing environment variable [%s]", e.EnvironmentVariable) + return e.choseErrString() +} + +// ErrMissingAnyoneOfEnvironmentVariables is the error when anyone of the environment variables +// is required in a particular situation but not provided by the user +type ErrMissingAnyoneOfEnvironmentVariables struct { + BaseError + EnvironmentVariables []string +} + +func (e ErrMissingAnyoneOfEnvironmentVariables) Error() string { + e.DefaultErrString = fmt.Sprintf( + "Missing one of the following environment variables [%s]", + strings.Join(e.EnvironmentVariables, ", "), + ) + return e.choseErrString() +} + +// ErrUnexpectedResponseCode is returned by the Request method when a response code other than +// those listed in OkCodes is encountered. +type ErrUnexpectedResponseCode struct { + BaseError + URL string + Method string + Expected []int + Actual int + Body []byte +} + +func (e ErrUnexpectedResponseCode) Error() string { + e.DefaultErrString = fmt.Sprintf( + "Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s", + e.Expected, e.Method, e.URL, e.Actual, e.Body, + ) + return e.choseErrString() +} + +// ErrDefault400 is the default error type returned on a 400 HTTP response code. +type ErrDefault400 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault401 is the default error type returned on a 401 HTTP response code. +type ErrDefault401 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault403 is the default error type returned on a 403 HTTP response code. +type ErrDefault403 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault404 is the default error type returned on a 404 HTTP response code. +type ErrDefault404 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault405 is the default error type returned on a 405 HTTP response code. +type ErrDefault405 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault408 is the default error type returned on a 408 HTTP response code. +type ErrDefault408 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault409 is the default error type returned on a 409 HTTP response code. +type ErrDefault409 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault429 is the default error type returned on a 429 HTTP response code. +type ErrDefault429 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault500 is the default error type returned on a 500 HTTP response code. +type ErrDefault500 struct { + ErrUnexpectedResponseCode +} + +// ErrDefault503 is the default error type returned on a 503 HTTP response code. +type ErrDefault503 struct { + ErrUnexpectedResponseCode +} + +func (e ErrDefault400) Error() string { + e.DefaultErrString = fmt.Sprintf( + "Bad request with: [%s %s], error message: %s", + e.Method, e.URL, e.Body, + ) + return e.choseErrString() +} +func (e ErrDefault401) Error() string { + return "Authentication failed" +} +func (e ErrDefault403) Error() string { + e.DefaultErrString = fmt.Sprintf( + "Request forbidden: [%s %s], error message: %s", + e.Method, e.URL, e.Body, + ) + return e.choseErrString() +} +func (e ErrDefault404) Error() string { + return "Resource not found" +} +func (e ErrDefault405) Error() string { + return "Method not allowed" +} +func (e ErrDefault408) Error() string { + return "The server timed out waiting for the request" +} +func (e ErrDefault429) Error() string { + return "Too many requests have been sent in a given amount of time. Pause" + + " requests, wait up to one minute, and try again." +} +func (e ErrDefault500) Error() string { + return "Internal Server Error" +} +func (e ErrDefault503) Error() string { + return "The service is currently unable to handle the request due to a temporary" + + " overloading or maintenance. This is a temporary condition. Try again later." +} + +// Err400er is the interface resource error types implement to override the error message +// from a 400 error. +type Err400er interface { + Error400(ErrUnexpectedResponseCode) error +} + +// Err401er is the interface resource error types implement to override the error message +// from a 401 error. +type Err401er interface { + Error401(ErrUnexpectedResponseCode) error +} + +// Err403er is the interface resource error types implement to override the error message +// from a 403 error. +type Err403er interface { + Error403(ErrUnexpectedResponseCode) error +} + +// Err404er is the interface resource error types implement to override the error message +// from a 404 error. +type Err404er interface { + Error404(ErrUnexpectedResponseCode) error +} + +// Err405er is the interface resource error types implement to override the error message +// from a 405 error. +type Err405er interface { + Error405(ErrUnexpectedResponseCode) error +} + +// Err408er is the interface resource error types implement to override the error message +// from a 408 error. +type Err408er interface { + Error408(ErrUnexpectedResponseCode) error +} + +// Err409er is the interface resource error types implement to override the error message +// from a 409 error. +type Err409er interface { + Error409(ErrUnexpectedResponseCode) error +} + +// Err429er is the interface resource error types implement to override the error message +// from a 429 error. +type Err429er interface { + Error429(ErrUnexpectedResponseCode) error +} + +// Err500er is the interface resource error types implement to override the error message +// from a 500 error. +type Err500er interface { + Error500(ErrUnexpectedResponseCode) error +} + +// Err503er is the interface resource error types implement to override the error message +// from a 503 error. +type Err503er interface { + Error503(ErrUnexpectedResponseCode) error +} + +// ErrTimeOut is the error type returned when an operations times out. +type ErrTimeOut struct { + BaseError +} + +func (e ErrTimeOut) Error() string { + e.DefaultErrString = "A time out occurred" + return e.choseErrString() +} + +// ErrUnableToReauthenticate is the error type returned when reauthentication fails. +type ErrUnableToReauthenticate struct { + BaseError + ErrOriginal error +} + +func (e ErrUnableToReauthenticate) Error() string { + e.DefaultErrString = fmt.Sprintf("Unable to re-authenticate: %s", e.ErrOriginal) + return e.choseErrString() +} + +// ErrErrorAfterReauthentication is the error type returned when reauthentication +// succeeds, but an error occurs afterword (usually an HTTP error). +type ErrErrorAfterReauthentication struct { + BaseError + ErrOriginal error +} + +func (e ErrErrorAfterReauthentication) Error() string { + e.DefaultErrString = fmt.Sprintf("Successfully re-authenticated, but got error executing request: %s", e.ErrOriginal) + return e.choseErrString() +} + +// ErrServiceNotFound is returned when no service in a service catalog matches +// the provided EndpointOpts. This is generally returned by provider service +// factory methods like "NewComputeV2()" and can mean that a service is not +// enabled for your account. +type ErrServiceNotFound struct { + BaseError +} + +func (e ErrServiceNotFound) Error() string { + e.DefaultErrString = "No suitable service could be found in the service catalog." + return e.choseErrString() +} + +// ErrEndpointNotFound is returned when no available endpoints match the +// provided EndpointOpts. This is also generally returned by provider service +// factory methods, and usually indicates that a region was specified +// incorrectly. +type ErrEndpointNotFound struct { + BaseError +} + +func (e ErrEndpointNotFound) Error() string { + e.DefaultErrString = "No suitable endpoint could be found in the service catalog." + return e.choseErrString() +} + +// ErrResourceNotFound is the error when trying to retrieve a resource's +// ID by name and the resource doesn't exist. +type ErrResourceNotFound struct { + BaseError + Name string + ResourceType string +} + +func (e ErrResourceNotFound) Error() string { + e.DefaultErrString = fmt.Sprintf("Unable to find %s with name %s", e.ResourceType, e.Name) + return e.choseErrString() +} + +// ErrMultipleResourcesFound is the error when trying to retrieve a resource's +// ID by name and multiple resources have the user-provided name. +type ErrMultipleResourcesFound struct { + BaseError + Name string + Count int + ResourceType string +} + +func (e ErrMultipleResourcesFound) Error() string { + e.DefaultErrString = fmt.Sprintf("Found %d %ss matching %s", e.Count, e.ResourceType, e.Name) + return e.choseErrString() +} + +// ErrUnexpectedType is the error when an unexpected type is encountered +type ErrUnexpectedType struct { + BaseError + Expected string + Actual string +} + +func (e ErrUnexpectedType) Error() string { + e.DefaultErrString = fmt.Sprintf("Expected %s but got %s", e.Expected, e.Actual) + return e.choseErrString() +} + +func unacceptedAttributeErr(attribute string) string { + return fmt.Sprintf("The base Identity V3 API does not accept authentication by %s", attribute) +} + +func redundantWithTokenErr(attribute string) string { + return fmt.Sprintf("%s may not be provided when authenticating with a TokenID", attribute) +} + +func redundantWithUserID(attribute string) string { + return fmt.Sprintf("%s may not be provided when authenticating with a UserID", attribute) +} + +// ErrAPIKeyProvided indicates that an APIKey was provided but can't be used. +type ErrAPIKeyProvided struct{ BaseError } + +func (e ErrAPIKeyProvided) Error() string { + return unacceptedAttributeErr("APIKey") +} + +// ErrTenantIDProvided indicates that a TenantID was provided but can't be used. +type ErrTenantIDProvided struct{ BaseError } + +func (e ErrTenantIDProvided) Error() string { + return unacceptedAttributeErr("TenantID") +} + +// ErrTenantNameProvided indicates that a TenantName was provided but can't be used. +type ErrTenantNameProvided struct{ BaseError } + +func (e ErrTenantNameProvided) Error() string { + return unacceptedAttributeErr("TenantName") +} + +// ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead. +type ErrUsernameWithToken struct{ BaseError } + +func (e ErrUsernameWithToken) Error() string { + return redundantWithTokenErr("Username") +} + +// ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead. +type ErrUserIDWithToken struct{ BaseError } + +func (e ErrUserIDWithToken) Error() string { + return redundantWithTokenErr("UserID") +} + +// ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead. +type ErrDomainIDWithToken struct{ BaseError } + +func (e ErrDomainIDWithToken) Error() string { + return redundantWithTokenErr("DomainID") +} + +// ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s +type ErrDomainNameWithToken struct{ BaseError } + +func (e ErrDomainNameWithToken) Error() string { + return redundantWithTokenErr("DomainName") +} + +// ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once. +type ErrUsernameOrUserID struct{ BaseError } + +func (e ErrUsernameOrUserID) Error() string { + return "Exactly one of Username and UserID must be provided for password authentication" +} + +// ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used. +type ErrDomainIDWithUserID struct{ BaseError } + +func (e ErrDomainIDWithUserID) Error() string { + return redundantWithUserID("DomainID") +} + +// ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used. +type ErrDomainNameWithUserID struct{ BaseError } + +func (e ErrDomainNameWithUserID) Error() string { + return redundantWithUserID("DomainName") +} + +// ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it. +// It may also indicate that both a DomainID and a DomainName were provided at once. +type ErrDomainIDOrDomainName struct{ BaseError } + +func (e ErrDomainIDOrDomainName) Error() string { + return "You must provide exactly one of DomainID or DomainName to authenticate by Username" +} + +// ErrMissingPassword indicates that no password was provided and no token is available. +type ErrMissingPassword struct{ BaseError } + +func (e ErrMissingPassword) Error() string { + return "You must provide a password to authenticate" +} + +// ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present. +type ErrScopeDomainIDOrDomainName struct{ BaseError } + +func (e ErrScopeDomainIDOrDomainName) Error() string { + return "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName" +} + +// ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope. +type ErrScopeProjectIDOrProjectName struct{ BaseError } + +func (e ErrScopeProjectIDOrProjectName) Error() string { + return "You must provide at most one of ProjectID or ProjectName in a Scope" +} + +// ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope. +type ErrScopeProjectIDAlone struct{ BaseError } + +func (e ErrScopeProjectIDAlone) Error() string { + return "ProjectID must be supplied alone in a Scope" +} + +// ErrScopeEmpty indicates that no credentials were provided in a Scope. +type ErrScopeEmpty struct{ BaseError } + +func (e ErrScopeEmpty) Error() string { + return "You must provide either a Project or Domain in a Scope" +} + +// ErrAppCredMissingSecret indicates that no Application Credential Secret was provided with Application Credential ID or Name +type ErrAppCredMissingSecret struct{ BaseError } + +func (e ErrAppCredMissingSecret) Error() string { + return "You must provide an Application Credential Secret" +} diff --git a/vendor/github.com/gophercloud/gophercloud/go.mod b/vendor/github.com/gophercloud/gophercloud/go.mod new file mode 100644 index 000000000..d1ee3b472 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/go.mod @@ -0,0 +1,7 @@ +module github.com/gophercloud/gophercloud + +require ( + golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 + golang.org/x/sys v0.0.0-20190209173611-3b5209105503 // indirect + gopkg.in/yaml.v2 v2.2.2 +) diff --git a/vendor/github.com/gophercloud/gophercloud/go.sum b/vendor/github.com/gophercloud/gophercloud/go.sum new file mode 100644 index 000000000..33cb0be8a --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/go.sum @@ -0,0 +1,8 @@ +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503 h1:5SvYFrOM3W8Mexn9/oA44Ji7vhXAZQ9hiP+1Q/DMrWg= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go b/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go new file mode 100644 index 000000000..0e8d90ff8 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go @@ -0,0 +1,125 @@ +package openstack + +import ( + "os" + + "github.com/gophercloud/gophercloud" +) + +var nilOptions = gophercloud.AuthOptions{} + +/* +AuthOptionsFromEnv fills out an identity.AuthOptions structure with the +settings found on the various OpenStack OS_* environment variables. + +The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME, +OS_PASSWORD and OS_PROJECT_ID. + +Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must have settings, +or an error will result. OS_PROJECT_ID, is optional. + +OS_TENANT_ID and OS_TENANT_NAME are deprecated forms of OS_PROJECT_ID and +OS_PROJECT_NAME and the latter are expected against a v3 auth api. + +If OS_PROJECT_ID and OS_PROJECT_NAME are set, they will still be referred +as "tenant" in Gophercloud. + +If OS_PROJECT_NAME is set, it requires OS_PROJECT_ID to be set as well to +handle projects not on the default domain. + +To use this function, first set the OS_* environment variables (for example, +by sourcing an `openrc` file), then: + + opts, err := openstack.AuthOptionsFromEnv() + provider, err := openstack.AuthenticatedClient(opts) +*/ +func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) { + authURL := os.Getenv("OS_AUTH_URL") + username := os.Getenv("OS_USERNAME") + userID := os.Getenv("OS_USERID") + password := os.Getenv("OS_PASSWORD") + tenantID := os.Getenv("OS_TENANT_ID") + tenantName := os.Getenv("OS_TENANT_NAME") + domainID := os.Getenv("OS_DOMAIN_ID") + domainName := os.Getenv("OS_DOMAIN_NAME") + applicationCredentialID := os.Getenv("OS_APPLICATION_CREDENTIAL_ID") + applicationCredentialName := os.Getenv("OS_APPLICATION_CREDENTIAL_NAME") + applicationCredentialSecret := os.Getenv("OS_APPLICATION_CREDENTIAL_SECRET") + + // If OS_PROJECT_ID is set, overwrite tenantID with the value. + if v := os.Getenv("OS_PROJECT_ID"); v != "" { + tenantID = v + } + + // If OS_PROJECT_NAME is set, overwrite tenantName with the value. + if v := os.Getenv("OS_PROJECT_NAME"); v != "" { + tenantName = v + } + + if authURL == "" { + err := gophercloud.ErrMissingEnvironmentVariable{ + EnvironmentVariable: "OS_AUTH_URL", + } + return nilOptions, err + } + + if userID == "" && username == "" { + // Empty username and userID could be ignored, when applicationCredentialID and applicationCredentialSecret are set + if applicationCredentialID == "" && applicationCredentialSecret == "" { + err := gophercloud.ErrMissingAnyoneOfEnvironmentVariables{ + EnvironmentVariables: []string{"OS_USERID", "OS_USERNAME"}, + } + return nilOptions, err + } + } + + if password == "" && applicationCredentialID == "" && applicationCredentialName == "" { + err := gophercloud.ErrMissingEnvironmentVariable{ + EnvironmentVariable: "OS_PASSWORD", + } + return nilOptions, err + } + + if (applicationCredentialID != "" || applicationCredentialName != "") && applicationCredentialSecret == "" { + err := gophercloud.ErrMissingEnvironmentVariable{ + EnvironmentVariable: "OS_APPLICATION_CREDENTIAL_SECRET", + } + return nilOptions, err + } + + if domainID == "" && domainName == "" && tenantID == "" && tenantName != "" { + err := gophercloud.ErrMissingEnvironmentVariable{ + EnvironmentVariable: "OS_PROJECT_ID", + } + return nilOptions, err + } + + if applicationCredentialID == "" && applicationCredentialName != "" && applicationCredentialSecret != "" { + if userID == "" && username == "" { + return nilOptions, gophercloud.ErrMissingAnyoneOfEnvironmentVariables{ + EnvironmentVariables: []string{"OS_USERID", "OS_USERNAME"}, + } + } + if username != "" && domainID == "" && domainName == "" { + return nilOptions, gophercloud.ErrMissingAnyoneOfEnvironmentVariables{ + EnvironmentVariables: []string{"OS_DOMAIN_ID", "OS_DOMAIN_NAME"}, + } + } + } + + ao := gophercloud.AuthOptions{ + IdentityEndpoint: authURL, + UserID: userID, + Username: username, + Password: password, + TenantID: tenantID, + TenantName: tenantName, + DomainID: domainID, + DomainName: domainName, + ApplicationCredentialID: applicationCredentialID, + ApplicationCredentialName: applicationCredentialName, + ApplicationCredentialSecret: applicationCredentialSecret, + } + + return ao, nil +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/client.go b/vendor/github.com/gophercloud/gophercloud/openstack/client.go new file mode 100644 index 000000000..50f239711 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/client.go @@ -0,0 +1,438 @@ +package openstack + +import ( + "fmt" + "reflect" + + "github.com/gophercloud/gophercloud" + tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens" + tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens" + "github.com/gophercloud/gophercloud/openstack/utils" +) + +const ( + // v2 represents Keystone v2. + // It should never increase beyond 2.0. + v2 = "v2.0" + + // v3 represents Keystone v3. + // The version can be anything from v3 to v3.x. + v3 = "v3" +) + +/* +NewClient prepares an unauthenticated ProviderClient instance. +Most users will probably prefer using the AuthenticatedClient function +instead. + +This is useful if you wish to explicitly control the version of the identity +service that's used for authentication explicitly, for example. + +A basic example of using this would be: + + ao, err := openstack.AuthOptionsFromEnv() + provider, err := openstack.NewClient(ao.IdentityEndpoint) + client, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{}) +*/ +func NewClient(endpoint string) (*gophercloud.ProviderClient, error) { + base, err := utils.BaseEndpoint(endpoint) + if err != nil { + return nil, err + } + + endpoint = gophercloud.NormalizeURL(endpoint) + base = gophercloud.NormalizeURL(base) + + p := new(gophercloud.ProviderClient) + p.IdentityBase = base + p.IdentityEndpoint = endpoint + p.UseTokenLock() + + return p, nil +} + +/* +AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint +specified by the options, acquires a token, and returns a Provider Client +instance that's ready to operate. + +If the full path to a versioned identity endpoint was specified (example: +http://example.com:5000/v3), that path will be used as the endpoint to query. + +If a versionless endpoint was specified (example: http://example.com:5000/), +the endpoint will be queried to determine which versions of the identity service +are available, then chooses the most recent or most supported version. + +Example: + + ao, err := openstack.AuthOptionsFromEnv() + provider, err := openstack.AuthenticatedClient(ao) + client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{ + Region: os.Getenv("OS_REGION_NAME"), + }) +*/ +func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) { + client, err := NewClient(options.IdentityEndpoint) + if err != nil { + return nil, err + } + + err = Authenticate(client, options) + if err != nil { + return nil, err + } + return client, nil +} + +// Authenticate or re-authenticate against the most recent identity service +// supported at the provided endpoint. +func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error { + versions := []*utils.Version{ + {ID: v2, Priority: 20, Suffix: "/v2.0/"}, + {ID: v3, Priority: 30, Suffix: "/v3/"}, + } + + chosen, endpoint, err := utils.ChooseVersion(client, versions) + if err != nil { + return err + } + + switch chosen.ID { + case v2: + return v2auth(client, endpoint, options, gophercloud.EndpointOpts{}) + case v3: + return v3auth(client, endpoint, &options, gophercloud.EndpointOpts{}) + default: + // The switch statement must be out of date from the versions list. + return fmt.Errorf("Unrecognized identity version: %s", chosen.ID) + } +} + +// AuthenticateV2 explicitly authenticates against the identity v2 endpoint. +func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error { + return v2auth(client, "", options, eo) +} + +func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error { + v2Client, err := NewIdentityV2(client, eo) + if err != nil { + return err + } + + if endpoint != "" { + v2Client.Endpoint = endpoint + } + + v2Opts := tokens2.AuthOptions{ + IdentityEndpoint: options.IdentityEndpoint, + Username: options.Username, + Password: options.Password, + TenantID: options.TenantID, + TenantName: options.TenantName, + AllowReauth: options.AllowReauth, + TokenID: options.TokenID, + } + + result := tokens2.Create(v2Client, v2Opts) + + err = client.SetTokenAndAuthResult(result) + if err != nil { + return err + } + + catalog, err := result.ExtractServiceCatalog() + if err != nil { + return err + } + + if options.AllowReauth { + // here we're creating a throw-away client (tac). it's a copy of the user's provider client, but + // with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`, + // this should retry authentication only once + tac := *client + tac.SetThrowaway(true) + tac.ReauthFunc = nil + tac.SetTokenAndAuthResult(nil) + tao := options + tao.AllowReauth = false + client.ReauthFunc = func() error { + err := v2auth(&tac, endpoint, tao, eo) + if err != nil { + return err + } + client.CopyTokenFrom(&tac) + return nil + } + } + client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { + return V2EndpointURL(catalog, opts) + } + + return nil +} + +// AuthenticateV3 explicitly authenticates against the identity v3 service. +func AuthenticateV3(client *gophercloud.ProviderClient, options tokens3.AuthOptionsBuilder, eo gophercloud.EndpointOpts) error { + return v3auth(client, "", options, eo) +} + +func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.AuthOptionsBuilder, eo gophercloud.EndpointOpts) error { + // Override the generated service endpoint with the one returned by the version endpoint. + v3Client, err := NewIdentityV3(client, eo) + if err != nil { + return err + } + + if endpoint != "" { + v3Client.Endpoint = endpoint + } + + result := tokens3.Create(v3Client, opts) + + err = client.SetTokenAndAuthResult(result) + if err != nil { + return err + } + + catalog, err := result.ExtractServiceCatalog() + if err != nil { + return err + } + + if opts.CanReauth() { + // here we're creating a throw-away client (tac). it's a copy of the user's provider client, but + // with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`, + // this should retry authentication only once + tac := *client + tac.SetThrowaway(true) + tac.ReauthFunc = nil + tac.SetTokenAndAuthResult(nil) + var tao tokens3.AuthOptionsBuilder + switch ot := opts.(type) { + case *gophercloud.AuthOptions: + o := *ot + o.AllowReauth = false + tao = &o + case *tokens3.AuthOptions: + o := *ot + o.AllowReauth = false + tao = &o + default: + tao = opts + } + client.ReauthFunc = func() error { + err := v3auth(&tac, endpoint, tao, eo) + if err != nil { + return err + } + client.CopyTokenFrom(&tac) + return nil + } + } + client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) { + return V3EndpointURL(catalog, opts) + } + + return nil +} + +// NewIdentityV2 creates a ServiceClient that may be used to interact with the +// v2 identity service. +func NewIdentityV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + endpoint := client.IdentityBase + "v2.0/" + clientType := "identity" + var err error + if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) { + eo.ApplyDefaults(clientType) + endpoint, err = client.EndpointLocator(eo) + if err != nil { + return nil, err + } + } + + return &gophercloud.ServiceClient{ + ProviderClient: client, + Endpoint: endpoint, + Type: clientType, + }, nil +} + +// NewIdentityV3 creates a ServiceClient that may be used to access the v3 +// identity service. +func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + endpoint := client.IdentityBase + "v3/" + clientType := "identity" + var err error + if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) { + eo.ApplyDefaults(clientType) + endpoint, err = client.EndpointLocator(eo) + if err != nil { + return nil, err + } + } + + // Ensure endpoint still has a suffix of v3. + // This is because EndpointLocator might have found a versionless + // endpoint or the published endpoint is still /v2.0. In both + // cases, we need to fix the endpoint to point to /v3. + base, err := utils.BaseEndpoint(endpoint) + if err != nil { + return nil, err + } + + base = gophercloud.NormalizeURL(base) + + endpoint = base + "v3/" + + return &gophercloud.ServiceClient{ + ProviderClient: client, + Endpoint: endpoint, + Type: clientType, + }, nil +} + +func initClientOpts(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts, clientType string) (*gophercloud.ServiceClient, error) { + sc := new(gophercloud.ServiceClient) + eo.ApplyDefaults(clientType) + url, err := client.EndpointLocator(eo) + if err != nil { + return sc, err + } + sc.ProviderClient = client + sc.Endpoint = url + sc.Type = clientType + return sc, nil +} + +// NewBareMetalV1 creates a ServiceClient that may be used with the v1 +// bare metal package. +func NewBareMetalV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "baremetal") +} + +// NewBareMetalIntrospectionV1 creates a ServiceClient that may be used with the v1 +// bare metal introspection package. +func NewBareMetalIntrospectionV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "baremetal-inspector") +} + +// NewObjectStorageV1 creates a ServiceClient that may be used with the v1 +// object storage package. +func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "object-store") +} + +// NewComputeV2 creates a ServiceClient that may be used with the v2 compute +// package. +func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "compute") +} + +// NewNetworkV2 creates a ServiceClient that may be used with the v2 network +// package. +func NewNetworkV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "network") + sc.ResourceBase = sc.Endpoint + "v2.0/" + return sc, err +} + +// NewBlockStorageV1 creates a ServiceClient that may be used to access the v1 +// block storage service. +func NewBlockStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "volume") +} + +// NewBlockStorageV2 creates a ServiceClient that may be used to access the v2 +// block storage service. +func NewBlockStorageV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "volumev2") +} + +// NewBlockStorageV3 creates a ServiceClient that may be used to access the v3 block storage service. +func NewBlockStorageV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "volumev3") +} + +// NewSharedFileSystemV2 creates a ServiceClient that may be used to access the v2 shared file system service. +func NewSharedFileSystemV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "sharev2") +} + +// NewCDNV1 creates a ServiceClient that may be used to access the OpenStack v1 +// CDN service. +func NewCDNV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "cdn") +} + +// NewOrchestrationV1 creates a ServiceClient that may be used to access the v1 +// orchestration service. +func NewOrchestrationV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "orchestration") +} + +// NewDBV1 creates a ServiceClient that may be used to access the v1 DB service. +func NewDBV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "database") +} + +// NewDNSV2 creates a ServiceClient that may be used to access the v2 DNS +// service. +func NewDNSV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "dns") + sc.ResourceBase = sc.Endpoint + "v2/" + return sc, err +} + +// NewImageServiceV2 creates a ServiceClient that may be used to access the v2 +// image service. +func NewImageServiceV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "image") + sc.ResourceBase = sc.Endpoint + "v2/" + return sc, err +} + +// NewLoadBalancerV2 creates a ServiceClient that may be used to access the v2 +// load balancer service. +func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "load-balancer") + sc.ResourceBase = sc.Endpoint + "v2.0/" + return sc, err +} + +// NewClusteringV1 creates a ServiceClient that may be used with the v1 clustering +// package. +func NewClusteringV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "clustering") +} + +// NewMessagingV2 creates a ServiceClient that may be used with the v2 messaging +// service. +func NewMessagingV2(client *gophercloud.ProviderClient, clientID string, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "messaging") + sc.MoreHeaders = map[string]string{"Client-ID": clientID} + return sc, err +} + +// NewContainerV1 creates a ServiceClient that may be used with v1 container package +func NewContainerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "container") +} + +// NewKeyManagerV1 creates a ServiceClient that may be used with the v1 key +// manager service. +func NewKeyManagerV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "key-manager") + sc.ResourceBase = sc.Endpoint + "v1/" + return sc, err +} + +// NewContainerInfraV1 creates a ServiceClient that may be used with the v1 container infra management +// package. +func NewContainerInfraV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "container-infra") +} + +// NewWorkflowV2 creates a ServiceClient that may be used with the v2 workflow management package. +func NewWorkflowV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) { + return initClientOpts(client, eo, "workflowv2") +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/doc.go new file mode 100644 index 000000000..617fafa63 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/doc.go @@ -0,0 +1,54 @@ +/* +Package recordsets provides information and interaction with the zone API +resource for the OpenStack DNS service. + +Example to List RecordSets by Zone + + listOpts := recordsets.ListOpts{ + Type: "A", + } + + zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" + + allPages, err := recordsets.ListByZone(dnsClient, zoneID, listOpts).AllPages() + if err != nil { + panic(err) + } + + allRRs, err := recordsets.ExtractRecordSets(allPages() + if err != nil { + panic(err) + } + + for _, rr := range allRRs { + fmt.Printf("%+v\n", rr) + } + +Example to Create a RecordSet + + createOpts := recordsets.CreateOpts{ + Name: "example.com.", + Type: "A", + TTL: 3600, + Description: "This is a recordset.", + Records: []string{"10.1.0.2"}, + } + + zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" + + rr, err := recordsets.Create(dnsClient, zoneID, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete a RecordSet + + zoneID := "fff121f5-c506-410a-a69e-2d73ef9cbdbd" + recordsetID := "d96ed01a-b439-4eb8-9b90-7a9f71017f7b" + + err := recordsets.Delete(dnsClient, zoneID, recordsetID).ExtractErr() + if err != nil { + panic(err) + } +*/ +package recordsets diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/requests.go new file mode 100644 index 000000000..1d9a77bcf --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/requests.go @@ -0,0 +1,173 @@ +package recordsets + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// ListOptsBuilder allows extensions to add additional parameters to the +// List request. +type ListOptsBuilder interface { + ToRecordSetListQuery() (string, error) +} + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the server attributes you want to see returned. Marker and Limit are used +// for pagination. +// https://developer.openstack.org/api-ref/dns/ +type ListOpts struct { + // Integer value for the limit of values to return. + Limit int `q:"limit"` + + // UUID of the recordset at which you want to set a marker. + Marker string `q:"marker"` + + Data string `q:"data"` + Description string `q:"description"` + Name string `q:"name"` + SortDir string `q:"sort_dir"` + SortKey string `q:"sort_key"` + Status string `q:"status"` + TTL int `q:"ttl"` + Type string `q:"type"` + ZoneID string `q:"zone_id"` +} + +// ToRecordSetListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToRecordSetListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// ListByZone implements the recordset list request. +func ListByZone(client *gophercloud.ServiceClient, zoneID string, opts ListOptsBuilder) pagination.Pager { + url := baseURL(client, zoneID) + if opts != nil { + query, err := opts.ToRecordSetListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return RecordSetPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// Get implements the recordset Get request. +func Get(client *gophercloud.ServiceClient, zoneID string, rrsetID string) (r GetResult) { + _, r.Err = client.Get(rrsetURL(client, zoneID, rrsetID), &r.Body, nil) + return +} + +// CreateOptsBuilder allows extensions to add additional attributes to the +// Create request. +type CreateOptsBuilder interface { + ToRecordSetCreateMap() (map[string]interface{}, error) +} + +// CreateOpts specifies the base attributes that may be used to create a +// RecordSet. +type CreateOpts struct { + // Name is the name of the RecordSet. + Name string `json:"name" required:"true"` + + // Description is a description of the RecordSet. + Description string `json:"description,omitempty"` + + // Records are the DNS records of the RecordSet. + Records []string `json:"records,omitempty"` + + // TTL is the time to live of the RecordSet. + TTL int `json:"ttl,omitempty"` + + // Type is the RRTYPE of the RecordSet. + Type string `json:"type,omitempty"` +} + +// ToRecordSetCreateMap formats an CreateOpts structure into a request body. +func (opts CreateOpts) ToRecordSetCreateMap() (map[string]interface{}, error) { + b, err := gophercloud.BuildRequestBody(opts, "") + if err != nil { + return nil, err + } + + return b, nil +} + +// Create creates a recordset in a given zone. +func Create(client *gophercloud.ServiceClient, zoneID string, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToRecordSetCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(baseURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{201, 202}, + }) + return +} + +// UpdateOptsBuilder allows extensions to add additional attributes to the +// Update request. +type UpdateOptsBuilder interface { + ToRecordSetUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts specifies the base attributes that may be updated on an existing +// RecordSet. +type UpdateOpts struct { + // Description is a description of the RecordSet. + Description *string `json:"description,omitempty"` + + // TTL is the time to live of the RecordSet. + TTL *int `json:"ttl,omitempty"` + + // Records are the DNS records of the RecordSet. + Records []string `json:"records,omitempty"` +} + +// ToRecordSetUpdateMap formats an UpdateOpts structure into a request body. +func (opts UpdateOpts) ToRecordSetUpdateMap() (map[string]interface{}, error) { + b, err := gophercloud.BuildRequestBody(opts, "") + if err != nil { + return nil, err + } + + // If opts.TTL was actually set, use 0 as a special value to send "null", + // even though the result from the API is 0. + // + // Otherwise, don't send the TTL field. + if opts.TTL != nil { + ttl := *(opts.TTL) + if ttl > 0 { + b["ttl"] = ttl + } else { + b["ttl"] = nil + } + } + + return b, nil +} + +// Update updates a recordset in a given zone +func Update(client *gophercloud.ServiceClient, zoneID string, rrsetID string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToRecordSetUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Put(rrsetURL(client, zoneID, rrsetID), &b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 202}, + }) + return +} + +// Delete removes an existing RecordSet. +func Delete(client *gophercloud.ServiceClient, zoneID string, rrsetID string) (r DeleteResult) { + _, r.Err = client.Delete(rrsetURL(client, zoneID, rrsetID), &gophercloud.RequestOpts{ + OkCodes: []int{202}, + }) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/results.go new file mode 100644 index 000000000..0fdc1fe52 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/results.go @@ -0,0 +1,147 @@ +package recordsets + +import ( + "encoding/json" + "time" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +type commonResult struct { + gophercloud.Result +} + +// Extract interprets a GetResult, CreateResult or UpdateResult as a RecordSet. +// An error is returned if the original call or the extraction failed. +func (r commonResult) Extract() (*RecordSet, error) { + var s *RecordSet + err := r.ExtractInto(&s) + return s, err +} + +// CreateResult is the result of a Create operation. Call its Extract method to +// interpret the result as a RecordSet. +type CreateResult struct { + commonResult +} + +// GetResult is the result of a Get operation. Call its Extract method to +// interpret the result as a RecordSet. +type GetResult struct { + commonResult +} + +// RecordSetPage is a single page of RecordSet results. +type RecordSetPage struct { + pagination.LinkedPageBase +} + +// UpdateResult is result of an Update operation. Call its Extract method to +// interpret the result as a RecordSet. +type UpdateResult struct { + commonResult +} + +// DeleteResult is result of a Delete operation. Call its ExtractErr method to +// determine if the operation succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// IsEmpty returns true if the page contains no results. +func (r RecordSetPage) IsEmpty() (bool, error) { + s, err := ExtractRecordSets(r) + return len(s) == 0, err +} + +// ExtractRecordSets extracts a slice of RecordSets from a List result. +func ExtractRecordSets(r pagination.Page) ([]RecordSet, error) { + var s struct { + RecordSets []RecordSet `json:"recordsets"` + } + err := (r.(RecordSetPage)).ExtractInto(&s) + return s.RecordSets, err +} + +// RecordSet represents a DNS Record Set. +type RecordSet struct { + // ID is the unique ID of the recordset + ID string `json:"id"` + + // ZoneID is the ID of the zone the recordset belongs to. + ZoneID string `json:"zone_id"` + + // ProjectID is the ID of the project that owns the recordset. + ProjectID string `json:"project_id"` + + // Name is the name of the recordset. + Name string `json:"name"` + + // ZoneName is the name of the zone the recordset belongs to. + ZoneName string `json:"zone_name"` + + // Type is the RRTYPE of the recordset. + Type string `json:"type"` + + // Records are the DNS records of the recordset. + Records []string `json:"records"` + + // TTL is the time to live of the recordset. + TTL int `json:"ttl"` + + // Status is the status of the recordset. + Status string `json:"status"` + + // Action is the current action in progress of the recordset. + Action string `json:"action"` + + // Description is the description of the recordset. + Description string `json:"description"` + + // Version is the revision of the recordset. + Version int `json:"version"` + + // CreatedAt is the date when the recordset was created. + CreatedAt time.Time `json:"-"` + + // UpdatedAt is the date when the recordset was updated. + UpdatedAt time.Time `json:"-"` + + // Links includes HTTP references to the itself, + // useful for passing along to other APIs that might want a recordset + // reference. + Links []gophercloud.Link `json:"-"` +} + +func (r *RecordSet) UnmarshalJSON(b []byte) error { + type tmp RecordSet + var s struct { + tmp + CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"` + Links map[string]interface{} `json:"links"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = RecordSet(s.tmp) + + r.CreatedAt = time.Time(s.CreatedAt) + r.UpdatedAt = time.Time(s.UpdatedAt) + + if s.Links != nil { + for rel, href := range s.Links { + if v, ok := href.(string); ok { + link := gophercloud.Link{ + Rel: rel, + Href: v, + } + r.Links = append(r.Links, link) + } + } + } + + return err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/urls.go new file mode 100644 index 000000000..5ec18d1bb --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/recordsets/urls.go @@ -0,0 +1,11 @@ +package recordsets + +import "github.com/gophercloud/gophercloud" + +func baseURL(c *gophercloud.ServiceClient, zoneID string) string { + return c.ServiceURL("zones", zoneID, "recordsets") +} + +func rrsetURL(c *gophercloud.ServiceClient, zoneID string, rrsetID string) string { + return c.ServiceURL("zones", zoneID, "recordsets", rrsetID) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/doc.go new file mode 100644 index 000000000..7733155bc --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/doc.go @@ -0,0 +1,48 @@ +/* +Package zones provides information and interaction with the zone API +resource for the OpenStack DNS service. + +Example to List Zones + + listOpts := zones.ListOpts{ + Email: "jdoe@example.com", + } + + allPages, err := zones.List(dnsClient, listOpts).AllPages() + if err != nil { + panic(err) + } + + allZones, err := zones.ExtractZones(allPages) + if err != nil { + panic(err) + } + + for _, zone := range allZones { + fmt.Printf("%+v\n", zone) + } + +Example to Create a Zone + + createOpts := zones.CreateOpts{ + Name: "example.com.", + Email: "jdoe@example.com", + Type: "PRIMARY", + TTL: 7200, + Description: "This is a zone.", + } + + zone, err := zones.Create(dnsClient, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete a Zone + + zoneID := "99d10f68-5623-4491-91a0-6daafa32b60e" + err := zones.Delete(dnsClient, zoneID).ExtractErr() + if err != nil { + panic(err) + } +*/ +package zones diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/requests.go new file mode 100644 index 000000000..78b08ae4f --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/requests.go @@ -0,0 +1,174 @@ +package zones + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// ListOptsBuilder allows extensions to add parameters to the List request. +type ListOptsBuilder interface { + ToZoneListQuery() (string, error) +} + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the server attributes you want to see returned. Marker and Limit are used +// for pagination. +// https://developer.openstack.org/api-ref/dns/ +type ListOpts struct { + // Integer value for the limit of values to return. + Limit int `q:"limit"` + + // UUID of the zone at which you want to set a marker. + Marker string `q:"marker"` + + Description string `q:"description"` + Email string `q:"email"` + Name string `q:"name"` + SortDir string `q:"sort_dir"` + SortKey string `q:"sort_key"` + Status string `q:"status"` + TTL int `q:"ttl"` + Type string `q:"type"` +} + +// ToZoneListQuery formats a ListOpts into a query string. +func (opts ListOpts) ToZoneListQuery() (string, error) { + q, err := gophercloud.BuildQueryString(opts) + return q.String(), err +} + +// List implements a zone List request. +func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { + url := baseURL(client) + if opts != nil { + query, err := opts.ToZoneListQuery() + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return ZonePage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// Get returns information about a zone, given its ID. +func Get(client *gophercloud.ServiceClient, zoneID string) (r GetResult) { + _, r.Err = client.Get(zoneURL(client, zoneID), &r.Body, nil) + return +} + +// CreateOptsBuilder allows extensions to add additional attributes to the +// Create request. +type CreateOptsBuilder interface { + ToZoneCreateMap() (map[string]interface{}, error) +} + +// CreateOpts specifies the attributes used to create a zone. +type CreateOpts struct { + // Attributes are settings that supply hints and filters for the zone. + Attributes map[string]string `json:"attributes,omitempty"` + + // Email contact of the zone. + Email string `json:"email,omitempty"` + + // Description of the zone. + Description string `json:"description,omitempty"` + + // Name of the zone. + Name string `json:"name" required:"true"` + + // Masters specifies zone masters if this is a secondary zone. + Masters []string `json:"masters,omitempty"` + + // TTL is the time to live of the zone. + TTL int `json:"-"` + + // Type specifies if this is a primary or secondary zone. + Type string `json:"type,omitempty"` +} + +// ToZoneCreateMap formats an CreateOpts structure into a request body. +func (opts CreateOpts) ToZoneCreateMap() (map[string]interface{}, error) { + b, err := gophercloud.BuildRequestBody(opts, "") + if err != nil { + return nil, err + } + + if opts.TTL > 0 { + b["ttl"] = opts.TTL + } + + return b, nil +} + +// Create implements a zone create request. +func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToZoneCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(baseURL(client), &b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{201, 202}, + }) + return +} + +// UpdateOptsBuilder allows extensions to add additional attributes to the +// Update request. +type UpdateOptsBuilder interface { + ToZoneUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts specifies the attributes to update a zone. +type UpdateOpts struct { + // Email contact of the zone. + Email string `json:"email,omitempty"` + + // TTL is the time to live of the zone. + TTL int `json:"-"` + + // Masters specifies zone masters if this is a secondary zone. + Masters []string `json:"masters,omitempty"` + + // Description of the zone. + Description *string `json:"description,omitempty"` +} + +// ToZoneUpdateMap formats an UpdateOpts structure into a request body. +func (opts UpdateOpts) ToZoneUpdateMap() (map[string]interface{}, error) { + b, err := gophercloud.BuildRequestBody(opts, "") + if err != nil { + return nil, err + } + + if opts.TTL > 0 { + b["ttl"] = opts.TTL + } + + return b, nil +} + +// Update implements a zone update request. +func Update(client *gophercloud.ServiceClient, zoneID string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToZoneUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Patch(zoneURL(client, zoneID), &b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 202}, + }) + return +} + +// Delete implements a zone delete request. +func Delete(client *gophercloud.ServiceClient, zoneID string) (r DeleteResult) { + _, r.Err = client.Delete(zoneURL(client, zoneID), &gophercloud.RequestOpts{ + OkCodes: []int{202}, + JSONResponse: &r.Body, + }) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/results.go new file mode 100644 index 000000000..a36eca7e2 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/results.go @@ -0,0 +1,166 @@ +package zones + +import ( + "encoding/json" + "strconv" + "time" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +type commonResult struct { + gophercloud.Result +} + +// Extract interprets a GetResult, CreateResult or UpdateResult as a Zone. +// An error is returned if the original call or the extraction failed. +func (r commonResult) Extract() (*Zone, error) { + var s *Zone + err := r.ExtractInto(&s) + return s, err +} + +// CreateResult is the result of a Create request. Call its Extract method +// to interpret the result as a Zone. +type CreateResult struct { + commonResult +} + +// GetResult is the result of a Get request. Call its Extract method +// to interpret the result as a Zone. +type GetResult struct { + commonResult +} + +// UpdateResult is the result of an Update request. Call its Extract method +// to interpret the result as a Zone. +type UpdateResult struct { + commonResult +} + +// DeleteResult is the result of a Delete request. Call its ExtractErr method +// to determine if the request succeeded or failed. +type DeleteResult struct { + commonResult +} + +// ZonePage is a single page of Zone results. +type ZonePage struct { + pagination.LinkedPageBase +} + +// IsEmpty returns true if the page contains no results. +func (r ZonePage) IsEmpty() (bool, error) { + s, err := ExtractZones(r) + return len(s) == 0, err +} + +// ExtractZones extracts a slice of Zones from a List result. +func ExtractZones(r pagination.Page) ([]Zone, error) { + var s struct { + Zones []Zone `json:"zones"` + } + err := (r.(ZonePage)).ExtractInto(&s) + return s.Zones, err +} + +// Zone represents a DNS zone. +type Zone struct { + // ID uniquely identifies this zone amongst all other zones, including those + // not accessible to the current tenant. + ID string `json:"id"` + + // PoolID is the ID for the pool hosting this zone. + PoolID string `json:"pool_id"` + + // ProjectID identifies the project/tenant owning this resource. + ProjectID string `json:"project_id"` + + // Name is the DNS Name for the zone. + Name string `json:"name"` + + // Email for the zone. Used in SOA records for the zone. + Email string `json:"email"` + + // Description for this zone. + Description string `json:"description"` + + // TTL is the Time to Live for the zone. + TTL int `json:"ttl"` + + // Serial is the current serial number for the zone. + Serial int `json:"-"` + + // Status is the status of the resource. + Status string `json:"status"` + + // Action is the current action in progress on the resource. + Action string `json:"action"` + + // Version of the resource. + Version int `json:"version"` + + // Attributes for the zone. + Attributes map[string]string `json:"attributes"` + + // Type of zone. Primary is controlled by Designate. + // Secondary zones are slaved from another DNS Server. + // Defaults to Primary. + Type string `json:"type"` + + // Masters is the servers for slave servers to get DNS information from. + Masters []string `json:"masters"` + + // CreatedAt is the date when the zone was created. + CreatedAt time.Time `json:"-"` + + // UpdatedAt is the date when the last change was made to the zone. + UpdatedAt time.Time `json:"-"` + + // TransferredAt is the last time an update was retrieved from the + // master servers. + TransferredAt time.Time `json:"-"` + + // Links includes HTTP references to the itself, useful for passing along + // to other APIs that might want a server reference. + Links map[string]interface{} `json:"links"` +} + +func (r *Zone) UnmarshalJSON(b []byte) error { + type tmp Zone + var s struct { + tmp + CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"` + UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at"` + TransferredAt gophercloud.JSONRFC3339MilliNoZ `json:"transferred_at"` + Serial interface{} `json:"serial"` + } + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + *r = Zone(s.tmp) + + r.CreatedAt = time.Time(s.CreatedAt) + r.UpdatedAt = time.Time(s.UpdatedAt) + r.TransferredAt = time.Time(s.TransferredAt) + + switch t := s.Serial.(type) { + case float64: + r.Serial = int(t) + case string: + switch t { + case "": + r.Serial = 0 + default: + serial, err := strconv.ParseFloat(t, 64) + if err != nil { + return err + } + r.Serial = int(serial) + } + } + + return err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/urls.go new file mode 100644 index 000000000..9bef70580 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/dns/v2/zones/urls.go @@ -0,0 +1,11 @@ +package zones + +import "github.com/gophercloud/gophercloud" + +func baseURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("zones") +} + +func zoneURL(c *gophercloud.ServiceClient, zoneID string) string { + return c.ServiceURL("zones", zoneID) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/doc.go new file mode 100644 index 000000000..cedf1f4d3 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/doc.go @@ -0,0 +1,14 @@ +/* +Package openstack contains resources for the individual OpenStack projects +supported in Gophercloud. It also includes functions to authenticate to an +OpenStack cloud and for provisioning various service-level clients. + +Example of Creating a Service Client + + ao, err := openstack.AuthOptionsFromEnv() + provider, err := openstack.AuthenticatedClient(ao) + client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{ + Region: os.Getenv("OS_REGION_NAME"), + }) +*/ +package openstack diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go b/vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go new file mode 100644 index 000000000..12c8aebcf --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go @@ -0,0 +1,107 @@ +package openstack + +import ( + "github.com/gophercloud/gophercloud" + tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens" + tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens" +) + +/* +V2EndpointURL discovers the endpoint URL for a specific service from a +ServiceCatalog acquired during the v2 identity service. + +The specified EndpointOpts are used to identify a unique, unambiguous endpoint +to return. It's an error both when multiple endpoints match the provided +criteria and when none do. The minimum that can be specified is a Type, but you +will also often need to specify a Name and/or a Region depending on what's +available on your OpenStack deployment. +*/ +func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { + // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided. + var endpoints = make([]tokens2.Endpoint, 0, 1) + for _, entry := range catalog.Entries { + if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { + for _, endpoint := range entry.Endpoints { + if opts.Region == "" || endpoint.Region == opts.Region { + endpoints = append(endpoints, endpoint) + } + } + } + } + + // Report an error if the options were ambiguous. + if len(endpoints) > 1 { + err := &ErrMultipleMatchingEndpointsV2{} + err.Endpoints = endpoints + return "", err + } + + // Extract the appropriate URL from the matching Endpoint. + for _, endpoint := range endpoints { + switch opts.Availability { + case gophercloud.AvailabilityPublic: + return gophercloud.NormalizeURL(endpoint.PublicURL), nil + case gophercloud.AvailabilityInternal: + return gophercloud.NormalizeURL(endpoint.InternalURL), nil + case gophercloud.AvailabilityAdmin: + return gophercloud.NormalizeURL(endpoint.AdminURL), nil + default: + err := &ErrInvalidAvailabilityProvided{} + err.Argument = "Availability" + err.Value = opts.Availability + return "", err + } + } + + // Report an error if there were no matching endpoints. + err := &gophercloud.ErrEndpointNotFound{} + return "", err +} + +/* +V3EndpointURL discovers the endpoint URL for a specific service from a Catalog +acquired during the v3 identity service. + +The specified EndpointOpts are used to identify a unique, unambiguous endpoint +to return. It's an error both when multiple endpoints match the provided +criteria and when none do. The minimum that can be specified is a Type, but you +will also often need to specify a Name and/or a Region depending on what's +available on your OpenStack deployment. +*/ +func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) { + // Extract Endpoints from the catalog entries that match the requested Type, Interface, + // Name if provided, and Region if provided. + var endpoints = make([]tokens3.Endpoint, 0, 1) + for _, entry := range catalog.Entries { + if (entry.Type == opts.Type) && (opts.Name == "" || entry.Name == opts.Name) { + for _, endpoint := range entry.Endpoints { + if opts.Availability != gophercloud.AvailabilityAdmin && + opts.Availability != gophercloud.AvailabilityPublic && + opts.Availability != gophercloud.AvailabilityInternal { + err := &ErrInvalidAvailabilityProvided{} + err.Argument = "Availability" + err.Value = opts.Availability + return "", err + } + if (opts.Availability == gophercloud.Availability(endpoint.Interface)) && + (opts.Region == "" || endpoint.Region == opts.Region || endpoint.RegionID == opts.Region) { + endpoints = append(endpoints, endpoint) + } + } + } + } + + // Report an error if the options were ambiguous. + if len(endpoints) > 1 { + return "", ErrMultipleMatchingEndpointsV3{Endpoints: endpoints} + } + + // Extract the URL from the matching Endpoint. + for _, endpoint := range endpoints { + return gophercloud.NormalizeURL(endpoint.URL), nil + } + + // Report an error if there were no matching endpoints. + err := &gophercloud.ErrEndpointNotFound{} + return "", err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/errors.go b/vendor/github.com/gophercloud/gophercloud/openstack/errors.go new file mode 100644 index 000000000..df410b1c6 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/errors.go @@ -0,0 +1,71 @@ +package openstack + +import ( + "fmt" + + "github.com/gophercloud/gophercloud" + tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens" + tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens" +) + +// ErrEndpointNotFound is the error when no suitable endpoint can be found +// in the user's catalog +type ErrEndpointNotFound struct{ gophercloud.BaseError } + +func (e ErrEndpointNotFound) Error() string { + return "No suitable endpoint could be found in the service catalog." +} + +// ErrInvalidAvailabilityProvided is the error when an invalid endpoint +// availability is provided +type ErrInvalidAvailabilityProvided struct{ gophercloud.ErrInvalidInput } + +func (e ErrInvalidAvailabilityProvided) Error() string { + return fmt.Sprintf("Unexpected availability in endpoint query: %s", e.Value) +} + +// ErrMultipleMatchingEndpointsV2 is the error when more than one endpoint +// for the given options is found in the v2 catalog +type ErrMultipleMatchingEndpointsV2 struct { + gophercloud.BaseError + Endpoints []tokens2.Endpoint +} + +func (e ErrMultipleMatchingEndpointsV2) Error() string { + return fmt.Sprintf("Discovered %d matching endpoints: %#v", len(e.Endpoints), e.Endpoints) +} + +// ErrMultipleMatchingEndpointsV3 is the error when more than one endpoint +// for the given options is found in the v3 catalog +type ErrMultipleMatchingEndpointsV3 struct { + gophercloud.BaseError + Endpoints []tokens3.Endpoint +} + +func (e ErrMultipleMatchingEndpointsV3) Error() string { + return fmt.Sprintf("Discovered %d matching endpoints: %#v", len(e.Endpoints), e.Endpoints) +} + +// ErrNoAuthURL is the error when the OS_AUTH_URL environment variable is not +// found +type ErrNoAuthURL struct{ gophercloud.ErrInvalidInput } + +func (e ErrNoAuthURL) Error() string { + return "Environment variable OS_AUTH_URL needs to be set." +} + +// ErrNoUsername is the error when the OS_USERNAME environment variable is not +// found +type ErrNoUsername struct{ gophercloud.ErrInvalidInput } + +func (e ErrNoUsername) Error() string { + return "Environment variable OS_USERNAME needs to be set." +} + +// ErrNoPassword is the error when the OS_PASSWORD environment variable is not +// found +type ErrNoPassword struct{ gophercloud.ErrInvalidInput } + +func (e ErrNoPassword) Error() string { + return "Environment variable OS_PASSWORD needs to be set." +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/doc.go new file mode 100644 index 000000000..45623369e --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/doc.go @@ -0,0 +1,65 @@ +/* +Package tenants provides information and interaction with the +tenants API resource for the OpenStack Identity service. + +See http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2 +and http://developer.openstack.org/api-ref-identity-v2.html#admin-tenants +for more information. + +Example to List Tenants + + listOpts := tenants.ListOpts{ + Limit: 2, + } + + allPages, err := tenants.List(identityClient, listOpts).AllPages() + if err != nil { + panic(err) + } + + allTenants, err := tenants.ExtractTenants(allPages) + if err != nil { + panic(err) + } + + for _, tenant := range allTenants { + fmt.Printf("%+v\n", tenant) + } + +Example to Create a Tenant + + createOpts := tenants.CreateOpts{ + Name: "tenant_name", + Description: "this is a tenant", + Enabled: gophercloud.Enabled, + } + + tenant, err := tenants.Create(identityClient, createOpts).Extract() + if err != nil { + panic(err) + } + +Example to Update a Tenant + + tenantID := "e6db6ed6277c461a853458589063b295" + + updateOpts := tenants.UpdateOpts{ + Description: "this is a new description", + Enabled: gophercloud.Disabled, + } + + tenant, err := tenants.Update(identityClient, tenantID, updateOpts).Extract() + if err != nil { + panic(err) + } + +Example to Delete a Tenant + + tenantID := "e6db6ed6277c461a853458589063b295" + + err := tenants.Delete(identitYClient, tenantID).ExtractErr() + if err != nil { + panic(err) + } +*/ +package tenants diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go new file mode 100644 index 000000000..f21a58f10 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go @@ -0,0 +1,116 @@ +package tenants + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// ListOpts filters the Tenants that are returned by the List call. +type ListOpts struct { + // Marker is the ID of the last Tenant on the previous page. + Marker string `q:"marker"` + + // Limit specifies the page size. + Limit int `q:"limit"` +} + +// List enumerates the Tenants to which the current token has access. +func List(client *gophercloud.ServiceClient, opts *ListOpts) pagination.Pager { + url := listURL(client) + if opts != nil { + q, err := gophercloud.BuildQueryString(opts) + if err != nil { + return pagination.Pager{Err: err} + } + url += q.String() + } + return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return TenantPage{pagination.LinkedPageBase{PageResult: r}} + }) +} + +// CreateOpts represents the options needed when creating new tenant. +type CreateOpts struct { + // Name is the name of the tenant. + Name string `json:"name" required:"true"` + + // Description is the description of the tenant. + Description string `json:"description,omitempty"` + + // Enabled sets the tenant status to enabled or disabled. + Enabled *bool `json:"enabled,omitempty"` +} + +// CreateOptsBuilder enables extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToTenantCreateMap() (map[string]interface{}, error) +} + +// ToTenantCreateMap assembles a request body based on the contents of +// a CreateOpts. +func (opts CreateOpts) ToTenantCreateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "tenant") +} + +// Create is the operation responsible for creating new tenant. +func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToTenantCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 201}, + }) + return +} + +// Get requests details on a single tenant by ID. +func Get(client *gophercloud.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(getURL(client, id), &r.Body, nil) + return +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToTenantUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts specifies the base attributes that may be updated on an existing +// tenant. +type UpdateOpts struct { + // Name is the name of the tenant. + Name string `json:"name,omitempty"` + + // Description is the description of the tenant. + Description *string `json:"description,omitempty"` + + // Enabled sets the tenant status to enabled or disabled. + Enabled *bool `json:"enabled,omitempty"` +} + +// ToTenantUpdateMap formats an UpdateOpts structure into a request body. +func (opts UpdateOpts) ToTenantUpdateMap() (map[string]interface{}, error) { + return gophercloud.BuildRequestBody(opts, "tenant") +} + +// Update is the operation responsible for updating exist tenants by their TenantID. +func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToTenantUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Put(updateURL(client, id), &b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Delete is the operation responsible for permanently deleting a tenant. +func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(deleteURL(client, id), nil) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/results.go new file mode 100644 index 000000000..bb6c2c6b0 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/results.go @@ -0,0 +1,91 @@ +package tenants + +import ( + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/pagination" +) + +// Tenant is a grouping of users in the identity service. +type Tenant struct { + // ID is a unique identifier for this tenant. + ID string `json:"id"` + + // Name is a friendlier user-facing name for this tenant. + Name string `json:"name"` + + // Description is a human-readable explanation of this Tenant's purpose. + Description string `json:"description"` + + // Enabled indicates whether or not a tenant is active. + Enabled bool `json:"enabled"` +} + +// TenantPage is a single page of Tenant results. +type TenantPage struct { + pagination.LinkedPageBase +} + +// IsEmpty determines whether or not a page of Tenants contains any results. +func (r TenantPage) IsEmpty() (bool, error) { + tenants, err := ExtractTenants(r) + return len(tenants) == 0, err +} + +// NextPageURL extracts the "next" link from the tenants_links section of the result. +func (r TenantPage) NextPageURL() (string, error) { + var s struct { + Links []gophercloud.Link `json:"tenants_links"` + } + err := r.ExtractInto(&s) + if err != nil { + return "", err + } + return gophercloud.ExtractNextURL(s.Links) +} + +// ExtractTenants returns a slice of Tenants contained in a single page of +// results. +func ExtractTenants(r pagination.Page) ([]Tenant, error) { + var s struct { + Tenants []Tenant `json:"tenants"` + } + err := (r.(TenantPage)).ExtractInto(&s) + return s.Tenants, err +} + +type tenantResult struct { + gophercloud.Result +} + +// Extract interprets any tenantResults as a Tenant. +func (r tenantResult) Extract() (*Tenant, error) { + var s struct { + Tenant *Tenant `json:"tenant"` + } + err := r.ExtractInto(&s) + return s.Tenant, err +} + +// GetResult is the response from a Get request. Call its Extract method to +// interpret it as a Tenant. +type GetResult struct { + tenantResult +} + +// CreateResult is the response from a Create request. Call its Extract method +// to interpret it as a Tenant. +type CreateResult struct { + tenantResult +} + +// DeleteResult is the response from a Get request. Call its ExtractErr method +// to determine if the call succeeded or failed. +type DeleteResult struct { + gophercloud.ErrResult +} + +// UpdateResult is the response from a Update request. Call its Extract method +// to interpret it as a Tenant. +type UpdateResult struct { + tenantResult +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/urls.go new file mode 100644 index 000000000..0f0266907 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/urls.go @@ -0,0 +1,23 @@ +package tenants + +import "github.com/gophercloud/gophercloud" + +func listURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("tenants") +} + +func getURL(client *gophercloud.ServiceClient, tenantID string) string { + return client.ServiceURL("tenants", tenantID) +} + +func createURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("tenants") +} + +func deleteURL(client *gophercloud.ServiceClient, tenantID string) string { + return client.ServiceURL("tenants", tenantID) +} + +func updateURL(client *gophercloud.ServiceClient, tenantID string) string { + return client.ServiceURL("tenants", tenantID) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/doc.go new file mode 100644 index 000000000..5375eea87 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/doc.go @@ -0,0 +1,46 @@ +/* +Package tokens provides information and interaction with the token API +resource for the OpenStack Identity service. + +For more information, see: +http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2 + +Example to Create an Unscoped Token from a Password + + authOpts := gophercloud.AuthOptions{ + Username: "user", + Password: "pass" + } + + token, err := tokens.Create(identityClient, authOpts).ExtractToken() + if err != nil { + panic(err) + } + +Example to Create a Token from a Tenant ID and Password + + authOpts := gophercloud.AuthOptions{ + Username: "user", + Password: "password", + TenantID: "fc394f2ab2df4114bde39905f800dc57" + } + + token, err := tokens.Create(identityClient, authOpts).ExtractToken() + if err != nil { + panic(err) + } + +Example to Create a Token from a Tenant Name and Password + + authOpts := gophercloud.AuthOptions{ + Username: "user", + Password: "password", + TenantName: "tenantname" + } + + token, err := tokens.Create(identityClient, authOpts).ExtractToken() + if err != nil { + panic(err) + } +*/ +package tokens diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go new file mode 100644 index 000000000..ab32368cc --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go @@ -0,0 +1,103 @@ +package tokens + +import "github.com/gophercloud/gophercloud" + +// PasswordCredentialsV2 represents the required options to authenticate +// with a username and password. +type PasswordCredentialsV2 struct { + Username string `json:"username" required:"true"` + Password string `json:"password" required:"true"` +} + +// TokenCredentialsV2 represents the required options to authenticate +// with a token. +type TokenCredentialsV2 struct { + ID string `json:"id,omitempty" required:"true"` +} + +// AuthOptionsV2 wraps a gophercloud AuthOptions in order to adhere to the +// AuthOptionsBuilder interface. +type AuthOptionsV2 struct { + PasswordCredentials *PasswordCredentialsV2 `json:"passwordCredentials,omitempty" xor:"TokenCredentials"` + + // The TenantID and TenantName fields are optional for the Identity V2 API. + // Some providers allow you to specify a TenantName instead of the TenantId. + // Some require both. Your provider's authentication policies will determine + // how these fields influence authentication. + TenantID string `json:"tenantId,omitempty"` + TenantName string `json:"tenantName,omitempty"` + + // TokenCredentials allows users to authenticate (possibly as another user) + // with an authentication token ID. + TokenCredentials *TokenCredentialsV2 `json:"token,omitempty" xor:"PasswordCredentials"` +} + +// AuthOptionsBuilder allows extensions to add additional parameters to the +// token create request. +type AuthOptionsBuilder interface { + // ToTokenCreateMap assembles the Create request body, returning an error + // if parameters are missing or inconsistent. + ToTokenV2CreateMap() (map[string]interface{}, error) +} + +// AuthOptions are the valid options for Openstack Identity v2 authentication. +// For field descriptions, see gophercloud.AuthOptions. +type AuthOptions struct { + IdentityEndpoint string `json:"-"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + TenantID string `json:"tenantId,omitempty"` + TenantName string `json:"tenantName,omitempty"` + AllowReauth bool `json:"-"` + TokenID string +} + +// ToTokenV2CreateMap builds a token request body from the given AuthOptions. +func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) { + v2Opts := AuthOptionsV2{ + TenantID: opts.TenantID, + TenantName: opts.TenantName, + } + + if opts.Password != "" { + v2Opts.PasswordCredentials = &PasswordCredentialsV2{ + Username: opts.Username, + Password: opts.Password, + } + } else { + v2Opts.TokenCredentials = &TokenCredentialsV2{ + ID: opts.TokenID, + } + } + + b, err := gophercloud.BuildRequestBody(v2Opts, "auth") + if err != nil { + return nil, err + } + return b, nil +} + +// Create authenticates to the identity service and attempts to acquire a Token. +// Generally, rather than interact with this call directly, end users should +// call openstack.AuthenticatedClient(), which abstracts all of the gory details +// about navigating service catalogs and such. +func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) (r CreateResult) { + b, err := auth.ToTokenV2CreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(CreateURL(client), b, &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 203}, + MoreHeaders: map[string]string{"X-Auth-Token": ""}, + }) + return +} + +// Get validates and retrieves information for user's token. +func Get(client *gophercloud.ServiceClient, token string) (r GetResult) { + _, r.Err = client.Get(GetURL(client, token), &r.Body, &gophercloud.RequestOpts{ + OkCodes: []int{200, 203}, + }) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go new file mode 100644 index 000000000..ee5da37f4 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go @@ -0,0 +1,174 @@ +package tokens + +import ( + "time" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants" +) + +// Token provides only the most basic information related to an authentication +// token. +type Token struct { + // ID provides the primary means of identifying a user to the OpenStack API. + // OpenStack defines this field as an opaque value, so do not depend on its + // content. It is safe, however, to compare for equality. + ID string + + // ExpiresAt provides a timestamp in ISO 8601 format, indicating when the + // authentication token becomes invalid. After this point in time, future + // API requests made using this authentication token will respond with + // errors. Either the caller will need to reauthenticate manually, or more + // preferably, the caller should exploit automatic re-authentication. + // See the AuthOptions structure for more details. + ExpiresAt time.Time + + // Tenant provides information about the tenant to which this token grants + // access. + Tenant tenants.Tenant +} + +// Role is a role for a user. +type Role struct { + Name string `json:"name"` +} + +// User is an OpenStack user. +type User struct { + ID string `json:"id"` + Name string `json:"name"` + UserName string `json:"username"` + Roles []Role `json:"roles"` +} + +// Endpoint represents a single API endpoint offered by a service. +// It provides the public and internal URLs, if supported, along with a region +// specifier, again if provided. +// +// The significance of the Region field will depend upon your provider. +// +// In addition, the interface offered by the service will have version +// information associated with it through the VersionId, VersionInfo, and +// VersionList fields, if provided or supported. +// +// In all cases, fields which aren't supported by the provider and service +// combined will assume a zero-value (""). +type Endpoint struct { + TenantID string `json:"tenantId"` + PublicURL string `json:"publicURL"` + InternalURL string `json:"internalURL"` + AdminURL string `json:"adminURL"` + Region string `json:"region"` + VersionID string `json:"versionId"` + VersionInfo string `json:"versionInfo"` + VersionList string `json:"versionList"` +} + +// CatalogEntry provides a type-safe interface to an Identity API V2 service +// catalog listing. +// +// Each class of service, such as cloud DNS or block storage services, will have +// a single CatalogEntry representing it. +// +// Note: when looking for the desired service, try, whenever possible, to key +// off the type field. Otherwise, you'll tie the representation of the service +// to a specific provider. +type CatalogEntry struct { + // Name will contain the provider-specified name for the service. + Name string `json:"name"` + + // Type will contain a type string if OpenStack defines a type for the + // service. Otherwise, for provider-specific services, the provider may assign + // their own type strings. + Type string `json:"type"` + + // Endpoints will let the caller iterate over all the different endpoints that + // may exist for the service. + Endpoints []Endpoint `json:"endpoints"` +} + +// ServiceCatalog provides a view into the service catalog from a previous, +// successful authentication. +type ServiceCatalog struct { + Entries []CatalogEntry +} + +// CreateResult is the response from a Create request. Use ExtractToken() to +// interpret it as a Token, or ExtractServiceCatalog() to interpret it as a +// service catalog. +type CreateResult struct { + gophercloud.Result +} + +// GetResult is the deferred response from a Get call, which is the same with a +// Created token. Use ExtractUser() to interpret it as a User. +type GetResult struct { + CreateResult +} + +// ExtractToken returns the just-created Token from a CreateResult. +func (r CreateResult) ExtractToken() (*Token, error) { + var s struct { + Access struct { + Token struct { + Expires string `json:"expires"` + ID string `json:"id"` + Tenant tenants.Tenant `json:"tenant"` + } `json:"token"` + } `json:"access"` + } + + err := r.ExtractInto(&s) + if err != nil { + return nil, err + } + + expiresTs, err := time.Parse(gophercloud.RFC3339Milli, s.Access.Token.Expires) + if err != nil { + return nil, err + } + + return &Token{ + ID: s.Access.Token.ID, + ExpiresAt: expiresTs, + Tenant: s.Access.Token.Tenant, + }, nil +} + +// ExtractTokenID implements the gophercloud.AuthResult interface. The returned +// string is the same as the ID field of the Token struct returned from +// ExtractToken(). +func (r CreateResult) ExtractTokenID() (string, error) { + var s struct { + Access struct { + Token struct { + ID string `json:"id"` + } `json:"token"` + } `json:"access"` + } + err := r.ExtractInto(&s) + return s.Access.Token.ID, err +} + +// ExtractServiceCatalog returns the ServiceCatalog that was generated along +// with the user's Token. +func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) { + var s struct { + Access struct { + Entries []CatalogEntry `json:"serviceCatalog"` + } `json:"access"` + } + err := r.ExtractInto(&s) + return &ServiceCatalog{Entries: s.Access.Entries}, err +} + +// ExtractUser returns the User from a GetResult. +func (r GetResult) ExtractUser() (*User, error) { + var s struct { + Access struct { + User User `json:"user"` + } `json:"access"` + } + err := r.ExtractInto(&s) + return &s.Access.User, err +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/urls.go new file mode 100644 index 000000000..ee0a28f20 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/urls.go @@ -0,0 +1,13 @@ +package tokens + +import "github.com/gophercloud/gophercloud" + +// CreateURL generates the URL used to create new Tokens. +func CreateURL(client *gophercloud.ServiceClient) string { + return client.ServiceURL("tokens") +} + +// GetURL generates the URL used to Validate Tokens. +func GetURL(client *gophercloud.ServiceClient, token string) string { + return client.ServiceURL("tokens", token) +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/doc.go new file mode 100644 index 000000000..966e128f1 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/doc.go @@ -0,0 +1,108 @@ +/* +Package tokens provides information and interaction with the token API +resource for the OpenStack Identity service. + +For more information, see: +http://developer.openstack.org/api-ref-identity-v3.html#tokens-v3 + +Example to Create a Token From a Username and Password + + authOptions := tokens.AuthOptions{ + UserID: "username", + Password: "password", + } + + token, err := tokens.Create(identityClient, authOptions).ExtractToken() + if err != nil { + panic(err) + } + +Example to Create a Token From a Username, Password, and Domain + + authOptions := tokens.AuthOptions{ + UserID: "username", + Password: "password", + DomainID: "default", + } + + token, err := tokens.Create(identityClient, authOptions).ExtractToken() + if err != nil { + panic(err) + } + + authOptions = tokens.AuthOptions{ + UserID: "username", + Password: "password", + DomainName: "default", + } + + token, err = tokens.Create(identityClient, authOptions).ExtractToken() + if err != nil { + panic(err) + } + +Example to Create a Token From a Token + + authOptions := tokens.AuthOptions{ + TokenID: "token_id", + } + + token, err := tokens.Create(identityClient, authOptions).ExtractToken() + if err != nil { + panic(err) + } + +Example to Create a Token from a Username and Password with Project ID Scope + + scope := tokens.Scope{ + ProjectID: "0fe36e73809d46aeae6705c39077b1b3", + } + + authOptions := tokens.AuthOptions{ + Scope: &scope, + UserID: "username", + Password: "password", + } + + token, err = tokens.Create(identityClient, authOptions).ExtractToken() + if err != nil { + panic(err) + } + +Example to Create a Token from a Username and Password with Domain ID Scope + + scope := tokens.Scope{ + DomainID: "default", + } + + authOptions := tokens.AuthOptions{ + Scope: &scope, + UserID: "username", + Password: "password", + } + + token, err = tokens.Create(identityClient, authOptions).ExtractToken() + if err != nil { + panic(err) + } + +Example to Create a Token from a Username and Password with Project Name Scope + + scope := tokens.Scope{ + ProjectName: "project_name", + DomainID: "default", + } + + authOptions := tokens.AuthOptions{ + Scope: &scope, + UserID: "username", + Password: "password", + } + + token, err = tokens.Create(identityClient, authOptions).ExtractToken() + if err != nil { + panic(err) + } + +*/ +package tokens diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go new file mode 100644 index 000000000..e4d766b23 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go @@ -0,0 +1,162 @@ +package tokens + +import "github.com/gophercloud/gophercloud" + +// Scope allows a created token to be limited to a specific domain or project. +type Scope struct { + ProjectID string + ProjectName string + DomainID string + DomainName string +} + +// AuthOptionsBuilder provides the ability for extensions to add additional +// parameters to AuthOptions. Extensions must satisfy all required methods. +type AuthOptionsBuilder interface { + // ToTokenV3CreateMap assembles the Create request body, returning an error + // if parameters are missing or inconsistent. + ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error) + ToTokenV3ScopeMap() (map[string]interface{}, error) + CanReauth() bool +} + +// AuthOptions represents options for authenticating a user. +type AuthOptions struct { + // IdentityEndpoint specifies the HTTP endpoint that is required to work with + // the Identity API of the appropriate version. While it's ultimately needed + // by all of the identity services, it will often be populated by a + // provider-level function. + IdentityEndpoint string `json:"-"` + + // Username is required if using Identity V2 API. Consult with your provider's + // control panel to discover your account's username. In Identity V3, either + // UserID or a combination of Username and DomainID or DomainName are needed. + Username string `json:"username,omitempty"` + UserID string `json:"id,omitempty"` + + Password string `json:"password,omitempty"` + + // At most one of DomainID and DomainName must be provided if using Username + // with Identity V3. Otherwise, either are optional. + DomainID string `json:"-"` + DomainName string `json:"name,omitempty"` + + // AllowReauth should be set to true if you grant permission for Gophercloud + // to cache your credentials in memory, and to allow Gophercloud to attempt + // to re-authenticate automatically if/when your token expires. If you set + // it to false, it will not cache these settings, but re-authentication will + // not be possible. This setting defaults to false. + AllowReauth bool `json:"-"` + + // TokenID allows users to authenticate (possibly as another user) with an + // authentication token ID. + TokenID string `json:"-"` + + // Authentication through Application Credentials requires supplying name, project and secret + // For project we can use TenantID + ApplicationCredentialID string `json:"-"` + ApplicationCredentialName string `json:"-"` + ApplicationCredentialSecret string `json:"-"` + + Scope Scope `json:"-"` +} + +// ToTokenV3CreateMap builds a request body from AuthOptions. +func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) { + gophercloudAuthOpts := gophercloud.AuthOptions{ + Username: opts.Username, + UserID: opts.UserID, + Password: opts.Password, + DomainID: opts.DomainID, + DomainName: opts.DomainName, + AllowReauth: opts.AllowReauth, + TokenID: opts.TokenID, + ApplicationCredentialID: opts.ApplicationCredentialID, + ApplicationCredentialName: opts.ApplicationCredentialName, + ApplicationCredentialSecret: opts.ApplicationCredentialSecret, + } + + return gophercloudAuthOpts.ToTokenV3CreateMap(scope) +} + +// ToTokenV3CreateMap builds a scope request body from AuthOptions. +func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) { + scope := gophercloud.AuthScope(opts.Scope) + + gophercloudAuthOpts := gophercloud.AuthOptions{ + Scope: &scope, + DomainID: opts.DomainID, + DomainName: opts.DomainName, + } + + return gophercloudAuthOpts.ToTokenV3ScopeMap() +} + +func (opts *AuthOptions) CanReauth() bool { + return opts.AllowReauth +} + +func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string { + return map[string]string{ + "X-Subject-Token": subjectToken, + } +} + +// Create authenticates and either generates a new token, or changes the Scope +// of an existing token. +func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder) (r CreateResult) { + scope, err := opts.ToTokenV3ScopeMap() + if err != nil { + r.Err = err + return + } + + b, err := opts.ToTokenV3CreateMap(scope) + if err != nil { + r.Err = err + return + } + + resp, err := c.Post(tokenURL(c), b, &r.Body, &gophercloud.RequestOpts{ + MoreHeaders: map[string]string{"X-Auth-Token": ""}, + }) + r.Err = err + if resp != nil { + r.Header = resp.Header + } + return +} + +// Get validates and retrieves information about another token. +func Get(c *gophercloud.ServiceClient, token string) (r GetResult) { + resp, err := c.Get(tokenURL(c), &r.Body, &gophercloud.RequestOpts{ + MoreHeaders: subjectTokenHeaders(c, token), + OkCodes: []int{200, 203}, + }) + if resp != nil { + r.Header = resp.Header + } + r.Err = err + return +} + +// Validate determines if a specified token is valid or not. +func Validate(c *gophercloud.ServiceClient, token string) (bool, error) { + resp, err := c.Head(tokenURL(c), &gophercloud.RequestOpts{ + MoreHeaders: subjectTokenHeaders(c, token), + OkCodes: []int{200, 204, 404}, + }) + if err != nil { + return false, err + } + + return resp.StatusCode == 200 || resp.StatusCode == 204, nil +} + +// Revoke immediately makes specified token invalid. +func Revoke(c *gophercloud.ServiceClient, token string) (r RevokeResult) { + _, r.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{ + MoreHeaders: subjectTokenHeaders(c, token), + }) + return +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go new file mode 100644 index 000000000..6f26c96bc --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go @@ -0,0 +1,178 @@ +package tokens + +import ( + "time" + + "github.com/gophercloud/gophercloud" +) + +// Endpoint represents a single API endpoint offered by a service. +// It matches either a public, internal or admin URL. +// If supported, it contains a region specifier, again if provided. +// The significance of the Region field will depend upon your provider. +type Endpoint struct { + ID string `json:"id"` + Region string `json:"region"` + RegionID string `json:"region_id"` + Interface string `json:"interface"` + URL string `json:"url"` +} + +// CatalogEntry provides a type-safe interface to an Identity API V3 service +// catalog listing. Each class of service, such as cloud DNS or block storage +// services, could have multiple CatalogEntry representing it (one by interface +// type, e.g public, admin or internal). +// +// Note: when looking for the desired service, try, whenever possible, to key +// off the type field. Otherwise, you'll tie the representation of the service +// to a specific provider. +type CatalogEntry struct { + // Service ID + ID string `json:"id"` + + // Name will contain the provider-specified name for the service. + Name string `json:"name"` + + // Type will contain a type string if OpenStack defines a type for the + // service. Otherwise, for provider-specific services, the provider may + // assign their own type strings. + Type string `json:"type"` + + // Endpoints will let the caller iterate over all the different endpoints that + // may exist for the service. + Endpoints []Endpoint `json:"endpoints"` +} + +// ServiceCatalog provides a view into the service catalog from a previous, +// successful authentication. +type ServiceCatalog struct { + Entries []CatalogEntry `json:"catalog"` +} + +// Domain provides information about the domain to which this token grants +// access. +type Domain struct { + ID string `json:"id"` + Name string `json:"name"` +} + +// User represents a user resource that exists in the Identity Service. +type User struct { + Domain Domain `json:"domain"` + ID string `json:"id"` + Name string `json:"name"` +} + +// Role provides information about roles to which User is authorized. +type Role struct { + ID string `json:"id"` + Name string `json:"name"` +} + +// Project provides information about project to which User is authorized. +type Project struct { + Domain Domain `json:"domain"` + ID string `json:"id"` + Name string `json:"name"` +} + +// commonResult is the response from a request. A commonResult has various +// methods which can be used to extract different details about the result. +type commonResult struct { + gophercloud.Result +} + +// Extract is a shortcut for ExtractToken. +// This function is deprecated and still present for backward compatibility. +func (r commonResult) Extract() (*Token, error) { + return r.ExtractToken() +} + +// ExtractToken interprets a commonResult as a Token. +func (r commonResult) ExtractToken() (*Token, error) { + var s Token + err := r.ExtractInto(&s) + if err != nil { + return nil, err + } + + // Parse the token itself from the stored headers. + s.ID = r.Header.Get("X-Subject-Token") + + return &s, err +} + +// ExtractTokenID implements the gophercloud.AuthResult interface. The returned +// string is the same as the ID field of the Token struct returned from +// ExtractToken(). +func (r CreateResult) ExtractTokenID() (string, error) { + return r.Header.Get("X-Subject-Token"), r.Err +} + +// ExtractServiceCatalog returns the ServiceCatalog that was generated along +// with the user's Token. +func (r commonResult) ExtractServiceCatalog() (*ServiceCatalog, error) { + var s ServiceCatalog + err := r.ExtractInto(&s) + return &s, err +} + +// ExtractUser returns the User that is the owner of the Token. +func (r commonResult) ExtractUser() (*User, error) { + var s struct { + User *User `json:"user"` + } + err := r.ExtractInto(&s) + return s.User, err +} + +// ExtractRoles returns Roles to which User is authorized. +func (r commonResult) ExtractRoles() ([]Role, error) { + var s struct { + Roles []Role `json:"roles"` + } + err := r.ExtractInto(&s) + return s.Roles, err +} + +// ExtractProject returns Project to which User is authorized. +func (r commonResult) ExtractProject() (*Project, error) { + var s struct { + Project *Project `json:"project"` + } + err := r.ExtractInto(&s) + return s.Project, err +} + +// CreateResult is the response from a Create request. Use ExtractToken() +// to interpret it as a Token, or ExtractServiceCatalog() to interpret it +// as a service catalog. +type CreateResult struct { + commonResult +} + +// GetResult is the response from a Get request. Use ExtractToken() +// to interpret it as a Token, or ExtractServiceCatalog() to interpret it +// as a service catalog. +type GetResult struct { + commonResult +} + +// RevokeResult is response from a Revoke request. +type RevokeResult struct { + commonResult +} + +// Token is a string that grants a user access to a controlled set of services +// in an OpenStack provider. Each Token is valid for a set length of time. +type Token struct { + // ID is the issued token. + ID string `json:"id"` + + // ExpiresAt is the timestamp at which this token will no longer be accepted. + ExpiresAt time.Time `json:"expires_at"` +} + +func (r commonResult) ExtractInto(v interface{}) error { + return r.ExtractIntoStructPtr(v, "token") +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/urls.go new file mode 100644 index 000000000..2f864a31c --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/urls.go @@ -0,0 +1,7 @@ +package tokens + +import "github.com/gophercloud/gophercloud" + +func tokenURL(c *gophercloud.ServiceClient) string { + return c.ServiceURL("auth", "tokens") +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go b/vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go new file mode 100644 index 000000000..40080f7af --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go @@ -0,0 +1,28 @@ +package utils + +import ( + "net/url" + "regexp" + "strings" +) + +// BaseEndpoint will return a URL without the /vX.Y +// portion of the URL. +func BaseEndpoint(endpoint string) (string, error) { + u, err := url.Parse(endpoint) + if err != nil { + return "", err + } + + u.RawQuery, u.Fragment = "", "" + + path := u.Path + versionRe := regexp.MustCompile("v[0-9.]+/?") + + if version := versionRe.FindString(path); version != "" { + versionIndex := strings.Index(path, version) + u.Path = path[:versionIndex] + } + + return u.String(), nil +} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/utils/choose_version.go b/vendor/github.com/gophercloud/gophercloud/openstack/utils/choose_version.go new file mode 100644 index 000000000..27da19f91 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/openstack/utils/choose_version.go @@ -0,0 +1,111 @@ +package utils + +import ( + "fmt" + "strings" + + "github.com/gophercloud/gophercloud" +) + +// Version is a supported API version, corresponding to a vN package within the appropriate service. +type Version struct { + ID string + Suffix string + Priority int +} + +var goodStatus = map[string]bool{ + "current": true, + "supported": true, + "stable": true, +} + +// ChooseVersion queries the base endpoint of an API to choose the most recent non-experimental alternative from a service's +// published versions. +// It returns the highest-Priority Version among the alternatives that are provided, as well as its corresponding endpoint. +func ChooseVersion(client *gophercloud.ProviderClient, recognized []*Version) (*Version, string, error) { + type linkResp struct { + Href string `json:"href"` + Rel string `json:"rel"` + } + + type valueResp struct { + ID string `json:"id"` + Status string `json:"status"` + Links []linkResp `json:"links"` + } + + type versionsResp struct { + Values []valueResp `json:"values"` + } + + type response struct { + Versions versionsResp `json:"versions"` + } + + normalize := func(endpoint string) string { + if !strings.HasSuffix(endpoint, "/") { + return endpoint + "/" + } + return endpoint + } + identityEndpoint := normalize(client.IdentityEndpoint) + + // If a full endpoint is specified, check version suffixes for a match first. + for _, v := range recognized { + if strings.HasSuffix(identityEndpoint, v.Suffix) { + return v, identityEndpoint, nil + } + } + + var resp response + _, err := client.Request("GET", client.IdentityBase, &gophercloud.RequestOpts{ + JSONResponse: &resp, + OkCodes: []int{200, 300}, + }) + + if err != nil { + return nil, "", err + } + + var highest *Version + var endpoint string + + for _, value := range resp.Versions.Values { + href := "" + for _, link := range value.Links { + if link.Rel == "self" { + href = normalize(link.Href) + } + } + + for _, version := range recognized { + if strings.Contains(value.ID, version.ID) { + // Prefer a version that exactly matches the provided endpoint. + if href == identityEndpoint { + if href == "" { + return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", value.ID, client.IdentityBase) + } + return version, href, nil + } + + // Otherwise, find the highest-priority version with a whitelisted status. + if goodStatus[strings.ToLower(value.Status)] { + if highest == nil || version.Priority > highest.Priority { + highest = version + endpoint = href + } + } + } + } + } + + if highest == nil { + return nil, "", fmt.Errorf("No supported version available from endpoint %s", client.IdentityBase) + } + if endpoint == "" { + return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", highest.ID, client.IdentityBase) + } + + return highest, endpoint, nil +} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/http.go b/vendor/github.com/gophercloud/gophercloud/pagination/http.go new file mode 100644 index 000000000..757295c42 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/pagination/http.go @@ -0,0 +1,60 @@ +package pagination + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "net/url" + "strings" + + "github.com/gophercloud/gophercloud" +) + +// PageResult stores the HTTP response that returned the current page of results. +type PageResult struct { + gophercloud.Result + url.URL +} + +// PageResultFrom parses an HTTP response as JSON and returns a PageResult containing the +// results, interpreting it as JSON if the content type indicates. +func PageResultFrom(resp *http.Response) (PageResult, error) { + var parsedBody interface{} + + defer resp.Body.Close() + rawBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return PageResult{}, err + } + + if strings.HasPrefix(resp.Header.Get("Content-Type"), "application/json") { + err = json.Unmarshal(rawBody, &parsedBody) + if err != nil { + return PageResult{}, err + } + } else { + parsedBody = rawBody + } + + return PageResultFromParsed(resp, parsedBody), err +} + +// PageResultFromParsed constructs a PageResult from an HTTP response that has already had its +// body parsed as JSON (and closed). +func PageResultFromParsed(resp *http.Response, body interface{}) PageResult { + return PageResult{ + Result: gophercloud.Result{ + Body: body, + Header: resp.Header, + }, + URL: *resp.Request.URL, + } +} + +// Request performs an HTTP request and extracts the http.Response from the result. +func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (*http.Response, error) { + return client.Get(url, nil, &gophercloud.RequestOpts{ + MoreHeaders: headers, + OkCodes: []int{200, 204, 300}, + }) +} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/linked.go b/vendor/github.com/gophercloud/gophercloud/pagination/linked.go new file mode 100644 index 000000000..3656fb7f8 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/pagination/linked.go @@ -0,0 +1,92 @@ +package pagination + +import ( + "fmt" + "reflect" + + "github.com/gophercloud/gophercloud" +) + +// LinkedPageBase may be embedded to implement a page that provides navigational "Next" and "Previous" links within its result. +type LinkedPageBase struct { + PageResult + + // LinkPath lists the keys that should be traversed within a response to arrive at the "next" pointer. + // If any link along the path is missing, an empty URL will be returned. + // If any link results in an unexpected value type, an error will be returned. + // When left as "nil", []string{"links", "next"} will be used as a default. + LinkPath []string +} + +// NextPageURL extracts the pagination structure from a JSON response and returns the "next" link, if one is present. +// It assumes that the links are available in a "links" element of the top-level response object. +// If this is not the case, override NextPageURL on your result type. +func (current LinkedPageBase) NextPageURL() (string, error) { + var path []string + var key string + + if current.LinkPath == nil { + path = []string{"links", "next"} + } else { + path = current.LinkPath + } + + submap, ok := current.Body.(map[string]interface{}) + if !ok { + err := gophercloud.ErrUnexpectedType{} + err.Expected = "map[string]interface{}" + err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) + return "", err + } + + for { + key, path = path[0], path[1:len(path)] + + value, ok := submap[key] + if !ok { + return "", nil + } + + if len(path) > 0 { + submap, ok = value.(map[string]interface{}) + if !ok { + err := gophercloud.ErrUnexpectedType{} + err.Expected = "map[string]interface{}" + err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) + return "", err + } + } else { + if value == nil { + // Actual null element. + return "", nil + } + + url, ok := value.(string) + if !ok { + err := gophercloud.ErrUnexpectedType{} + err.Expected = "string" + err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) + return "", err + } + + return url, nil + } + } +} + +// IsEmpty satisifies the IsEmpty method of the Page interface +func (current LinkedPageBase) IsEmpty() (bool, error) { + if b, ok := current.Body.([]interface{}); ok { + return len(b) == 0, nil + } + err := gophercloud.ErrUnexpectedType{} + err.Expected = "[]interface{}" + err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) + return true, err +} + +// GetBody returns the linked page's body. This method is needed to satisfy the +// Page interface. +func (current LinkedPageBase) GetBody() interface{} { + return current.Body +} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/marker.go b/vendor/github.com/gophercloud/gophercloud/pagination/marker.go new file mode 100644 index 000000000..52e53bae8 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/pagination/marker.go @@ -0,0 +1,58 @@ +package pagination + +import ( + "fmt" + "reflect" + + "github.com/gophercloud/gophercloud" +) + +// MarkerPage is a stricter Page interface that describes additional functionality required for use with NewMarkerPager. +// For convenience, embed the MarkedPageBase struct. +type MarkerPage interface { + Page + + // LastMarker returns the last "marker" value on this page. + LastMarker() (string, error) +} + +// MarkerPageBase is a page in a collection that's paginated by "limit" and "marker" query parameters. +type MarkerPageBase struct { + PageResult + + // Owner is a reference to the embedding struct. + Owner MarkerPage +} + +// NextPageURL generates the URL for the page of results after this one. +func (current MarkerPageBase) NextPageURL() (string, error) { + currentURL := current.URL + + mark, err := current.Owner.LastMarker() + if err != nil { + return "", err + } + + q := currentURL.Query() + q.Set("marker", mark) + currentURL.RawQuery = q.Encode() + + return currentURL.String(), nil +} + +// IsEmpty satisifies the IsEmpty method of the Page interface +func (current MarkerPageBase) IsEmpty() (bool, error) { + if b, ok := current.Body.([]interface{}); ok { + return len(b) == 0, nil + } + err := gophercloud.ErrUnexpectedType{} + err.Expected = "[]interface{}" + err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) + return true, err +} + +// GetBody returns the linked page's body. This method is needed to satisfy the +// Page interface. +func (current MarkerPageBase) GetBody() interface{} { + return current.Body +} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/pager.go b/vendor/github.com/gophercloud/gophercloud/pagination/pager.go new file mode 100644 index 000000000..42c0b2dbe --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/pagination/pager.go @@ -0,0 +1,251 @@ +package pagination + +import ( + "errors" + "fmt" + "net/http" + "reflect" + "strings" + + "github.com/gophercloud/gophercloud" +) + +var ( + // ErrPageNotAvailable is returned from a Pager when a next or previous page is requested, but does not exist. + ErrPageNotAvailable = errors.New("The requested page does not exist.") +) + +// Page must be satisfied by the result type of any resource collection. +// It allows clients to interact with the resource uniformly, regardless of whether or not or how it's paginated. +// Generally, rather than implementing this interface directly, implementors should embed one of the concrete PageBase structs, +// instead. +// Depending on the pagination strategy of a particular resource, there may be an additional subinterface that the result type +// will need to implement. +type Page interface { + // NextPageURL generates the URL for the page of data that follows this collection. + // Return "" if no such page exists. + NextPageURL() (string, error) + + // IsEmpty returns true if this Page has no items in it. + IsEmpty() (bool, error) + + // GetBody returns the Page Body. This is used in the `AllPages` method. + GetBody() interface{} +} + +// Pager knows how to advance through a specific resource collection, one page at a time. +type Pager struct { + client *gophercloud.ServiceClient + + initialURL string + + createPage func(r PageResult) Page + + firstPage Page + + Err error + + // Headers supplies additional HTTP headers to populate on each paged request. + Headers map[string]string +} + +// NewPager constructs a manually-configured pager. +// Supply the URL for the first page, a function that requests a specific page given a URL, and a function that counts a page. +func NewPager(client *gophercloud.ServiceClient, initialURL string, createPage func(r PageResult) Page) Pager { + return Pager{ + client: client, + initialURL: initialURL, + createPage: createPage, + } +} + +// WithPageCreator returns a new Pager that substitutes a different page creation function. This is +// useful for overriding List functions in delegation. +func (p Pager) WithPageCreator(createPage func(r PageResult) Page) Pager { + return Pager{ + client: p.client, + initialURL: p.initialURL, + createPage: createPage, + } +} + +func (p Pager) fetchNextPage(url string) (Page, error) { + resp, err := Request(p.client, p.Headers, url) + if err != nil { + return nil, err + } + + remembered, err := PageResultFrom(resp) + if err != nil { + return nil, err + } + + return p.createPage(remembered), nil +} + +// EachPage iterates over each page returned by a Pager, yielding one at a time to a handler function. +// Return "false" from the handler to prematurely stop iterating. +func (p Pager) EachPage(handler func(Page) (bool, error)) error { + if p.Err != nil { + return p.Err + } + currentURL := p.initialURL + for { + var currentPage Page + + // if first page has already been fetched, no need to fetch it again + if p.firstPage != nil { + currentPage = p.firstPage + p.firstPage = nil + } else { + var err error + currentPage, err = p.fetchNextPage(currentURL) + if err != nil { + return err + } + } + + empty, err := currentPage.IsEmpty() + if err != nil { + return err + } + if empty { + return nil + } + + ok, err := handler(currentPage) + if err != nil { + return err + } + if !ok { + return nil + } + + currentURL, err = currentPage.NextPageURL() + if err != nil { + return err + } + if currentURL == "" { + return nil + } + } +} + +// AllPages returns all the pages from a `List` operation in a single page, +// allowing the user to retrieve all the pages at once. +func (p Pager) AllPages() (Page, error) { + // pagesSlice holds all the pages until they get converted into as Page Body. + var pagesSlice []interface{} + // body will contain the final concatenated Page body. + var body reflect.Value + + // Grab a first page to ascertain the page body type. + firstPage, err := p.fetchNextPage(p.initialURL) + if err != nil { + return nil, err + } + // Store the page type so we can use reflection to create a new mega-page of + // that type. + pageType := reflect.TypeOf(firstPage) + + // if it's a single page, just return the firstPage (first page) + if _, found := pageType.FieldByName("SinglePageBase"); found { + return firstPage, nil + } + + // store the first page to avoid getting it twice + p.firstPage = firstPage + + // Switch on the page body type. Recognized types are `map[string]interface{}`, + // `[]byte`, and `[]interface{}`. + switch pb := firstPage.GetBody().(type) { + case map[string]interface{}: + // key is the map key for the page body if the body type is `map[string]interface{}`. + var key string + // Iterate over the pages to concatenate the bodies. + err = p.EachPage(func(page Page) (bool, error) { + b := page.GetBody().(map[string]interface{}) + for k, v := range b { + // If it's a linked page, we don't want the `links`, we want the other one. + if !strings.HasSuffix(k, "links") { + // check the field's type. we only want []interface{} (which is really []map[string]interface{}) + switch vt := v.(type) { + case []interface{}: + key = k + pagesSlice = append(pagesSlice, vt...) + } + } + } + return true, nil + }) + if err != nil { + return nil, err + } + // Set body to value of type `map[string]interface{}` + body = reflect.MakeMap(reflect.MapOf(reflect.TypeOf(key), reflect.TypeOf(pagesSlice))) + body.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(pagesSlice)) + case []byte: + // Iterate over the pages to concatenate the bodies. + err = p.EachPage(func(page Page) (bool, error) { + b := page.GetBody().([]byte) + pagesSlice = append(pagesSlice, b) + // seperate pages with a comma + pagesSlice = append(pagesSlice, []byte{10}) + return true, nil + }) + if err != nil { + return nil, err + } + if len(pagesSlice) > 0 { + // Remove the trailing comma. + pagesSlice = pagesSlice[:len(pagesSlice)-1] + } + var b []byte + // Combine the slice of slices in to a single slice. + for _, slice := range pagesSlice { + b = append(b, slice.([]byte)...) + } + // Set body to value of type `bytes`. + body = reflect.New(reflect.TypeOf(b)).Elem() + body.SetBytes(b) + case []interface{}: + // Iterate over the pages to concatenate the bodies. + err = p.EachPage(func(page Page) (bool, error) { + b := page.GetBody().([]interface{}) + pagesSlice = append(pagesSlice, b...) + return true, nil + }) + if err != nil { + return nil, err + } + // Set body to value of type `[]interface{}` + body = reflect.MakeSlice(reflect.TypeOf(pagesSlice), len(pagesSlice), len(pagesSlice)) + for i, s := range pagesSlice { + body.Index(i).Set(reflect.ValueOf(s)) + } + default: + err := gophercloud.ErrUnexpectedType{} + err.Expected = "map[string]interface{}/[]byte/[]interface{}" + err.Actual = fmt.Sprintf("%T", pb) + return nil, err + } + + // Each `Extract*` function is expecting a specific type of page coming back, + // otherwise the type assertion in those functions will fail. pageType is needed + // to create a type in this method that has the same type that the `Extract*` + // function is expecting and set the Body of that object to the concatenated + // pages. + page := reflect.New(pageType) + // Set the page body to be the concatenated pages. + page.Elem().FieldByName("Body").Set(body) + // Set any additional headers that were pass along. The `objectstorage` pacakge, + // for example, passes a Content-Type header. + h := make(http.Header) + for k, v := range p.Headers { + h.Add(k, v) + } + page.Elem().FieldByName("Header").Set(reflect.ValueOf(h)) + // Type assert the page to a Page interface so that the type assertion in the + // `Extract*` methods will work. + return page.Elem().Interface().(Page), err +} diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/pkg.go b/vendor/github.com/gophercloud/gophercloud/pagination/pkg.go new file mode 100644 index 000000000..912daea36 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/pagination/pkg.go @@ -0,0 +1,4 @@ +/* +Package pagination contains utilities and convenience structs that implement common pagination idioms within OpenStack APIs. +*/ +package pagination diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/single.go b/vendor/github.com/gophercloud/gophercloud/pagination/single.go new file mode 100644 index 000000000..4251d6491 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/pagination/single.go @@ -0,0 +1,33 @@ +package pagination + +import ( + "fmt" + "reflect" + + "github.com/gophercloud/gophercloud" +) + +// SinglePageBase may be embedded in a Page that contains all of the results from an operation at once. +type SinglePageBase PageResult + +// NextPageURL always returns "" to indicate that there are no more pages to return. +func (current SinglePageBase) NextPageURL() (string, error) { + return "", nil +} + +// IsEmpty satisifies the IsEmpty method of the Page interface +func (current SinglePageBase) IsEmpty() (bool, error) { + if b, ok := current.Body.([]interface{}); ok { + return len(b) == 0, nil + } + err := gophercloud.ErrUnexpectedType{} + err.Expected = "[]interface{}" + err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) + return true, err +} + +// GetBody returns the single page's body. This method is needed to satisfy the +// Page interface. +func (current SinglePageBase) GetBody() interface{} { + return current.Body +} diff --git a/vendor/github.com/gophercloud/gophercloud/params.go b/vendor/github.com/gophercloud/gophercloud/params.go new file mode 100644 index 000000000..b9986660c --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/params.go @@ -0,0 +1,491 @@ +package gophercloud + +import ( + "encoding/json" + "fmt" + "net/url" + "reflect" + "strconv" + "strings" + "time" +) + +/* +BuildRequestBody builds a map[string]interface from the given `struct`. If +parent is not an empty string, the final map[string]interface returned will +encapsulate the built one. For example: + + disk := 1 + createOpts := flavors.CreateOpts{ + ID: "1", + Name: "m1.tiny", + Disk: &disk, + RAM: 512, + VCPUs: 1, + RxTxFactor: 1.0, + } + + body, err := gophercloud.BuildRequestBody(createOpts, "flavor") + +The above example can be run as-is, however it is recommended to look at how +BuildRequestBody is used within Gophercloud to more fully understand how it +fits within the request process as a whole rather than use it directly as shown +above. +*/ +func BuildRequestBody(opts interface{}, parent string) (map[string]interface{}, error) { + optsValue := reflect.ValueOf(opts) + if optsValue.Kind() == reflect.Ptr { + optsValue = optsValue.Elem() + } + + optsType := reflect.TypeOf(opts) + if optsType.Kind() == reflect.Ptr { + optsType = optsType.Elem() + } + + optsMap := make(map[string]interface{}) + if optsValue.Kind() == reflect.Struct { + //fmt.Printf("optsValue.Kind() is a reflect.Struct: %+v\n", optsValue.Kind()) + for i := 0; i < optsValue.NumField(); i++ { + v := optsValue.Field(i) + f := optsType.Field(i) + + if f.Name != strings.Title(f.Name) { + //fmt.Printf("Skipping field: %s...\n", f.Name) + continue + } + + //fmt.Printf("Starting on field: %s...\n", f.Name) + + zero := isZero(v) + //fmt.Printf("v is zero?: %v\n", zero) + + // if the field has a required tag that's set to "true" + if requiredTag := f.Tag.Get("required"); requiredTag == "true" { + //fmt.Printf("Checking required field [%s]:\n\tv: %+v\n\tisZero:%v\n", f.Name, v.Interface(), zero) + // if the field's value is zero, return a missing-argument error + if zero { + // if the field has a 'required' tag, it can't have a zero-value + err := ErrMissingInput{} + err.Argument = f.Name + return nil, err + } + } + + if xorTag := f.Tag.Get("xor"); xorTag != "" { + //fmt.Printf("Checking `xor` tag for field [%s] with value %+v:\n\txorTag: %s\n", f.Name, v, xorTag) + xorField := optsValue.FieldByName(xorTag) + var xorFieldIsZero bool + if reflect.ValueOf(xorField.Interface()) == reflect.Zero(xorField.Type()) { + xorFieldIsZero = true + } else { + if xorField.Kind() == reflect.Ptr { + xorField = xorField.Elem() + } + xorFieldIsZero = isZero(xorField) + } + if !(zero != xorFieldIsZero) { + err := ErrMissingInput{} + err.Argument = fmt.Sprintf("%s/%s", f.Name, xorTag) + err.Info = fmt.Sprintf("Exactly one of %s and %s must be provided", f.Name, xorTag) + return nil, err + } + } + + if orTag := f.Tag.Get("or"); orTag != "" { + //fmt.Printf("Checking `or` tag for field with:\n\tname: %+v\n\torTag:%s\n", f.Name, orTag) + //fmt.Printf("field is zero?: %v\n", zero) + if zero { + orField := optsValue.FieldByName(orTag) + var orFieldIsZero bool + if reflect.ValueOf(orField.Interface()) == reflect.Zero(orField.Type()) { + orFieldIsZero = true + } else { + if orField.Kind() == reflect.Ptr { + orField = orField.Elem() + } + orFieldIsZero = isZero(orField) + } + if orFieldIsZero { + err := ErrMissingInput{} + err.Argument = fmt.Sprintf("%s/%s", f.Name, orTag) + err.Info = fmt.Sprintf("At least one of %s and %s must be provided", f.Name, orTag) + return nil, err + } + } + } + + jsonTag := f.Tag.Get("json") + if jsonTag == "-" { + continue + } + + if v.Kind() == reflect.Slice || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Slice) { + sliceValue := v + if sliceValue.Kind() == reflect.Ptr { + sliceValue = sliceValue.Elem() + } + + for i := 0; i < sliceValue.Len(); i++ { + element := sliceValue.Index(i) + if element.Kind() == reflect.Struct || (element.Kind() == reflect.Ptr && element.Elem().Kind() == reflect.Struct) { + _, err := BuildRequestBody(element.Interface(), "") + if err != nil { + return nil, err + } + } + } + } + if v.Kind() == reflect.Struct || (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) { + if zero { + //fmt.Printf("value before change: %+v\n", optsValue.Field(i)) + if jsonTag != "" { + jsonTagPieces := strings.Split(jsonTag, ",") + if len(jsonTagPieces) > 1 && jsonTagPieces[1] == "omitempty" { + if v.CanSet() { + if !v.IsNil() { + if v.Kind() == reflect.Ptr { + v.Set(reflect.Zero(v.Type())) + } + } + //fmt.Printf("value after change: %+v\n", optsValue.Field(i)) + } + } + } + continue + } + + //fmt.Printf("Calling BuildRequestBody with:\n\tv: %+v\n\tf.Name:%s\n", v.Interface(), f.Name) + _, err := BuildRequestBody(v.Interface(), f.Name) + if err != nil { + return nil, err + } + } + } + + //fmt.Printf("opts: %+v \n", opts) + + b, err := json.Marshal(opts) + if err != nil { + return nil, err + } + + //fmt.Printf("string(b): %s\n", string(b)) + + err = json.Unmarshal(b, &optsMap) + if err != nil { + return nil, err + } + + //fmt.Printf("optsMap: %+v\n", optsMap) + + if parent != "" { + optsMap = map[string]interface{}{parent: optsMap} + } + //fmt.Printf("optsMap after parent added: %+v\n", optsMap) + return optsMap, nil + } + // Return an error if the underlying type of 'opts' isn't a struct. + return nil, fmt.Errorf("Options type is not a struct.") +} + +// EnabledState is a convenience type, mostly used in Create and Update +// operations. Because the zero value of a bool is FALSE, we need to use a +// pointer instead to indicate zero-ness. +type EnabledState *bool + +// Convenience vars for EnabledState values. +var ( + iTrue = true + iFalse = false + + Enabled EnabledState = &iTrue + Disabled EnabledState = &iFalse +) + +// IPVersion is a type for the possible IP address versions. Valid instances +// are IPv4 and IPv6 +type IPVersion int + +const ( + // IPv4 is used for IP version 4 addresses + IPv4 IPVersion = 4 + // IPv6 is used for IP version 6 addresses + IPv6 IPVersion = 6 +) + +// IntToPointer is a function for converting integers into integer pointers. +// This is useful when passing in options to operations. +func IntToPointer(i int) *int { + return &i +} + +/* +MaybeString is an internal function to be used by request methods in individual +resource packages. + +It takes a string that might be a zero value and returns either a pointer to its +address or nil. This is useful for allowing users to conveniently omit values +from an options struct by leaving them zeroed, but still pass nil to the JSON +serializer so they'll be omitted from the request body. +*/ +func MaybeString(original string) *string { + if original != "" { + return &original + } + return nil +} + +/* +MaybeInt is an internal function to be used by request methods in individual +resource packages. + +Like MaybeString, it accepts an int that may or may not be a zero value, and +returns either a pointer to its address or nil. It's intended to hint that the +JSON serializer should omit its field. +*/ +func MaybeInt(original int) *int { + if original != 0 { + return &original + } + return nil +} + +/* +func isUnderlyingStructZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Ptr: + return isUnderlyingStructZero(v.Elem()) + default: + return isZero(v) + } +} +*/ + +var t time.Time + +func isZero(v reflect.Value) bool { + //fmt.Printf("\n\nchecking isZero for value: %+v\n", v) + switch v.Kind() { + case reflect.Ptr: + if v.IsNil() { + return true + } + return false + case reflect.Func, reflect.Map, reflect.Slice: + return v.IsNil() + case reflect.Array: + z := true + for i := 0; i < v.Len(); i++ { + z = z && isZero(v.Index(i)) + } + return z + case reflect.Struct: + if v.Type() == reflect.TypeOf(t) { + if v.Interface().(time.Time).IsZero() { + return true + } + return false + } + z := true + for i := 0; i < v.NumField(); i++ { + z = z && isZero(v.Field(i)) + } + return z + } + // Compare other types directly: + z := reflect.Zero(v.Type()) + //fmt.Printf("zero type for value: %+v\n\n\n", z) + return v.Interface() == z.Interface() +} + +/* +BuildQueryString is an internal function to be used by request methods in +individual resource packages. + +It accepts a tagged structure and expands it into a URL struct. Field names are +converted into query parameters based on a "q" tag. For example: + + type struct Something { + Bar string `q:"x_bar"` + Baz int `q:"lorem_ipsum"` + } + + instance := Something{ + Bar: "AAA", + Baz: "BBB", + } + +will be converted into "?x_bar=AAA&lorem_ipsum=BBB". + +The struct's fields may be strings, integers, or boolean values. Fields left at +their type's zero value will be omitted from the query. +*/ +func BuildQueryString(opts interface{}) (*url.URL, error) { + optsValue := reflect.ValueOf(opts) + if optsValue.Kind() == reflect.Ptr { + optsValue = optsValue.Elem() + } + + optsType := reflect.TypeOf(opts) + if optsType.Kind() == reflect.Ptr { + optsType = optsType.Elem() + } + + params := url.Values{} + + if optsValue.Kind() == reflect.Struct { + for i := 0; i < optsValue.NumField(); i++ { + v := optsValue.Field(i) + f := optsType.Field(i) + qTag := f.Tag.Get("q") + + // if the field has a 'q' tag, it goes in the query string + if qTag != "" { + tags := strings.Split(qTag, ",") + + // if the field is set, add it to the slice of query pieces + if !isZero(v) { + loop: + switch v.Kind() { + case reflect.Ptr: + v = v.Elem() + goto loop + case reflect.String: + params.Add(tags[0], v.String()) + case reflect.Int: + params.Add(tags[0], strconv.FormatInt(v.Int(), 10)) + case reflect.Bool: + params.Add(tags[0], strconv.FormatBool(v.Bool())) + case reflect.Slice: + switch v.Type().Elem() { + case reflect.TypeOf(0): + for i := 0; i < v.Len(); i++ { + params.Add(tags[0], strconv.FormatInt(v.Index(i).Int(), 10)) + } + default: + for i := 0; i < v.Len(); i++ { + params.Add(tags[0], v.Index(i).String()) + } + } + case reflect.Map: + if v.Type().Key().Kind() == reflect.String && v.Type().Elem().Kind() == reflect.String { + var s []string + for _, k := range v.MapKeys() { + value := v.MapIndex(k).String() + s = append(s, fmt.Sprintf("'%s':'%s'", k.String(), value)) + } + params.Add(tags[0], fmt.Sprintf("{%s}", strings.Join(s, ", "))) + } + } + } else { + // if the field has a 'required' tag, it can't have a zero-value + if requiredTag := f.Tag.Get("required"); requiredTag == "true" { + return &url.URL{}, fmt.Errorf("Required query parameter [%s] not set.", f.Name) + } + } + } + } + + return &url.URL{RawQuery: params.Encode()}, nil + } + // Return an error if the underlying type of 'opts' isn't a struct. + return nil, fmt.Errorf("Options type is not a struct.") +} + +/* +BuildHeaders is an internal function to be used by request methods in +individual resource packages. + +It accepts an arbitrary tagged structure and produces a string map that's +suitable for use as the HTTP headers of an outgoing request. Field names are +mapped to header names based in "h" tags. + + type struct Something { + Bar string `h:"x_bar"` + Baz int `h:"lorem_ipsum"` + } + + instance := Something{ + Bar: "AAA", + Baz: "BBB", + } + +will be converted into: + + map[string]string{ + "x_bar": "AAA", + "lorem_ipsum": "BBB", + } + +Untagged fields and fields left at their zero values are skipped. Integers, +booleans and string values are supported. +*/ +func BuildHeaders(opts interface{}) (map[string]string, error) { + optsValue := reflect.ValueOf(opts) + if optsValue.Kind() == reflect.Ptr { + optsValue = optsValue.Elem() + } + + optsType := reflect.TypeOf(opts) + if optsType.Kind() == reflect.Ptr { + optsType = optsType.Elem() + } + + optsMap := make(map[string]string) + if optsValue.Kind() == reflect.Struct { + for i := 0; i < optsValue.NumField(); i++ { + v := optsValue.Field(i) + f := optsType.Field(i) + hTag := f.Tag.Get("h") + + // if the field has a 'h' tag, it goes in the header + if hTag != "" { + tags := strings.Split(hTag, ",") + + // if the field is set, add it to the slice of query pieces + if !isZero(v) { + switch v.Kind() { + case reflect.String: + optsMap[tags[0]] = v.String() + case reflect.Int: + optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10) + case reflect.Bool: + optsMap[tags[0]] = strconv.FormatBool(v.Bool()) + } + } else { + // if the field has a 'required' tag, it can't have a zero-value + if requiredTag := f.Tag.Get("required"); requiredTag == "true" { + return optsMap, fmt.Errorf("Required header [%s] not set.", f.Name) + } + } + } + + } + return optsMap, nil + } + // Return an error if the underlying type of 'opts' isn't a struct. + return optsMap, fmt.Errorf("Options type is not a struct.") +} + +// IDSliceToQueryString takes a slice of elements and converts them into a query +// string. For example, if name=foo and slice=[]int{20, 40, 60}, then the +// result would be `?name=20&name=40&name=60' +func IDSliceToQueryString(name string, ids []int) string { + str := "" + for k, v := range ids { + if k == 0 { + str += "?" + } else { + str += "&" + } + str += fmt.Sprintf("%s=%s", name, strconv.Itoa(v)) + } + return str +} + +// IntWithinRange returns TRUE if an integer falls within a defined range, and +// FALSE if not. +func IntWithinRange(val, min, max int) bool { + return val > min && val < max +} diff --git a/vendor/github.com/gophercloud/gophercloud/provider_client.go b/vendor/github.com/gophercloud/gophercloud/provider_client.go new file mode 100644 index 000000000..fce00462f --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/provider_client.go @@ -0,0 +1,501 @@ +package gophercloud + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "io" + "io/ioutil" + "net/http" + "strings" + "sync" +) + +// DefaultUserAgent is the default User-Agent string set in the request header. +const DefaultUserAgent = "gophercloud/2.0.0" + +// UserAgent represents a User-Agent header. +type UserAgent struct { + // prepend is the slice of User-Agent strings to prepend to DefaultUserAgent. + // All the strings to prepend are accumulated and prepended in the Join method. + prepend []string +} + +// Prepend prepends a user-defined string to the default User-Agent string. Users +// may pass in one or more strings to prepend. +func (ua *UserAgent) Prepend(s ...string) { + ua.prepend = append(s, ua.prepend...) +} + +// Join concatenates all the user-defined User-Agend strings with the default +// Gophercloud User-Agent string. +func (ua *UserAgent) Join() string { + uaSlice := append(ua.prepend, DefaultUserAgent) + return strings.Join(uaSlice, " ") +} + +// ProviderClient stores details that are required to interact with any +// services within a specific provider's API. +// +// Generally, you acquire a ProviderClient by calling the NewClient method in +// the appropriate provider's child package, providing whatever authentication +// credentials are required. +type ProviderClient struct { + // IdentityBase is the base URL used for a particular provider's identity + // service - it will be used when issuing authenticatation requests. It + // should point to the root resource of the identity service, not a specific + // identity version. + IdentityBase string + + // IdentityEndpoint is the identity endpoint. This may be a specific version + // of the identity service. If this is the case, this endpoint is used rather + // than querying versions first. + IdentityEndpoint string + + // TokenID is the ID of the most recently issued valid token. + // NOTE: Aside from within a custom ReauthFunc, this field shouldn't be set by an application. + // To safely read or write this value, call `Token` or `SetToken`, respectively + TokenID string + + // EndpointLocator describes how this provider discovers the endpoints for + // its constituent services. + EndpointLocator EndpointLocator + + // HTTPClient allows users to interject arbitrary http, https, or other transit behaviors. + HTTPClient http.Client + + // UserAgent represents the User-Agent header in the HTTP request. + UserAgent UserAgent + + // ReauthFunc is the function used to re-authenticate the user if the request + // fails with a 401 HTTP response code. This a needed because there may be multiple + // authentication functions for different Identity service versions. + ReauthFunc func() error + + // Throwaway determines whether if this client is a throw-away client. It's a copy of user's provider client + // with the token and reauth func zeroed. Such client can be used to perform reauthorization. + Throwaway bool + + // Context is the context passed to the HTTP request. + Context context.Context + + // mut is a mutex for the client. It protects read and write access to client attributes such as getting + // and setting the TokenID. + mut *sync.RWMutex + + // reauthmut is a mutex for reauthentication it attempts to ensure that only one reauthentication + // attempt happens at one time. + reauthmut *reauthlock + + authResult AuthResult +} + +// reauthlock represents a set of attributes used to help in the reauthentication process. +type reauthlock struct { + sync.RWMutex + reauthing bool + reauthingErr error + done *sync.Cond +} + +// AuthenticatedHeaders returns a map of HTTP headers that are common for all +// authenticated service requests. Blocks if Reauthenticate is in progress. +func (client *ProviderClient) AuthenticatedHeaders() (m map[string]string) { + if client.IsThrowaway() { + return + } + if client.reauthmut != nil { + client.reauthmut.Lock() + for client.reauthmut.reauthing { + client.reauthmut.done.Wait() + } + client.reauthmut.Unlock() + } + t := client.Token() + if t == "" { + return + } + return map[string]string{"X-Auth-Token": t} +} + +// UseTokenLock creates a mutex that is used to allow safe concurrent access to the auth token. +// If the application's ProviderClient is not used concurrently, this doesn't need to be called. +func (client *ProviderClient) UseTokenLock() { + client.mut = new(sync.RWMutex) + client.reauthmut = new(reauthlock) +} + +// GetAuthResult returns the result from the request that was used to obtain a +// provider client's Keystone token. +// +// The result is nil when authentication has not yet taken place, when the token +// was set manually with SetToken(), or when a ReauthFunc was used that does not +// record the AuthResult. +func (client *ProviderClient) GetAuthResult() AuthResult { + if client.mut != nil { + client.mut.RLock() + defer client.mut.RUnlock() + } + return client.authResult +} + +// Token safely reads the value of the auth token from the ProviderClient. Applications should +// call this method to access the token instead of the TokenID field +func (client *ProviderClient) Token() string { + if client.mut != nil { + client.mut.RLock() + defer client.mut.RUnlock() + } + return client.TokenID +} + +// SetToken safely sets the value of the auth token in the ProviderClient. Applications may +// use this method in a custom ReauthFunc. +// +// WARNING: This function is deprecated. Use SetTokenAndAuthResult() instead. +func (client *ProviderClient) SetToken(t string) { + if client.mut != nil { + client.mut.Lock() + defer client.mut.Unlock() + } + client.TokenID = t + client.authResult = nil +} + +// SetTokenAndAuthResult safely sets the value of the auth token in the +// ProviderClient and also records the AuthResult that was returned from the +// token creation request. Applications may call this in a custom ReauthFunc. +func (client *ProviderClient) SetTokenAndAuthResult(r AuthResult) error { + tokenID := "" + var err error + if r != nil { + tokenID, err = r.ExtractTokenID() + if err != nil { + return err + } + } + + if client.mut != nil { + client.mut.Lock() + defer client.mut.Unlock() + } + client.TokenID = tokenID + client.authResult = r + return nil +} + +// CopyTokenFrom safely copies the token from another ProviderClient into the +// this one. +func (client *ProviderClient) CopyTokenFrom(other *ProviderClient) { + if client.mut != nil { + client.mut.Lock() + defer client.mut.Unlock() + } + if other.mut != nil && other.mut != client.mut { + other.mut.RLock() + defer other.mut.RUnlock() + } + client.TokenID = other.TokenID + client.authResult = other.authResult +} + +// IsThrowaway safely reads the value of the client Throwaway field. +func (client *ProviderClient) IsThrowaway() bool { + if client.reauthmut != nil { + client.reauthmut.RLock() + defer client.reauthmut.RUnlock() + } + return client.Throwaway +} + +// SetThrowaway safely sets the value of the client Throwaway field. +func (client *ProviderClient) SetThrowaway(v bool) { + if client.reauthmut != nil { + client.reauthmut.Lock() + defer client.reauthmut.Unlock() + } + client.Throwaway = v +} + +// Reauthenticate calls client.ReauthFunc in a thread-safe way. If this is +// called because of a 401 response, the caller may pass the previous token. In +// this case, the reauthentication can be skipped if another thread has already +// reauthenticated in the meantime. If no previous token is known, an empty +// string should be passed instead to force unconditional reauthentication. +func (client *ProviderClient) Reauthenticate(previousToken string) (err error) { + if client.ReauthFunc == nil { + return nil + } + + if client.reauthmut == nil { + return client.ReauthFunc() + } + + client.reauthmut.Lock() + if client.reauthmut.reauthing { + for !client.reauthmut.reauthing { + client.reauthmut.done.Wait() + } + err = client.reauthmut.reauthingErr + client.reauthmut.Unlock() + return err + } + client.reauthmut.Unlock() + + client.reauthmut.Lock() + client.reauthmut.reauthing = true + client.reauthmut.done = sync.NewCond(client.reauthmut) + client.reauthmut.reauthingErr = nil + client.reauthmut.Unlock() + + if previousToken == "" || client.TokenID == previousToken { + err = client.ReauthFunc() + } + + client.reauthmut.Lock() + client.reauthmut.reauthing = false + client.reauthmut.reauthingErr = err + client.reauthmut.done.Broadcast() + client.reauthmut.Unlock() + return +} + +// RequestOpts customizes the behavior of the provider.Request() method. +type RequestOpts struct { + // JSONBody, if provided, will be encoded as JSON and used as the body of the HTTP request. The + // content type of the request will default to "application/json" unless overridden by MoreHeaders. + // It's an error to specify both a JSONBody and a RawBody. + JSONBody interface{} + // RawBody contains an io.Reader that will be consumed by the request directly. No content-type + // will be set unless one is provided explicitly by MoreHeaders. + RawBody io.Reader + // JSONResponse, if provided, will be populated with the contents of the response body parsed as + // JSON. + JSONResponse interface{} + // OkCodes contains a list of numeric HTTP status codes that should be interpreted as success. If + // the response has a different code, an error will be returned. + OkCodes []int + // MoreHeaders specifies additional HTTP headers to be provide on the request. If a header is + // provided with a blank value (""), that header will be *omitted* instead: use this to suppress + // the default Accept header or an inferred Content-Type, for example. + MoreHeaders map[string]string + // ErrorContext specifies the resource error type to return if an error is encountered. + // This lets resources override default error messages based on the response status code. + ErrorContext error +} + +var applicationJSON = "application/json" + +// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication +// header will automatically be provided. +func (client *ProviderClient) Request(method, url string, options *RequestOpts) (*http.Response, error) { + var body io.Reader + var contentType *string + + // Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided + // io.ReadSeeker as-is. Default the content-type to application/json. + if options.JSONBody != nil { + if options.RawBody != nil { + return nil, errors.New("please provide only one of JSONBody or RawBody to gophercloud.Request()") + } + + rendered, err := json.Marshal(options.JSONBody) + if err != nil { + return nil, err + } + + body = bytes.NewReader(rendered) + contentType = &applicationJSON + } + + if options.RawBody != nil { + body = options.RawBody + } + + // Construct the http.Request. + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + if client.Context != nil { + req = req.WithContext(client.Context) + } + + // Populate the request headers. Apply options.MoreHeaders last, to give the caller the chance to + // modify or omit any header. + if contentType != nil { + req.Header.Set("Content-Type", *contentType) + } + req.Header.Set("Accept", applicationJSON) + + // Set the User-Agent header + req.Header.Set("User-Agent", client.UserAgent.Join()) + + if options.MoreHeaders != nil { + for k, v := range options.MoreHeaders { + if v != "" { + req.Header.Set(k, v) + } else { + req.Header.Del(k) + } + } + } + + // get latest token from client + for k, v := range client.AuthenticatedHeaders() { + req.Header.Set(k, v) + } + + // Set connection parameter to close the connection immediately when we've got the response + req.Close = true + + prereqtok := req.Header.Get("X-Auth-Token") + + // Issue the request. + resp, err := client.HTTPClient.Do(req) + if err != nil { + return nil, err + } + + // Allow default OkCodes if none explicitly set + okc := options.OkCodes + if okc == nil { + okc = defaultOkCodes(method) + } + + // Validate the HTTP response status. + var ok bool + for _, code := range okc { + if resp.StatusCode == code { + ok = true + break + } + } + + if !ok { + body, _ := ioutil.ReadAll(resp.Body) + resp.Body.Close() + respErr := ErrUnexpectedResponseCode{ + URL: url, + Method: method, + Expected: options.OkCodes, + Actual: resp.StatusCode, + Body: body, + } + + errType := options.ErrorContext + switch resp.StatusCode { + case http.StatusBadRequest: + err = ErrDefault400{respErr} + if error400er, ok := errType.(Err400er); ok { + err = error400er.Error400(respErr) + } + case http.StatusUnauthorized: + if client.ReauthFunc != nil { + err = client.Reauthenticate(prereqtok) + if err != nil { + e := &ErrUnableToReauthenticate{} + e.ErrOriginal = respErr + return nil, e + } + if options.RawBody != nil { + if seeker, ok := options.RawBody.(io.Seeker); ok { + seeker.Seek(0, 0) + } + } + resp, err = client.Request(method, url, options) + if err != nil { + switch err.(type) { + case *ErrUnexpectedResponseCode: + e := &ErrErrorAfterReauthentication{} + e.ErrOriginal = err.(*ErrUnexpectedResponseCode) + return nil, e + default: + e := &ErrErrorAfterReauthentication{} + e.ErrOriginal = err + return nil, e + } + } + return resp, nil + } + err = ErrDefault401{respErr} + if error401er, ok := errType.(Err401er); ok { + err = error401er.Error401(respErr) + } + case http.StatusForbidden: + err = ErrDefault403{respErr} + if error403er, ok := errType.(Err403er); ok { + err = error403er.Error403(respErr) + } + case http.StatusNotFound: + err = ErrDefault404{respErr} + if error404er, ok := errType.(Err404er); ok { + err = error404er.Error404(respErr) + } + case http.StatusMethodNotAllowed: + err = ErrDefault405{respErr} + if error405er, ok := errType.(Err405er); ok { + err = error405er.Error405(respErr) + } + case http.StatusRequestTimeout: + err = ErrDefault408{respErr} + if error408er, ok := errType.(Err408er); ok { + err = error408er.Error408(respErr) + } + case http.StatusConflict: + err = ErrDefault409{respErr} + if error409er, ok := errType.(Err409er); ok { + err = error409er.Error409(respErr) + } + case 429: + err = ErrDefault429{respErr} + if error429er, ok := errType.(Err429er); ok { + err = error429er.Error429(respErr) + } + case http.StatusInternalServerError: + err = ErrDefault500{respErr} + if error500er, ok := errType.(Err500er); ok { + err = error500er.Error500(respErr) + } + case http.StatusServiceUnavailable: + err = ErrDefault503{respErr} + if error503er, ok := errType.(Err503er); ok { + err = error503er.Error503(respErr) + } + } + + if err == nil { + err = respErr + } + + return resp, err + } + + // Parse the response body as JSON, if requested to do so. + if options.JSONResponse != nil { + defer resp.Body.Close() + if err := json.NewDecoder(resp.Body).Decode(options.JSONResponse); err != nil { + return nil, err + } + } + + return resp, nil +} + +func defaultOkCodes(method string) []int { + switch { + case method == "GET": + return []int{200} + case method == "POST": + return []int{201, 202} + case method == "PUT": + return []int{201, 202} + case method == "PATCH": + return []int{200, 202, 204} + case method == "DELETE": + return []int{202, 204} + } + + return []int{} +} diff --git a/vendor/github.com/gophercloud/gophercloud/results.go b/vendor/github.com/gophercloud/gophercloud/results.go new file mode 100644 index 000000000..94a16bff0 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/results.go @@ -0,0 +1,448 @@ +package gophercloud + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "reflect" + "strconv" + "time" +) + +/* +Result is an internal type to be used by individual resource packages, but its +methods will be available on a wide variety of user-facing embedding types. + +It acts as a base struct that other Result types, returned from request +functions, can embed for convenience. All Results capture basic information +from the HTTP transaction that was performed, including the response body, +HTTP headers, and any errors that happened. + +Generally, each Result type will have an Extract method that can be used to +further interpret the result's payload in a specific context. Extensions or +providers can then provide additional extraction functions to pull out +provider- or extension-specific information as well. +*/ +type Result struct { + // Body is the payload of the HTTP response from the server. In most cases, + // this will be the deserialized JSON structure. + Body interface{} + + // Header contains the HTTP header structure from the original response. + Header http.Header + + // Err is an error that occurred during the operation. It's deferred until + // extraction to make it easier to chain the Extract call. + Err error +} + +// ExtractInto allows users to provide an object into which `Extract` will extract +// the `Result.Body`. This would be useful for OpenStack providers that have +// different fields in the response object than OpenStack proper. +func (r Result) ExtractInto(to interface{}) error { + if r.Err != nil { + return r.Err + } + + if reader, ok := r.Body.(io.Reader); ok { + if readCloser, ok := reader.(io.Closer); ok { + defer readCloser.Close() + } + return json.NewDecoder(reader).Decode(to) + } + + b, err := json.Marshal(r.Body) + if err != nil { + return err + } + err = json.Unmarshal(b, to) + + return err +} + +func (r Result) extractIntoPtr(to interface{}, label string) error { + if label == "" { + return r.ExtractInto(&to) + } + + var m map[string]interface{} + err := r.ExtractInto(&m) + if err != nil { + return err + } + + b, err := json.Marshal(m[label]) + if err != nil { + return err + } + + toValue := reflect.ValueOf(to) + if toValue.Kind() == reflect.Ptr { + toValue = toValue.Elem() + } + + switch toValue.Kind() { + case reflect.Slice: + typeOfV := toValue.Type().Elem() + if typeOfV.Kind() == reflect.Struct { + if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { + newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0) + + if mSlice, ok := m[label].([]interface{}); ok { + for _, v := range mSlice { + // For each iteration of the slice, we create a new struct. + // This is to work around a bug where elements of a slice + // are reused and not overwritten when the same copy of the + // struct is used: + // + // https://github.com/golang/go/issues/21092 + // https://github.com/golang/go/issues/24155 + // https://play.golang.org/p/NHo3ywlPZli + newType := reflect.New(typeOfV).Elem() + + b, err := json.Marshal(v) + if err != nil { + return err + } + + // This is needed for structs with an UnmarshalJSON method. + // Technically this is just unmarshalling the response into + // a struct that is never used, but it's good enough to + // trigger the UnmarshalJSON method. + for i := 0; i < newType.NumField(); i++ { + s := newType.Field(i).Addr().Interface() + + // Unmarshal is used rather than NewDecoder to also work + // around the above-mentioned bug. + err = json.Unmarshal(b, s) + if err != nil { + return err + } + } + + newSlice = reflect.Append(newSlice, newType) + } + } + + // "to" should now be properly modeled to receive the + // JSON response body and unmarshal into all the correct + // fields of the struct or composed extension struct + // at the end of this method. + toValue.Set(newSlice) + } + } + case reflect.Struct: + typeOfV := toValue.Type() + if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous { + for i := 0; i < toValue.NumField(); i++ { + toField := toValue.Field(i) + if toField.Kind() == reflect.Struct { + s := toField.Addr().Interface() + err = json.NewDecoder(bytes.NewReader(b)).Decode(s) + if err != nil { + return err + } + } + } + } + } + + err = json.Unmarshal(b, &to) + return err +} + +// ExtractIntoStructPtr will unmarshal the Result (r) into the provided +// interface{} (to). +// +// NOTE: For internal use only +// +// `to` must be a pointer to an underlying struct type +// +// If provided, `label` will be filtered out of the response +// body prior to `r` being unmarshalled into `to`. +func (r Result) ExtractIntoStructPtr(to interface{}, label string) error { + if r.Err != nil { + return r.Err + } + + t := reflect.TypeOf(to) + if k := t.Kind(); k != reflect.Ptr { + return fmt.Errorf("Expected pointer, got %v", k) + } + switch t.Elem().Kind() { + case reflect.Struct: + return r.extractIntoPtr(to, label) + default: + return fmt.Errorf("Expected pointer to struct, got: %v", t) + } +} + +// ExtractIntoSlicePtr will unmarshal the Result (r) into the provided +// interface{} (to). +// +// NOTE: For internal use only +// +// `to` must be a pointer to an underlying slice type +// +// If provided, `label` will be filtered out of the response +// body prior to `r` being unmarshalled into `to`. +func (r Result) ExtractIntoSlicePtr(to interface{}, label string) error { + if r.Err != nil { + return r.Err + } + + t := reflect.TypeOf(to) + if k := t.Kind(); k != reflect.Ptr { + return fmt.Errorf("Expected pointer, got %v", k) + } + switch t.Elem().Kind() { + case reflect.Slice: + return r.extractIntoPtr(to, label) + default: + return fmt.Errorf("Expected pointer to slice, got: %v", t) + } +} + +// PrettyPrintJSON creates a string containing the full response body as +// pretty-printed JSON. It's useful for capturing test fixtures and for +// debugging extraction bugs. If you include its output in an issue related to +// a buggy extraction function, we will all love you forever. +func (r Result) PrettyPrintJSON() string { + pretty, err := json.MarshalIndent(r.Body, "", " ") + if err != nil { + panic(err.Error()) + } + return string(pretty) +} + +// ErrResult is an internal type to be used by individual resource packages, but +// its methods will be available on a wide variety of user-facing embedding +// types. +// +// It represents results that only contain a potential error and +// nothing else. Usually, if the operation executed successfully, the Err field +// will be nil; otherwise it will be stocked with a relevant error. Use the +// ExtractErr method +// to cleanly pull it out. +type ErrResult struct { + Result +} + +// ExtractErr is a function that extracts error information, or nil, from a result. +func (r ErrResult) ExtractErr() error { + return r.Err +} + +/* +HeaderResult is an internal type to be used by individual resource packages, but +its methods will be available on a wide variety of user-facing embedding types. + +It represents a result that only contains an error (possibly nil) and an +http.Header. This is used, for example, by the objectstorage packages in +openstack, because most of the operations don't return response bodies, but do +have relevant information in headers. +*/ +type HeaderResult struct { + Result +} + +// ExtractInto allows users to provide an object into which `Extract` will +// extract the http.Header headers of the result. +func (r HeaderResult) ExtractInto(to interface{}) error { + if r.Err != nil { + return r.Err + } + + tmpHeaderMap := map[string]string{} + for k, v := range r.Header { + if len(v) > 0 { + tmpHeaderMap[k] = v[0] + } + } + + b, err := json.Marshal(tmpHeaderMap) + if err != nil { + return err + } + err = json.Unmarshal(b, to) + + return err +} + +// RFC3339Milli describes a common time format used by some API responses. +const RFC3339Milli = "2006-01-02T15:04:05.999999Z" + +type JSONRFC3339Milli time.Time + +func (jt *JSONRFC3339Milli) UnmarshalJSON(data []byte) error { + b := bytes.NewBuffer(data) + dec := json.NewDecoder(b) + var s string + if err := dec.Decode(&s); err != nil { + return err + } + t, err := time.Parse(RFC3339Milli, s) + if err != nil { + return err + } + *jt = JSONRFC3339Milli(t) + return nil +} + +const RFC3339MilliNoZ = "2006-01-02T15:04:05.999999" + +type JSONRFC3339MilliNoZ time.Time + +func (jt *JSONRFC3339MilliNoZ) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + if s == "" { + return nil + } + t, err := time.Parse(RFC3339MilliNoZ, s) + if err != nil { + return err + } + *jt = JSONRFC3339MilliNoZ(t) + return nil +} + +type JSONRFC1123 time.Time + +func (jt *JSONRFC1123) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + if s == "" { + return nil + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + return err + } + *jt = JSONRFC1123(t) + return nil +} + +type JSONUnix time.Time + +func (jt *JSONUnix) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + if s == "" { + return nil + } + unix, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return err + } + t = time.Unix(unix, 0) + *jt = JSONUnix(t) + return nil +} + +// RFC3339NoZ is the time format used in Heat (Orchestration). +const RFC3339NoZ = "2006-01-02T15:04:05" + +type JSONRFC3339NoZ time.Time + +func (jt *JSONRFC3339NoZ) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + if s == "" { + return nil + } + t, err := time.Parse(RFC3339NoZ, s) + if err != nil { + return err + } + *jt = JSONRFC3339NoZ(t) + return nil +} + +// RFC3339ZNoT is the time format used in Zun (Containers Service). +const RFC3339ZNoT = "2006-01-02 15:04:05-07:00" + +type JSONRFC3339ZNoT time.Time + +func (jt *JSONRFC3339ZNoT) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + if s == "" { + return nil + } + t, err := time.Parse(RFC3339ZNoT, s) + if err != nil { + return err + } + *jt = JSONRFC3339ZNoT(t) + return nil +} + +// RFC3339ZNoTNoZ is another time format used in Zun (Containers Service). +const RFC3339ZNoTNoZ = "2006-01-02 15:04:05" + +type JSONRFC3339ZNoTNoZ time.Time + +func (jt *JSONRFC3339ZNoTNoZ) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + if s == "" { + return nil + } + t, err := time.Parse(RFC3339ZNoTNoZ, s) + if err != nil { + return err + } + *jt = JSONRFC3339ZNoTNoZ(t) + return nil +} + +/* +Link is an internal type to be used in packages of collection resources that are +paginated in a certain way. + +It's a response substructure common to many paginated collection results that is +used to point to related pages. Usually, the one we care about is the one with +Rel field set to "next". +*/ +type Link struct { + Href string `json:"href"` + Rel string `json:"rel"` +} + +/* +ExtractNextURL is an internal function useful for packages of collection +resources that are paginated in a certain way. + +It attempts to extract the "next" URL from slice of Link structs, or +"" if no such URL is present. +*/ +func ExtractNextURL(links []Link) (string, error) { + var url string + + for _, l := range links { + if l.Rel == "next" { + url = l.Href + } + } + + if url == "" { + return "", nil + } + + return url, nil +} diff --git a/vendor/github.com/gophercloud/gophercloud/service_client.go b/vendor/github.com/gophercloud/gophercloud/service_client.go new file mode 100644 index 000000000..f222f05a6 --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/service_client.go @@ -0,0 +1,154 @@ +package gophercloud + +import ( + "io" + "net/http" + "strings" +) + +// ServiceClient stores details required to interact with a specific service API implemented by a provider. +// Generally, you'll acquire these by calling the appropriate `New` method on a ProviderClient. +type ServiceClient struct { + // ProviderClient is a reference to the provider that implements this service. + *ProviderClient + + // Endpoint is the base URL of the service's API, acquired from a service catalog. + // It MUST end with a /. + Endpoint string + + // ResourceBase is the base URL shared by the resources within a service's API. It should include + // the API version and, like Endpoint, MUST end with a / if set. If not set, the Endpoint is used + // as-is, instead. + ResourceBase string + + // This is the service client type (e.g. compute, sharev2). + // NOTE: FOR INTERNAL USE ONLY. DO NOT SET. GOPHERCLOUD WILL SET THIS. + // It is only exported because it gets set in a different package. + Type string + + // The microversion of the service to use. Set this to use a particular microversion. + Microversion string + + // MoreHeaders allows users (or Gophercloud) to set service-wide headers on requests. Put another way, + // values set in this field will be set on all the HTTP requests the service client sends. + MoreHeaders map[string]string +} + +// ResourceBaseURL returns the base URL of any resources used by this service. It MUST end with a /. +func (client *ServiceClient) ResourceBaseURL() string { + if client.ResourceBase != "" { + return client.ResourceBase + } + return client.Endpoint +} + +// ServiceURL constructs a URL for a resource belonging to this provider. +func (client *ServiceClient) ServiceURL(parts ...string) string { + return client.ResourceBaseURL() + strings.Join(parts, "/") +} + +func (client *ServiceClient) initReqOpts(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) { + if v, ok := (JSONBody).(io.Reader); ok { + opts.RawBody = v + } else if JSONBody != nil { + opts.JSONBody = JSONBody + } + + if JSONResponse != nil { + opts.JSONResponse = JSONResponse + } + + if opts.MoreHeaders == nil { + opts.MoreHeaders = make(map[string]string) + } + + if client.Microversion != "" { + client.setMicroversionHeader(opts) + } +} + +// Get calls `Request` with the "GET" HTTP verb. +func (client *ServiceClient) Get(url string, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = new(RequestOpts) + } + client.initReqOpts(url, nil, JSONResponse, opts) + return client.Request("GET", url, opts) +} + +// Post calls `Request` with the "POST" HTTP verb. +func (client *ServiceClient) Post(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = new(RequestOpts) + } + client.initReqOpts(url, JSONBody, JSONResponse, opts) + return client.Request("POST", url, opts) +} + +// Put calls `Request` with the "PUT" HTTP verb. +func (client *ServiceClient) Put(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = new(RequestOpts) + } + client.initReqOpts(url, JSONBody, JSONResponse, opts) + return client.Request("PUT", url, opts) +} + +// Patch calls `Request` with the "PATCH" HTTP verb. +func (client *ServiceClient) Patch(url string, JSONBody interface{}, JSONResponse interface{}, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = new(RequestOpts) + } + client.initReqOpts(url, JSONBody, JSONResponse, opts) + return client.Request("PATCH", url, opts) +} + +// Delete calls `Request` with the "DELETE" HTTP verb. +func (client *ServiceClient) Delete(url string, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = new(RequestOpts) + } + client.initReqOpts(url, nil, nil, opts) + return client.Request("DELETE", url, opts) +} + +// Head calls `Request` with the "HEAD" HTTP verb. +func (client *ServiceClient) Head(url string, opts *RequestOpts) (*http.Response, error) { + if opts == nil { + opts = new(RequestOpts) + } + client.initReqOpts(url, nil, nil, opts) + return client.Request("HEAD", url, opts) +} + +func (client *ServiceClient) setMicroversionHeader(opts *RequestOpts) { + switch client.Type { + case "compute": + opts.MoreHeaders["X-OpenStack-Nova-API-Version"] = client.Microversion + case "sharev2": + opts.MoreHeaders["X-OpenStack-Manila-API-Version"] = client.Microversion + case "volume": + opts.MoreHeaders["X-OpenStack-Volume-API-Version"] = client.Microversion + case "baremetal": + opts.MoreHeaders["X-OpenStack-Ironic-API-Version"] = client.Microversion + case "baremetal-introspection": + opts.MoreHeaders["X-OpenStack-Ironic-Inspector-API-Version"] = client.Microversion + } + + if client.Type != "" { + opts.MoreHeaders["OpenStack-API-Version"] = client.Type + " " + client.Microversion + } +} + +// Request carries out the HTTP operation for the service client +func (client *ServiceClient) Request(method, url string, options *RequestOpts) (*http.Response, error) { + if len(client.MoreHeaders) > 0 { + if options == nil { + options = new(RequestOpts) + } + for k, v := range client.MoreHeaders { + options.MoreHeaders[k] = v + } + } + return client.ProviderClient.Request(method, url, options) +} diff --git a/vendor/github.com/gophercloud/gophercloud/util.go b/vendor/github.com/gophercloud/gophercloud/util.go new file mode 100644 index 000000000..68f9a5d3e --- /dev/null +++ b/vendor/github.com/gophercloud/gophercloud/util.go @@ -0,0 +1,102 @@ +package gophercloud + +import ( + "fmt" + "net/url" + "path/filepath" + "strings" + "time" +) + +// WaitFor polls a predicate function, once per second, up to a timeout limit. +// This is useful to wait for a resource to transition to a certain state. +// To handle situations when the predicate might hang indefinitely, the +// predicate will be prematurely cancelled after the timeout. +// Resource packages will wrap this in a more convenient function that's +// specific to a certain resource, but it can also be useful on its own. +func WaitFor(timeout int, predicate func() (bool, error)) error { + type WaitForResult struct { + Success bool + Error error + } + + start := time.Now().Unix() + + for { + // If a timeout is set, and that's been exceeded, shut it down. + if timeout >= 0 && time.Now().Unix()-start >= int64(timeout) { + return fmt.Errorf("A timeout occurred") + } + + time.Sleep(1 * time.Second) + + var result WaitForResult + ch := make(chan bool, 1) + go func() { + defer close(ch) + satisfied, err := predicate() + result.Success = satisfied + result.Error = err + }() + + select { + case <-ch: + if result.Error != nil { + return result.Error + } + if result.Success { + return nil + } + // If the predicate has not finished by the timeout, cancel it. + case <-time.After(time.Duration(timeout) * time.Second): + return fmt.Errorf("A timeout occurred") + } + } +} + +// NormalizeURL is an internal function to be used by provider clients. +// +// It ensures that each endpoint URL has a closing `/`, as expected by +// ServiceClient's methods. +func NormalizeURL(url string) string { + if !strings.HasSuffix(url, "/") { + return url + "/" + } + return url +} + +// NormalizePathURL is used to convert rawPath to a fqdn, using basePath as +// a reference in the filesystem, if necessary. basePath is assumed to contain +// either '.' when first used, or the file:// type fqdn of the parent resource. +// e.g. myFavScript.yaml => file://opt/lib/myFavScript.yaml +func NormalizePathURL(basePath, rawPath string) (string, error) { + u, err := url.Parse(rawPath) + if err != nil { + return "", err + } + // if a scheme is defined, it must be a fqdn already + if u.Scheme != "" { + return u.String(), nil + } + // if basePath is a url, then child resources are assumed to be relative to it + bu, err := url.Parse(basePath) + if err != nil { + return "", err + } + var basePathSys, absPathSys string + if bu.Scheme != "" { + basePathSys = filepath.FromSlash(bu.Path) + absPathSys = filepath.Join(basePathSys, rawPath) + bu.Path = filepath.ToSlash(absPathSys) + return bu.String(), nil + } + + absPathSys = filepath.Join(basePath, rawPath) + u.Path = filepath.ToSlash(absPathSys) + if err != nil { + return "", err + } + u.Scheme = "file" + return u.String(), nil + +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt b/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt new file mode 100644 index 000000000..364516251 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2015, Gengo, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Gengo, Inc. nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel new file mode 100644 index 000000000..76cafe6ec --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/BUILD.bazel @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") + +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "internal_proto", + srcs = ["stream_chunk.proto"], + deps = ["@com_google_protobuf//:any_proto"], +) + +go_proto_library( + name = "internal_go_proto", + importpath = "github.com/grpc-ecosystem/grpc-gateway/internal", + proto = ":internal_proto", +) + +go_library( + name = "go_default_library", + embed = [":internal_go_proto"], + importpath = "github.com/grpc-ecosystem/grpc-gateway/internal", +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go new file mode 100644 index 000000000..8858f0690 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.pb.go @@ -0,0 +1,118 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: internal/stream_chunk.proto + +package internal + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import any "github.com/golang/protobuf/ptypes/any" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// StreamError is a response type which is returned when +// streaming rpc returns an error. +type StreamError struct { + GrpcCode int32 `protobuf:"varint,1,opt,name=grpc_code,json=grpcCode,proto3" json:"grpc_code,omitempty"` + HttpCode int32 `protobuf:"varint,2,opt,name=http_code,json=httpCode,proto3" json:"http_code,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + HttpStatus string `protobuf:"bytes,4,opt,name=http_status,json=httpStatus,proto3" json:"http_status,omitempty"` + Details []*any.Any `protobuf:"bytes,5,rep,name=details,proto3" json:"details,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StreamError) Reset() { *m = StreamError{} } +func (m *StreamError) String() string { return proto.CompactTextString(m) } +func (*StreamError) ProtoMessage() {} +func (*StreamError) Descriptor() ([]byte, []int) { + return fileDescriptor_stream_chunk_a2afb657504565d7, []int{0} +} +func (m *StreamError) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StreamError.Unmarshal(m, b) +} +func (m *StreamError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StreamError.Marshal(b, m, deterministic) +} +func (dst *StreamError) XXX_Merge(src proto.Message) { + xxx_messageInfo_StreamError.Merge(dst, src) +} +func (m *StreamError) XXX_Size() int { + return xxx_messageInfo_StreamError.Size(m) +} +func (m *StreamError) XXX_DiscardUnknown() { + xxx_messageInfo_StreamError.DiscardUnknown(m) +} + +var xxx_messageInfo_StreamError proto.InternalMessageInfo + +func (m *StreamError) GetGrpcCode() int32 { + if m != nil { + return m.GrpcCode + } + return 0 +} + +func (m *StreamError) GetHttpCode() int32 { + if m != nil { + return m.HttpCode + } + return 0 +} + +func (m *StreamError) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func (m *StreamError) GetHttpStatus() string { + if m != nil { + return m.HttpStatus + } + return "" +} + +func (m *StreamError) GetDetails() []*any.Any { + if m != nil { + return m.Details + } + return nil +} + +func init() { + proto.RegisterType((*StreamError)(nil), "grpc.gateway.runtime.StreamError") +} + +func init() { + proto.RegisterFile("internal/stream_chunk.proto", fileDescriptor_stream_chunk_a2afb657504565d7) +} + +var fileDescriptor_stream_chunk_a2afb657504565d7 = []byte{ + // 223 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0x90, 0x41, 0x4e, 0xc3, 0x30, + 0x10, 0x45, 0x15, 0x4a, 0x69, 0x3b, 0xd9, 0x45, 0x5d, 0x18, 0xba, 0x20, 0x62, 0x95, 0x95, 0x23, + 0xc1, 0x09, 0x00, 0x71, 0x81, 0x74, 0xc7, 0xa6, 0x9a, 0x26, 0x83, 0x13, 0x91, 0xd8, 0xd1, 0x78, + 0x22, 0x94, 0x6b, 0x71, 0xc2, 0xca, 0x8e, 0xb2, 0xf4, 0x7b, 0x7f, 0xbe, 0xbe, 0x0c, 0xa7, 0xce, + 0x0a, 0xb1, 0xc5, 0xbe, 0xf4, 0xc2, 0x84, 0xc3, 0xa5, 0x6e, 0x27, 0xfb, 0xab, 0x47, 0x76, 0xe2, + 0xb2, 0xa3, 0xe1, 0xb1, 0xd6, 0x06, 0x85, 0xfe, 0x70, 0xd6, 0x3c, 0x59, 0xe9, 0x06, 0x7a, 0x7a, + 0x34, 0xce, 0x99, 0x9e, 0xca, 0x98, 0xb9, 0x4e, 0x3f, 0x25, 0xda, 0x79, 0x39, 0x78, 0xf9, 0x4f, + 0x20, 0x3d, 0xc7, 0x9e, 0x2f, 0x66, 0xc7, 0xd9, 0x09, 0x0e, 0xa1, 0xe2, 0x52, 0xbb, 0x86, 0x54, + 0x92, 0x27, 0xc5, 0xb6, 0xda, 0x07, 0xf0, 0xe9, 0x1a, 0x0a, 0xb2, 0x15, 0x19, 0x17, 0x79, 0xb7, + 0xc8, 0x00, 0xa2, 0x54, 0xb0, 0x1b, 0xc8, 0x7b, 0x34, 0xa4, 0x36, 0x79, 0x52, 0x1c, 0xaa, 0xf5, + 0x99, 0x3d, 0x43, 0x1a, 0xcf, 0xbc, 0xa0, 0x4c, 0x5e, 0xdd, 0x47, 0x0b, 0x01, 0x9d, 0x23, 0xc9, + 0x34, 0xec, 0x1a, 0x12, 0xec, 0x7a, 0xaf, 0xb6, 0xf9, 0xa6, 0x48, 0x5f, 0x8f, 0x7a, 0x59, 0xac, + 0xd7, 0xc5, 0xfa, 0xdd, 0xce, 0xd5, 0x1a, 0xfa, 0x80, 0xef, 0xfd, 0xfa, 0x09, 0xd7, 0x87, 0x18, + 0x79, 0xbb, 0x05, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x7d, 0xa5, 0x18, 0x17, 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.proto b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.proto new file mode 100644 index 000000000..55f42ce63 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/internal/stream_chunk.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package grpc.gateway.runtime; +option go_package = "internal"; + +import "google/protobuf/any.proto"; + +// StreamError is a response type which is returned when +// streaming rpc returns an error. +message StreamError { + int32 grpc_code = 1; + int32 http_code = 2; + string message = 3; + string http_status = 4; + repeated google.protobuf.Any details = 5; +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel new file mode 100644 index 000000000..c99f83e58 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/BUILD.bazel @@ -0,0 +1,80 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package(default_visibility = ["//visibility:public"]) + +go_library( + name = "go_default_library", + srcs = [ + "context.go", + "convert.go", + "doc.go", + "errors.go", + "fieldmask.go", + "handler.go", + "marshal_json.go", + "marshal_jsonpb.go", + "marshal_proto.go", + "marshaler.go", + "marshaler_registry.go", + "mux.go", + "pattern.go", + "proto2_convert.go", + "proto_errors.go", + "query.go", + ], + importpath = "github.com/grpc-ecosystem/grpc-gateway/runtime", + deps = [ + "//internal:go_default_library", + "//utilities:go_default_library", + "@com_github_golang_protobuf//jsonpb:go_default_library_gen", + "@com_github_golang_protobuf//proto:go_default_library", + "@com_github_golang_protobuf//protoc-gen-go/generator:go_default_library_gen", + "@io_bazel_rules_go//proto/wkt:any_go_proto", + "@io_bazel_rules_go//proto/wkt:duration_go_proto", + "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", + "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", + "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", + "@org_golang_google_grpc//codes:go_default_library", + "@org_golang_google_grpc//grpclog:go_default_library", + "@org_golang_google_grpc//metadata:go_default_library", + "@org_golang_google_grpc//status:go_default_library", + ], +) + +go_test( + name = "go_default_test", + size = "small", + srcs = [ + "context_test.go", + "errors_test.go", + "fieldmask_test.go", + "handler_test.go", + "marshal_json_test.go", + "marshal_jsonpb_test.go", + "marshal_proto_test.go", + "marshaler_registry_test.go", + "mux_test.go", + "pattern_test.go", + "query_test.go", + ], + embed = [":go_default_library"], + deps = [ + "//examples/proto/examplepb:go_default_library", + "//internal:go_default_library", + "//utilities:go_default_library", + "@com_github_golang_protobuf//jsonpb:go_default_library_gen", + "@com_github_golang_protobuf//proto:go_default_library", + "@com_github_golang_protobuf//ptypes:go_default_library_gen", + "@go_googleapis//google/rpc:errdetails_go_proto", + "@io_bazel_rules_go//proto/wkt:duration_go_proto", + "@io_bazel_rules_go//proto/wkt:empty_go_proto", + "@io_bazel_rules_go//proto/wkt:field_mask_go_proto", + "@io_bazel_rules_go//proto/wkt:struct_go_proto", + "@io_bazel_rules_go//proto/wkt:timestamp_go_proto", + "@io_bazel_rules_go//proto/wkt:wrappers_go_proto", + "@org_golang_google_grpc//:go_default_library", + "@org_golang_google_grpc//codes:go_default_library", + "@org_golang_google_grpc//metadata:go_default_library", + "@org_golang_google_grpc//status:go_default_library", + ], +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go new file mode 100644 index 000000000..896057e1e --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/context.go @@ -0,0 +1,210 @@ +package runtime + +import ( + "context" + "encoding/base64" + "fmt" + "net" + "net/http" + "net/textproto" + "strconv" + "strings" + "time" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// MetadataHeaderPrefix is the http prefix that represents custom metadata +// parameters to or from a gRPC call. +const MetadataHeaderPrefix = "Grpc-Metadata-" + +// MetadataPrefix is prepended to permanent HTTP header keys (as specified +// by the IANA) when added to the gRPC context. +const MetadataPrefix = "grpcgateway-" + +// MetadataTrailerPrefix is prepended to gRPC metadata as it is converted to +// HTTP headers in a response handled by grpc-gateway +const MetadataTrailerPrefix = "Grpc-Trailer-" + +const metadataGrpcTimeout = "Grpc-Timeout" +const metadataHeaderBinarySuffix = "-Bin" + +const xForwardedFor = "X-Forwarded-For" +const xForwardedHost = "X-Forwarded-Host" + +var ( + // DefaultContextTimeout is used for gRPC call context.WithTimeout whenever a Grpc-Timeout inbound + // header isn't present. If the value is 0 the sent `context` will not have a timeout. + DefaultContextTimeout = 0 * time.Second +) + +func decodeBinHeader(v string) ([]byte, error) { + if len(v)%4 == 0 { + // Input was padded, or padding was not necessary. + return base64.StdEncoding.DecodeString(v) + } + return base64.RawStdEncoding.DecodeString(v) +} + +/* +AnnotateContext adds context information such as metadata from the request. + +At a minimum, the RemoteAddr is included in the fashion of "X-Forwarded-For", +except that the forwarded destination is not another HTTP service but rather +a gRPC service. +*/ +func AnnotateContext(ctx context.Context, mux *ServeMux, req *http.Request) (context.Context, error) { + var pairs []string + timeout := DefaultContextTimeout + if tm := req.Header.Get(metadataGrpcTimeout); tm != "" { + var err error + timeout, err = timeoutDecode(tm) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid grpc-timeout: %s", tm) + } + } + + for key, vals := range req.Header { + for _, val := range vals { + key = textproto.CanonicalMIMEHeaderKey(key) + // For backwards-compatibility, pass through 'authorization' header with no prefix. + if key == "Authorization" { + pairs = append(pairs, "authorization", val) + } + if h, ok := mux.incomingHeaderMatcher(key); ok { + // Handles "-bin" metadata in grpc, since grpc will do another base64 + // encode before sending to server, we need to decode it first. + if strings.HasSuffix(key, metadataHeaderBinarySuffix) { + b, err := decodeBinHeader(val) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid binary header %s: %s", key, err) + } + + val = string(b) + } + pairs = append(pairs, h, val) + } + } + } + if host := req.Header.Get(xForwardedHost); host != "" { + pairs = append(pairs, strings.ToLower(xForwardedHost), host) + } else if req.Host != "" { + pairs = append(pairs, strings.ToLower(xForwardedHost), req.Host) + } + + if addr := req.RemoteAddr; addr != "" { + if remoteIP, _, err := net.SplitHostPort(addr); err == nil { + if fwd := req.Header.Get(xForwardedFor); fwd == "" { + pairs = append(pairs, strings.ToLower(xForwardedFor), remoteIP) + } else { + pairs = append(pairs, strings.ToLower(xForwardedFor), fmt.Sprintf("%s, %s", fwd, remoteIP)) + } + } else { + grpclog.Infof("invalid remote addr: %s", addr) + } + } + + if timeout != 0 { + ctx, _ = context.WithTimeout(ctx, timeout) + } + if len(pairs) == 0 { + return ctx, nil + } + md := metadata.Pairs(pairs...) + for _, mda := range mux.metadataAnnotators { + md = metadata.Join(md, mda(ctx, req)) + } + return metadata.NewOutgoingContext(ctx, md), nil +} + +// ServerMetadata consists of metadata sent from gRPC server. +type ServerMetadata struct { + HeaderMD metadata.MD + TrailerMD metadata.MD +} + +type serverMetadataKey struct{} + +// NewServerMetadataContext creates a new context with ServerMetadata +func NewServerMetadataContext(ctx context.Context, md ServerMetadata) context.Context { + return context.WithValue(ctx, serverMetadataKey{}, md) +} + +// ServerMetadataFromContext returns the ServerMetadata in ctx +func ServerMetadataFromContext(ctx context.Context) (md ServerMetadata, ok bool) { + md, ok = ctx.Value(serverMetadataKey{}).(ServerMetadata) + return +} + +func timeoutDecode(s string) (time.Duration, error) { + size := len(s) + if size < 2 { + return 0, fmt.Errorf("timeout string is too short: %q", s) + } + d, ok := timeoutUnitToDuration(s[size-1]) + if !ok { + return 0, fmt.Errorf("timeout unit is not recognized: %q", s) + } + t, err := strconv.ParseInt(s[:size-1], 10, 64) + if err != nil { + return 0, err + } + return d * time.Duration(t), nil +} + +func timeoutUnitToDuration(u uint8) (d time.Duration, ok bool) { + switch u { + case 'H': + return time.Hour, true + case 'M': + return time.Minute, true + case 'S': + return time.Second, true + case 'm': + return time.Millisecond, true + case 'u': + return time.Microsecond, true + case 'n': + return time.Nanosecond, true + default: + } + return +} + +// isPermanentHTTPHeader checks whether hdr belongs to the list of +// permenant request headers maintained by IANA. +// http://www.iana.org/assignments/message-headers/message-headers.xml +func isPermanentHTTPHeader(hdr string) bool { + switch hdr { + case + "Accept", + "Accept-Charset", + "Accept-Language", + "Accept-Ranges", + "Authorization", + "Cache-Control", + "Content-Type", + "Cookie", + "Date", + "Expect", + "From", + "Host", + "If-Match", + "If-Modified-Since", + "If-None-Match", + "If-Schedule-Tag-Match", + "If-Unmodified-Since", + "Max-Forwards", + "Origin", + "Pragma", + "Referer", + "User-Agent", + "Via", + "Warning": + return true + } + return false +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go new file mode 100644 index 000000000..a5b3bd6a7 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/convert.go @@ -0,0 +1,312 @@ +package runtime + +import ( + "encoding/base64" + "fmt" + "strconv" + "strings" + + "github.com/golang/protobuf/jsonpb" + "github.com/golang/protobuf/ptypes/duration" + "github.com/golang/protobuf/ptypes/timestamp" + "github.com/golang/protobuf/ptypes/wrappers" +) + +// String just returns the given string. +// It is just for compatibility to other types. +func String(val string) (string, error) { + return val, nil +} + +// StringSlice converts 'val' where individual strings are separated by +// 'sep' into a string slice. +func StringSlice(val, sep string) ([]string, error) { + return strings.Split(val, sep), nil +} + +// Bool converts the given string representation of a boolean value into bool. +func Bool(val string) (bool, error) { + return strconv.ParseBool(val) +} + +// BoolSlice converts 'val' where individual booleans are separated by +// 'sep' into a bool slice. +func BoolSlice(val, sep string) ([]bool, error) { + s := strings.Split(val, sep) + values := make([]bool, len(s)) + for i, v := range s { + value, err := Bool(v) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +// Float64 converts the given string representation into representation of a floating point number into float64. +func Float64(val string) (float64, error) { + return strconv.ParseFloat(val, 64) +} + +// Float64Slice converts 'val' where individual floating point numbers are separated by +// 'sep' into a float64 slice. +func Float64Slice(val, sep string) ([]float64, error) { + s := strings.Split(val, sep) + values := make([]float64, len(s)) + for i, v := range s { + value, err := Float64(v) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +// Float32 converts the given string representation of a floating point number into float32. +func Float32(val string) (float32, error) { + f, err := strconv.ParseFloat(val, 32) + if err != nil { + return 0, err + } + return float32(f), nil +} + +// Float32Slice converts 'val' where individual floating point numbers are separated by +// 'sep' into a float32 slice. +func Float32Slice(val, sep string) ([]float32, error) { + s := strings.Split(val, sep) + values := make([]float32, len(s)) + for i, v := range s { + value, err := Float32(v) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +// Int64 converts the given string representation of an integer into int64. +func Int64(val string) (int64, error) { + return strconv.ParseInt(val, 0, 64) +} + +// Int64Slice converts 'val' where individual integers are separated by +// 'sep' into a int64 slice. +func Int64Slice(val, sep string) ([]int64, error) { + s := strings.Split(val, sep) + values := make([]int64, len(s)) + for i, v := range s { + value, err := Int64(v) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +// Int32 converts the given string representation of an integer into int32. +func Int32(val string) (int32, error) { + i, err := strconv.ParseInt(val, 0, 32) + if err != nil { + return 0, err + } + return int32(i), nil +} + +// Int32Slice converts 'val' where individual integers are separated by +// 'sep' into a int32 slice. +func Int32Slice(val, sep string) ([]int32, error) { + s := strings.Split(val, sep) + values := make([]int32, len(s)) + for i, v := range s { + value, err := Int32(v) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +// Uint64 converts the given string representation of an integer into uint64. +func Uint64(val string) (uint64, error) { + return strconv.ParseUint(val, 0, 64) +} + +// Uint64Slice converts 'val' where individual integers are separated by +// 'sep' into a uint64 slice. +func Uint64Slice(val, sep string) ([]uint64, error) { + s := strings.Split(val, sep) + values := make([]uint64, len(s)) + for i, v := range s { + value, err := Uint64(v) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +// Uint32 converts the given string representation of an integer into uint32. +func Uint32(val string) (uint32, error) { + i, err := strconv.ParseUint(val, 0, 32) + if err != nil { + return 0, err + } + return uint32(i), nil +} + +// Uint32Slice converts 'val' where individual integers are separated by +// 'sep' into a uint32 slice. +func Uint32Slice(val, sep string) ([]uint32, error) { + s := strings.Split(val, sep) + values := make([]uint32, len(s)) + for i, v := range s { + value, err := Uint32(v) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +// Bytes converts the given string representation of a byte sequence into a slice of bytes +// A bytes sequence is encoded in URL-safe base64 without padding +func Bytes(val string) ([]byte, error) { + b, err := base64.StdEncoding.DecodeString(val) + if err != nil { + b, err = base64.URLEncoding.DecodeString(val) + if err != nil { + return nil, err + } + } + return b, nil +} + +// BytesSlice converts 'val' where individual bytes sequences, encoded in URL-safe +// base64 without padding, are separated by 'sep' into a slice of bytes slices slice. +func BytesSlice(val, sep string) ([][]byte, error) { + s := strings.Split(val, sep) + values := make([][]byte, len(s)) + for i, v := range s { + value, err := Bytes(v) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +// Timestamp converts the given RFC3339 formatted string into a timestamp.Timestamp. +func Timestamp(val string) (*timestamp.Timestamp, error) { + var r *timestamp.Timestamp + err := jsonpb.UnmarshalString(val, r) + return r, err +} + +// Duration converts the given string into a timestamp.Duration. +func Duration(val string) (*duration.Duration, error) { + var r *duration.Duration + err := jsonpb.UnmarshalString(val, r) + return r, err +} + +// Enum converts the given string into an int32 that should be type casted into the +// correct enum proto type. +func Enum(val string, enumValMap map[string]int32) (int32, error) { + e, ok := enumValMap[val] + if ok { + return e, nil + } + + i, err := Int32(val) + if err != nil { + return 0, fmt.Errorf("%s is not valid", val) + } + for _, v := range enumValMap { + if v == i { + return i, nil + } + } + return 0, fmt.Errorf("%s is not valid", val) +} + +// EnumSlice converts 'val' where individual enums are separated by 'sep' +// into a int32 slice. Each individual int32 should be type casted into the +// correct enum proto type. +func EnumSlice(val, sep string, enumValMap map[string]int32) ([]int32, error) { + s := strings.Split(val, sep) + values := make([]int32, len(s)) + for i, v := range s { + value, err := Enum(v, enumValMap) + if err != nil { + return values, err + } + values[i] = value + } + return values, nil +} + +/* + Support fot google.protobuf.wrappers on top of primitive types +*/ + +// StringValue well-known type support as wrapper around string type +func StringValue(val string) (*wrappers.StringValue, error) { + return &wrappers.StringValue{Value: val}, nil +} + +// FloatValue well-known type support as wrapper around float32 type +func FloatValue(val string) (*wrappers.FloatValue, error) { + parsedVal, err := Float32(val) + return &wrappers.FloatValue{Value: parsedVal}, err +} + +// DoubleValue well-known type support as wrapper around float64 type +func DoubleValue(val string) (*wrappers.DoubleValue, error) { + parsedVal, err := Float64(val) + return &wrappers.DoubleValue{Value: parsedVal}, err +} + +// BoolValue well-known type support as wrapper around bool type +func BoolValue(val string) (*wrappers.BoolValue, error) { + parsedVal, err := Bool(val) + return &wrappers.BoolValue{Value: parsedVal}, err +} + +// Int32Value well-known type support as wrapper around int32 type +func Int32Value(val string) (*wrappers.Int32Value, error) { + parsedVal, err := Int32(val) + return &wrappers.Int32Value{Value: parsedVal}, err +} + +// UInt32Value well-known type support as wrapper around uint32 type +func UInt32Value(val string) (*wrappers.UInt32Value, error) { + parsedVal, err := Uint32(val) + return &wrappers.UInt32Value{Value: parsedVal}, err +} + +// Int64Value well-known type support as wrapper around int64 type +func Int64Value(val string) (*wrappers.Int64Value, error) { + parsedVal, err := Int64(val) + return &wrappers.Int64Value{Value: parsedVal}, err +} + +// UInt64Value well-known type support as wrapper around uint64 type +func UInt64Value(val string) (*wrappers.UInt64Value, error) { + parsedVal, err := Uint64(val) + return &wrappers.UInt64Value{Value: parsedVal}, err +} + +// BytesValue well-known type support as wrapper around bytes[] type +func BytesValue(val string) (*wrappers.BytesValue, error) { + parsedVal, err := Bytes(val) + return &wrappers.BytesValue{Value: parsedVal}, err +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go new file mode 100644 index 000000000..b6e5ddf7a --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/doc.go @@ -0,0 +1,5 @@ +/* +Package runtime contains runtime helper functions used by +servers which protoc-gen-grpc-gateway generates. +*/ +package runtime diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go new file mode 100644 index 000000000..41d54ef91 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/errors.go @@ -0,0 +1,145 @@ +package runtime + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes/any" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// HTTPStatusFromCode converts a gRPC error code into the corresponding HTTP response status. +// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto +func HTTPStatusFromCode(code codes.Code) int { + switch code { + case codes.OK: + return http.StatusOK + case codes.Canceled: + return http.StatusRequestTimeout + case codes.Unknown: + return http.StatusInternalServerError + case codes.InvalidArgument: + return http.StatusBadRequest + case codes.DeadlineExceeded: + return http.StatusGatewayTimeout + case codes.NotFound: + return http.StatusNotFound + case codes.AlreadyExists: + return http.StatusConflict + case codes.PermissionDenied: + return http.StatusForbidden + case codes.Unauthenticated: + return http.StatusUnauthorized + case codes.ResourceExhausted: + return http.StatusTooManyRequests + case codes.FailedPrecondition: + return http.StatusPreconditionFailed + case codes.Aborted: + return http.StatusConflict + case codes.OutOfRange: + return http.StatusBadRequest + case codes.Unimplemented: + return http.StatusNotImplemented + case codes.Internal: + return http.StatusInternalServerError + case codes.Unavailable: + return http.StatusServiceUnavailable + case codes.DataLoss: + return http.StatusInternalServerError + } + + grpclog.Infof("Unknown gRPC error code: %v", code) + return http.StatusInternalServerError +} + +var ( + // HTTPError replies to the request with the error. + // You can set a custom function to this variable to customize error format. + HTTPError = DefaultHTTPError + // OtherErrorHandler handles the following error used by the gateway: StatusMethodNotAllowed StatusNotFound and StatusBadRequest + OtherErrorHandler = DefaultOtherErrorHandler +) + +type errorBody struct { + Error string `protobuf:"bytes,1,name=error" json:"error"` + // This is to make the error more compatible with users that expect errors to be Status objects: + // https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto + // It should be the exact same message as the Error field. + Message string `protobuf:"bytes,1,name=message" json:"message"` + Code int32 `protobuf:"varint,2,name=code" json:"code"` + Details []*any.Any `protobuf:"bytes,3,rep,name=details" json:"details,omitempty"` +} + +// Make this also conform to proto.Message for builtin JSONPb Marshaler +func (e *errorBody) Reset() { *e = errorBody{} } +func (e *errorBody) String() string { return proto.CompactTextString(e) } +func (*errorBody) ProtoMessage() {} + +// DefaultHTTPError is the default implementation of HTTPError. +// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode. +// If otherwise, it replies with http.StatusInternalServerError. +// +// The response body returned by this function is a JSON object, +// which contains a member whose key is "error" and whose value is err.Error(). +func DefaultHTTPError(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) { + const fallback = `{"error": "failed to marshal error message"}` + + s, ok := status.FromError(err) + if !ok { + s = status.New(codes.Unknown, err.Error()) + } + + w.Header().Del("Trailer") + + contentType := marshaler.ContentType() + // Check marshaler on run time in order to keep backwards compatability + // An interface param needs to be added to the ContentType() function on + // the Marshal interface to be able to remove this check + if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok { + pb := s.Proto() + contentType = httpBodyMarshaler.ContentTypeFromMessage(pb) + } + w.Header().Set("Content-Type", contentType) + + body := &errorBody{ + Error: s.Message(), + Message: s.Message(), + Code: int32(s.Code()), + Details: s.Proto().GetDetails(), + } + + buf, merr := marshaler.Marshal(body) + if merr != nil { + grpclog.Infof("Failed to marshal error message %q: %v", body, merr) + w.WriteHeader(http.StatusInternalServerError) + if _, err := io.WriteString(w, fallback); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, mux, md) + handleForwardResponseTrailerHeader(w, md) + st := HTTPStatusFromCode(s.Code()) + w.WriteHeader(st) + if _, err := w.Write(buf); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + + handleForwardResponseTrailer(w, md) +} + +// DefaultOtherErrorHandler is the default implementation of OtherErrorHandler. +// It simply writes a string representation of the given error into "w". +func DefaultOtherErrorHandler(w http.ResponseWriter, _ *http.Request, msg string, code int) { + http.Error(w, msg, code) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go new file mode 100644 index 000000000..e1cf7a914 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask.go @@ -0,0 +1,70 @@ +package runtime + +import ( + "encoding/json" + "io" + "strings" + + "github.com/golang/protobuf/protoc-gen-go/generator" + "google.golang.org/genproto/protobuf/field_mask" +) + +// FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body. +func FieldMaskFromRequestBody(r io.Reader) (*field_mask.FieldMask, error) { + fm := &field_mask.FieldMask{} + var root interface{} + if err := json.NewDecoder(r).Decode(&root); err != nil { + if err == io.EOF { + return fm, nil + } + return nil, err + } + + queue := []fieldMaskPathItem{{node: root}} + for len(queue) > 0 { + // dequeue an item + item := queue[0] + queue = queue[1:] + + if m, ok := item.node.(map[string]interface{}); ok { + // if the item is an object, then enqueue all of its children + for k, v := range m { + queue = append(queue, fieldMaskPathItem{path: append(item.path, generator.CamelCase(k)), node: v}) + } + } else if len(item.path) > 0 { + // otherwise, it's a leaf node so print its path + fm.Paths = append(fm.Paths, strings.Join(item.path, ".")) + } + } + + return fm, nil +} + +// fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask +type fieldMaskPathItem struct { + // the list of prior fields leading up to node + path []string + + // a generic decoded json object the current item to inspect for further path extraction + node interface{} +} + +// CamelCaseFieldMask updates the given FieldMask by converting all of its paths to CamelCase, using the same heuristic +// that's used for naming protobuf fields in Go. +func CamelCaseFieldMask(mask *field_mask.FieldMask) { + if mask == nil || mask.Paths == nil { + return + } + + var newPaths []string + for _, path := range mask.Paths { + lowerCasedParts := strings.Split(path, ".") + var camelCasedParts []string + for _, part := range lowerCasedParts { + camelCasedParts = append(camelCasedParts, generator.CamelCase(part)) + } + newPaths = append(newPaths, strings.Join(camelCasedParts, ".")) + } + + mask.Paths = newPaths +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go new file mode 100644 index 000000000..1fc63f7f5 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/handler.go @@ -0,0 +1,215 @@ +package runtime + +import ( + "fmt" + "io" + "net/http" + "net/textproto" + + "context" + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes/any" + "github.com/grpc-ecosystem/grpc-gateway/internal" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// ForwardResponseStream forwards the stream from gRPC server to REST client. +func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { + f, ok := w.(http.Flusher) + if !ok { + grpclog.Infof("Flush not supported in %T", w) + http.Error(w, "unexpected type of web server", http.StatusInternalServerError) + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + http.Error(w, "unexpected error", http.StatusInternalServerError) + return + } + handleForwardResponseServerMetadata(w, mux, md) + + w.Header().Set("Transfer-Encoding", "chunked") + w.Header().Set("Content-Type", marshaler.ContentType()) + if err := handleForwardResponseOptions(ctx, w, nil, opts); err != nil { + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + + var delimiter []byte + if d, ok := marshaler.(Delimited); ok { + delimiter = d.Delimiter() + } else { + delimiter = []byte("\n") + } + + var wroteHeader bool + for { + resp, err := recv() + if err == io.EOF { + return + } + if err != nil { + handleForwardResponseStreamError(wroteHeader, marshaler, w, err) + return + } + if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { + handleForwardResponseStreamError(wroteHeader, marshaler, w, err) + return + } + + buf, err := marshaler.Marshal(streamChunk(resp, nil)) + if err != nil { + grpclog.Infof("Failed to marshal response chunk: %v", err) + handleForwardResponseStreamError(wroteHeader, marshaler, w, err) + return + } + if _, err = w.Write(buf); err != nil { + grpclog.Infof("Failed to send response chunk: %v", err) + return + } + wroteHeader = true + if _, err = w.Write(delimiter); err != nil { + grpclog.Infof("Failed to send delimiter chunk: %v", err) + return + } + f.Flush() + } +} + +func handleForwardResponseServerMetadata(w http.ResponseWriter, mux *ServeMux, md ServerMetadata) { + for k, vs := range md.HeaderMD { + if h, ok := mux.outgoingHeaderMatcher(k); ok { + for _, v := range vs { + w.Header().Add(h, v) + } + } + } +} + +func handleForwardResponseTrailerHeader(w http.ResponseWriter, md ServerMetadata) { + for k := range md.TrailerMD { + tKey := textproto.CanonicalMIMEHeaderKey(fmt.Sprintf("%s%s", MetadataTrailerPrefix, k)) + w.Header().Add("Trailer", tKey) + } +} + +func handleForwardResponseTrailer(w http.ResponseWriter, md ServerMetadata) { + for k, vs := range md.TrailerMD { + tKey := fmt.Sprintf("%s%s", MetadataTrailerPrefix, k) + for _, v := range vs { + w.Header().Add(tKey, v) + } + } +} + +// responseBody interface contains method for getting field for marshaling to the response body +// this method is generated for response struct from the value of `response_body` in the `google.api.HttpRule` +type responseBody interface { + XXX_ResponseBody() interface{} +} + +// ForwardResponseMessage forwards the message "resp" from gRPC server to REST client. +func ForwardResponseMessage(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, resp proto.Message, opts ...func(context.Context, http.ResponseWriter, proto.Message) error) { + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, mux, md) + handleForwardResponseTrailerHeader(w, md) + + contentType := marshaler.ContentType() + // Check marshaler on run time in order to keep backwards compatability + // An interface param needs to be added to the ContentType() function on + // the Marshal interface to be able to remove this check + if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok { + contentType = httpBodyMarshaler.ContentTypeFromMessage(resp) + } + w.Header().Set("Content-Type", contentType) + + if err := handleForwardResponseOptions(ctx, w, resp, opts); err != nil { + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + var buf []byte + var err error + if rb, ok := resp.(responseBody); ok { + buf, err = marshaler.Marshal(rb.XXX_ResponseBody()) + } else { + buf, err = marshaler.Marshal(resp) + } + if err != nil { + grpclog.Infof("Marshal error: %v", err) + HTTPError(ctx, mux, marshaler, w, req, err) + return + } + + if _, err = w.Write(buf); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + + handleForwardResponseTrailer(w, md) +} + +func handleForwardResponseOptions(ctx context.Context, w http.ResponseWriter, resp proto.Message, opts []func(context.Context, http.ResponseWriter, proto.Message) error) error { + if len(opts) == 0 { + return nil + } + for _, opt := range opts { + if err := opt(ctx, w, resp); err != nil { + grpclog.Infof("Error handling ForwardResponseOptions: %v", err) + return err + } + } + return nil +} + +func handleForwardResponseStreamError(wroteHeader bool, marshaler Marshaler, w http.ResponseWriter, err error) { + buf, merr := marshaler.Marshal(streamChunk(nil, err)) + if merr != nil { + grpclog.Infof("Failed to marshal an error: %v", merr) + return + } + if !wroteHeader { + s, ok := status.FromError(err) + if !ok { + s = status.New(codes.Unknown, err.Error()) + } + w.WriteHeader(HTTPStatusFromCode(s.Code())) + } + if _, werr := w.Write(buf); werr != nil { + grpclog.Infof("Failed to notify error to client: %v", werr) + return + } +} + +func streamChunk(result proto.Message, err error) map[string]proto.Message { + if err != nil { + grpcCode := codes.Unknown + grpcMessage := err.Error() + var grpcDetails []*any.Any + if s, ok := status.FromError(err); ok { + grpcCode = s.Code() + grpcMessage = s.Message() + grpcDetails = s.Proto().GetDetails() + } + httpCode := HTTPStatusFromCode(grpcCode) + return map[string]proto.Message{ + "error": &internal.StreamError{ + GrpcCode: int32(grpcCode), + HttpCode: int32(httpCode), + Message: grpcMessage, + HttpStatus: http.StatusText(httpCode), + Details: grpcDetails, + }, + } + } + if result == nil { + return streamChunk(nil, fmt.Errorf("empty response")) + } + return map[string]proto.Message{"result": result} +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go new file mode 100644 index 000000000..f55285b5d --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_httpbodyproto.go @@ -0,0 +1,43 @@ +package runtime + +import ( + "google.golang.org/genproto/googleapis/api/httpbody" +) + +// SetHTTPBodyMarshaler overwrite the default marshaler with the HTTPBodyMarshaler +func SetHTTPBodyMarshaler(serveMux *ServeMux) { + serveMux.marshalers.mimeMap[MIMEWildcard] = &HTTPBodyMarshaler{ + Marshaler: &JSONPb{OrigName: true}, + } +} + +// HTTPBodyMarshaler is a Marshaler which supports marshaling of a +// google.api.HttpBody message as the full response body if it is +// the actual message used as the response. If not, then this will +// simply fallback to the Marshaler specified as its default Marshaler. +type HTTPBodyMarshaler struct { + Marshaler +} + +// ContentType implementation to keep backwards compatability with marshal interface +func (h *HTTPBodyMarshaler) ContentType() string { + return h.ContentTypeFromMessage(nil) +} + +// ContentTypeFromMessage in case v is a google.api.HttpBody message it returns +// its specified content type otherwise fall back to the default Marshaler. +func (h *HTTPBodyMarshaler) ContentTypeFromMessage(v interface{}) string { + if httpBody, ok := v.(*httpbody.HttpBody); ok { + return httpBody.GetContentType() + } + return h.Marshaler.ContentType() +} + +// Marshal marshals "v" by returning the body bytes if v is a +// google.api.HttpBody message, otherwise it falls back to the default Marshaler. +func (h *HTTPBodyMarshaler) Marshal(v interface{}) ([]byte, error) { + if httpBody, ok := v.(*httpbody.HttpBody); ok { + return httpBody.Data, nil + } + return h.Marshaler.Marshal(v) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go new file mode 100644 index 000000000..f9d3a585a --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_json.go @@ -0,0 +1,45 @@ +package runtime + +import ( + "encoding/json" + "io" +) + +// JSONBuiltin is a Marshaler which marshals/unmarshals into/from JSON +// with the standard "encoding/json" package of Golang. +// Although it is generally faster for simple proto messages than JSONPb, +// it does not support advanced features of protobuf, e.g. map, oneof, .... +// +// The NewEncoder and NewDecoder types return *json.Encoder and +// *json.Decoder respectively. +type JSONBuiltin struct{} + +// ContentType always Returns "application/json". +func (*JSONBuiltin) ContentType() string { + return "application/json" +} + +// Marshal marshals "v" into JSON +func (j *JSONBuiltin) Marshal(v interface{}) ([]byte, error) { + return json.Marshal(v) +} + +// Unmarshal unmarshals JSON data into "v". +func (j *JSONBuiltin) Unmarshal(data []byte, v interface{}) error { + return json.Unmarshal(data, v) +} + +// NewDecoder returns a Decoder which reads JSON stream from "r". +func (j *JSONBuiltin) NewDecoder(r io.Reader) Decoder { + return json.NewDecoder(r) +} + +// NewEncoder returns an Encoder which writes JSON stream into "w". +func (j *JSONBuiltin) NewEncoder(w io.Writer) Encoder { + return json.NewEncoder(w) +} + +// Delimiter for newline encoded JSON streams. +func (j *JSONBuiltin) Delimiter() []byte { + return []byte("\n") +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go new file mode 100644 index 000000000..3530dddd0 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_jsonpb.go @@ -0,0 +1,242 @@ +package runtime + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "reflect" + + "github.com/golang/protobuf/jsonpb" + "github.com/golang/protobuf/proto" +) + +// JSONPb is a Marshaler which marshals/unmarshals into/from JSON +// with the "github.com/golang/protobuf/jsonpb". +// It supports fully functionality of protobuf unlike JSONBuiltin. +// +// The NewDecoder method returns a DecoderWrapper, so the underlying +// *json.Decoder methods can be used. +type JSONPb jsonpb.Marshaler + +// ContentType always returns "application/json". +func (*JSONPb) ContentType() string { + return "application/json" +} + +// Marshal marshals "v" into JSON. +func (j *JSONPb) Marshal(v interface{}) ([]byte, error) { + if _, ok := v.(proto.Message); !ok { + return j.marshalNonProtoField(v) + } + + var buf bytes.Buffer + if err := j.marshalTo(&buf, v); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error { + p, ok := v.(proto.Message) + if !ok { + buf, err := j.marshalNonProtoField(v) + if err != nil { + return err + } + _, err = w.Write(buf) + return err + } + return (*jsonpb.Marshaler)(j).Marshal(w, p) +} + +var ( + // protoMessageType is stored to prevent constant lookup of the same type at runtime. + protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() +) + +// marshalNonProto marshals a non-message field of a protobuf message. +// This function does not correctly marshals arbitrary data structure into JSON, +// but it is only capable of marshaling non-message field values of protobuf, +// i.e. primitive types, enums; pointers to primitives or enums; maps from +// integer/string types to primitives/enums/pointers to messages. +func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) { + if v == nil { + return []byte("null"), nil + } + rv := reflect.ValueOf(v) + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + return []byte("null"), nil + } + rv = rv.Elem() + } + + if rv.Kind() == reflect.Slice { + if rv.IsNil() { + if j.EmitDefaults { + return []byte("[]"), nil + } + return []byte("null"), nil + } + + if rv.Type().Elem().Implements(protoMessageType) { + var buf bytes.Buffer + err := buf.WriteByte('[') + if err != nil { + return nil, err + } + for i := 0; i < rv.Len(); i++ { + if i != 0 { + err = buf.WriteByte(',') + if err != nil { + return nil, err + } + } + if err = (*jsonpb.Marshaler)(j).Marshal(&buf, rv.Index(i).Interface().(proto.Message)); err != nil { + return nil, err + } + } + err = buf.WriteByte(']') + if err != nil { + return nil, err + } + + return buf.Bytes(), nil + } + } + + if rv.Kind() == reflect.Map { + m := make(map[string]*json.RawMessage) + for _, k := range rv.MapKeys() { + buf, err := j.Marshal(rv.MapIndex(k).Interface()) + if err != nil { + return nil, err + } + m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf) + } + if j.Indent != "" { + return json.MarshalIndent(m, "", j.Indent) + } + return json.Marshal(m) + } + if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts { + return json.Marshal(enum.String()) + } + return json.Marshal(rv.Interface()) +} + +// Unmarshal unmarshals JSON "data" into "v" +func (j *JSONPb) Unmarshal(data []byte, v interface{}) error { + return unmarshalJSONPb(data, v) +} + +// NewDecoder returns a Decoder which reads JSON stream from "r". +func (j *JSONPb) NewDecoder(r io.Reader) Decoder { + d := json.NewDecoder(r) + return DecoderWrapper{Decoder: d} +} + +// DecoderWrapper is a wrapper around a *json.Decoder that adds +// support for protos to the Decode method. +type DecoderWrapper struct { + *json.Decoder +} + +// Decode wraps the embedded decoder's Decode method to support +// protos using a jsonpb.Unmarshaler. +func (d DecoderWrapper) Decode(v interface{}) error { + return decodeJSONPb(d.Decoder, v) +} + +// NewEncoder returns an Encoder which writes JSON stream into "w". +func (j *JSONPb) NewEncoder(w io.Writer) Encoder { + return EncoderFunc(func(v interface{}) error { return j.marshalTo(w, v) }) +} + +func unmarshalJSONPb(data []byte, v interface{}) error { + d := json.NewDecoder(bytes.NewReader(data)) + return decodeJSONPb(d, v) +} + +func decodeJSONPb(d *json.Decoder, v interface{}) error { + p, ok := v.(proto.Message) + if !ok { + return decodeNonProtoField(d, v) + } + unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true} + return unmarshaler.UnmarshalNext(d, p) +} + +func decodeNonProtoField(d *json.Decoder, v interface{}) error { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr { + return fmt.Errorf("%T is not a pointer", v) + } + for rv.Kind() == reflect.Ptr { + if rv.IsNil() { + rv.Set(reflect.New(rv.Type().Elem())) + } + if rv.Type().ConvertibleTo(typeProtoMessage) { + unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true} + return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message)) + } + rv = rv.Elem() + } + if rv.Kind() == reflect.Map { + if rv.IsNil() { + rv.Set(reflect.MakeMap(rv.Type())) + } + conv, ok := convFromType[rv.Type().Key().Kind()] + if !ok { + return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key()) + } + + m := make(map[string]*json.RawMessage) + if err := d.Decode(&m); err != nil { + return err + } + for k, v := range m { + result := conv.Call([]reflect.Value{reflect.ValueOf(k)}) + if err := result[1].Interface(); err != nil { + return err.(error) + } + bk := result[0] + bv := reflect.New(rv.Type().Elem()) + if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil { + return err + } + rv.SetMapIndex(bk, bv.Elem()) + } + return nil + } + if _, ok := rv.Interface().(protoEnum); ok { + var repr interface{} + if err := d.Decode(&repr); err != nil { + return err + } + switch repr.(type) { + case string: + // TODO(yugui) Should use proto.StructProperties? + return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface()) + case float64: + rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type())) + return nil + default: + return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface()) + } + } + return d.Decode(v) +} + +type protoEnum interface { + fmt.Stringer + EnumDescriptor() ([]byte, []int) +} + +var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() + +// Delimiter for newline encoded JSON streams. +func (j *JSONPb) Delimiter() []byte { + return []byte("\n") +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go new file mode 100644 index 000000000..f65d1a267 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshal_proto.go @@ -0,0 +1,62 @@ +package runtime + +import ( + "io" + + "errors" + "github.com/golang/protobuf/proto" + "io/ioutil" +) + +// ProtoMarshaller is a Marshaller which marshals/unmarshals into/from serialize proto bytes +type ProtoMarshaller struct{} + +// ContentType always returns "application/octet-stream". +func (*ProtoMarshaller) ContentType() string { + return "application/octet-stream" +} + +// Marshal marshals "value" into Proto +func (*ProtoMarshaller) Marshal(value interface{}) ([]byte, error) { + message, ok := value.(proto.Message) + if !ok { + return nil, errors.New("unable to marshal non proto field") + } + return proto.Marshal(message) +} + +// Unmarshal unmarshals proto "data" into "value" +func (*ProtoMarshaller) Unmarshal(data []byte, value interface{}) error { + message, ok := value.(proto.Message) + if !ok { + return errors.New("unable to unmarshal non proto field") + } + return proto.Unmarshal(data, message) +} + +// NewDecoder returns a Decoder which reads proto stream from "reader". +func (marshaller *ProtoMarshaller) NewDecoder(reader io.Reader) Decoder { + return DecoderFunc(func(value interface{}) error { + buffer, err := ioutil.ReadAll(reader) + if err != nil { + return err + } + return marshaller.Unmarshal(buffer, value) + }) +} + +// NewEncoder returns an Encoder which writes proto stream into "writer". +func (marshaller *ProtoMarshaller) NewEncoder(writer io.Writer) Encoder { + return EncoderFunc(func(value interface{}) error { + buffer, err := marshaller.Marshal(value) + if err != nil { + return err + } + _, err = writer.Write(buffer) + if err != nil { + return err + } + + return nil + }) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go new file mode 100644 index 000000000..98fe6e88a --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler.go @@ -0,0 +1,48 @@ +package runtime + +import ( + "io" +) + +// Marshaler defines a conversion between byte sequence and gRPC payloads / fields. +type Marshaler interface { + // Marshal marshals "v" into byte sequence. + Marshal(v interface{}) ([]byte, error) + // Unmarshal unmarshals "data" into "v". + // "v" must be a pointer value. + Unmarshal(data []byte, v interface{}) error + // NewDecoder returns a Decoder which reads byte sequence from "r". + NewDecoder(r io.Reader) Decoder + // NewEncoder returns an Encoder which writes bytes sequence into "w". + NewEncoder(w io.Writer) Encoder + // ContentType returns the Content-Type which this marshaler is responsible for. + ContentType() string +} + +// Decoder decodes a byte sequence +type Decoder interface { + Decode(v interface{}) error +} + +// Encoder encodes gRPC payloads / fields into byte sequence. +type Encoder interface { + Encode(v interface{}) error +} + +// DecoderFunc adapts an decoder function into Decoder. +type DecoderFunc func(v interface{}) error + +// Decode delegates invocations to the underlying function itself. +func (f DecoderFunc) Decode(v interface{}) error { return f(v) } + +// EncoderFunc adapts an encoder function into Encoder +type EncoderFunc func(v interface{}) error + +// Encode delegates invocations to the underlying function itself. +func (f EncoderFunc) Encode(v interface{}) error { return f(v) } + +// Delimited defines the streaming delimiter. +type Delimited interface { + // Delimiter returns the record seperator for the stream. + Delimiter() []byte +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go new file mode 100644 index 000000000..5cc53ae4f --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/marshaler_registry.go @@ -0,0 +1,91 @@ +package runtime + +import ( + "errors" + "net/http" +) + +// MIMEWildcard is the fallback MIME type used for requests which do not match +// a registered MIME type. +const MIMEWildcard = "*" + +var ( + acceptHeader = http.CanonicalHeaderKey("Accept") + contentTypeHeader = http.CanonicalHeaderKey("Content-Type") + + defaultMarshaler = &JSONPb{OrigName: true} +) + +// MarshalerForRequest returns the inbound/outbound marshalers for this request. +// It checks the registry on the ServeMux for the MIME type set by the Content-Type header. +// If it isn't set (or the request Content-Type is empty), checks for "*". +// If there are multiple Content-Type headers set, choose the first one that it can +// exactly match in the registry. +// Otherwise, it follows the above logic for "*"/InboundMarshaler/OutboundMarshaler. +func MarshalerForRequest(mux *ServeMux, r *http.Request) (inbound Marshaler, outbound Marshaler) { + for _, acceptVal := range r.Header[acceptHeader] { + if m, ok := mux.marshalers.mimeMap[acceptVal]; ok { + outbound = m + break + } + } + + for _, contentTypeVal := range r.Header[contentTypeHeader] { + if m, ok := mux.marshalers.mimeMap[contentTypeVal]; ok { + inbound = m + break + } + } + + if inbound == nil { + inbound = mux.marshalers.mimeMap[MIMEWildcard] + } + if outbound == nil { + outbound = inbound + } + + return inbound, outbound +} + +// marshalerRegistry is a mapping from MIME types to Marshalers. +type marshalerRegistry struct { + mimeMap map[string]Marshaler +} + +// add adds a marshaler for a case-sensitive MIME type string ("*" to match any +// MIME type). +func (m marshalerRegistry) add(mime string, marshaler Marshaler) error { + if len(mime) == 0 { + return errors.New("empty MIME type") + } + + m.mimeMap[mime] = marshaler + + return nil +} + +// makeMarshalerMIMERegistry returns a new registry of marshalers. +// It allows for a mapping of case-sensitive Content-Type MIME type string to runtime.Marshaler interfaces. +// +// For example, you could allow the client to specify the use of the runtime.JSONPb marshaler +// with a "application/jsonpb" Content-Type and the use of the runtime.JSONBuiltin marshaler +// with a "application/json" Content-Type. +// "*" can be used to match any Content-Type. +// This can be attached to a ServerMux with the marshaler option. +func makeMarshalerMIMERegistry() marshalerRegistry { + return marshalerRegistry{ + mimeMap: map[string]Marshaler{ + MIMEWildcard: defaultMarshaler, + }, + } +} + +// WithMarshalerOption returns a ServeMuxOption which associates inbound and outbound +// Marshalers to a MIME type in mux. +func WithMarshalerOption(mime string, marshaler Marshaler) ServeMuxOption { + return func(mux *ServeMux) { + if err := mux.marshalers.add(mime, marshaler); err != nil { + panic(err) + } + } +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go new file mode 100644 index 000000000..ec81e55b5 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/mux.go @@ -0,0 +1,268 @@ +package runtime + +import ( + "context" + "fmt" + "net/http" + "net/textproto" + "strings" + + "github.com/golang/protobuf/proto" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// A HandlerFunc handles a specific pair of path pattern and HTTP method. +type HandlerFunc func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) + +// ServeMux is a request multiplexer for grpc-gateway. +// It matches http requests to patterns and invokes the corresponding handler. +type ServeMux struct { + // handlers maps HTTP method to a list of handlers. + handlers map[string][]handler + forwardResponseOptions []func(context.Context, http.ResponseWriter, proto.Message) error + marshalers marshalerRegistry + incomingHeaderMatcher HeaderMatcherFunc + outgoingHeaderMatcher HeaderMatcherFunc + metadataAnnotators []func(context.Context, *http.Request) metadata.MD + protoErrorHandler ProtoErrorHandlerFunc + disablePathLengthFallback bool +} + +// ServeMuxOption is an option that can be given to a ServeMux on construction. +type ServeMuxOption func(*ServeMux) + +// WithForwardResponseOption returns a ServeMuxOption representing the forwardResponseOption. +// +// forwardResponseOption is an option that will be called on the relevant context.Context, +// http.ResponseWriter, and proto.Message before every forwarded response. +// +// The message may be nil in the case where just a header is being sent. +func WithForwardResponseOption(forwardResponseOption func(context.Context, http.ResponseWriter, proto.Message) error) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.forwardResponseOptions = append(serveMux.forwardResponseOptions, forwardResponseOption) + } +} + +// HeaderMatcherFunc checks whether a header key should be forwarded to/from gRPC context. +type HeaderMatcherFunc func(string) (string, bool) + +// DefaultHeaderMatcher is used to pass http request headers to/from gRPC context. This adds permanent HTTP header +// keys (as specified by the IANA) to gRPC context with grpcgateway- prefix. HTTP headers that start with +// 'Grpc-Metadata-' are mapped to gRPC metadata after removing prefix 'Grpc-Metadata-'. +func DefaultHeaderMatcher(key string) (string, bool) { + key = textproto.CanonicalMIMEHeaderKey(key) + if isPermanentHTTPHeader(key) { + return MetadataPrefix + key, true + } else if strings.HasPrefix(key, MetadataHeaderPrefix) { + return key[len(MetadataHeaderPrefix):], true + } + return "", false +} + +// WithIncomingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for incoming request to gateway. +// +// This matcher will be called with each header in http.Request. If matcher returns true, that header will be +// passed to gRPC context. To transform the header before passing to gRPC context, matcher should return modified header. +func WithIncomingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { + return func(mux *ServeMux) { + mux.incomingHeaderMatcher = fn + } +} + +// WithOutgoingHeaderMatcher returns a ServeMuxOption representing a headerMatcher for outgoing response from gateway. +// +// This matcher will be called with each header in response header metadata. If matcher returns true, that header will be +// passed to http response returned from gateway. To transform the header before passing to response, +// matcher should return modified header. +func WithOutgoingHeaderMatcher(fn HeaderMatcherFunc) ServeMuxOption { + return func(mux *ServeMux) { + mux.outgoingHeaderMatcher = fn + } +} + +// WithMetadata returns a ServeMuxOption for passing metadata to a gRPC context. +// +// This can be used by services that need to read from http.Request and modify gRPC context. A common use case +// is reading token from cookie and adding it in gRPC context. +func WithMetadata(annotator func(context.Context, *http.Request) metadata.MD) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.metadataAnnotators = append(serveMux.metadataAnnotators, annotator) + } +} + +// WithProtoErrorHandler returns a ServeMuxOption for passing metadata to a gRPC context. +// +// This can be used to handle an error as general proto message defined by gRPC. +// The response including body and status is not backward compatible with the default error handler. +// When this option is used, HTTPError and OtherErrorHandler are overwritten on initialization. +func WithProtoErrorHandler(fn ProtoErrorHandlerFunc) ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.protoErrorHandler = fn + } +} + +// WithDisablePathLengthFallback returns a ServeMuxOption for disable path length fallback. +func WithDisablePathLengthFallback() ServeMuxOption { + return func(serveMux *ServeMux) { + serveMux.disablePathLengthFallback = true + } +} + +// NewServeMux returns a new ServeMux whose internal mapping is empty. +func NewServeMux(opts ...ServeMuxOption) *ServeMux { + serveMux := &ServeMux{ + handlers: make(map[string][]handler), + forwardResponseOptions: make([]func(context.Context, http.ResponseWriter, proto.Message) error, 0), + marshalers: makeMarshalerMIMERegistry(), + } + + for _, opt := range opts { + opt(serveMux) + } + + if serveMux.protoErrorHandler != nil { + HTTPError = serveMux.protoErrorHandler + // OtherErrorHandler is no longer used when protoErrorHandler is set. + // Overwritten by a special error handler to return Unknown. + OtherErrorHandler = func(w http.ResponseWriter, r *http.Request, _ string, _ int) { + ctx := context.Background() + _, outboundMarshaler := MarshalerForRequest(serveMux, r) + sterr := status.Error(codes.Unknown, "unexpected use of OtherErrorHandler") + serveMux.protoErrorHandler(ctx, serveMux, outboundMarshaler, w, r, sterr) + } + } + + if serveMux.incomingHeaderMatcher == nil { + serveMux.incomingHeaderMatcher = DefaultHeaderMatcher + } + + if serveMux.outgoingHeaderMatcher == nil { + serveMux.outgoingHeaderMatcher = func(key string) (string, bool) { + return fmt.Sprintf("%s%s", MetadataHeaderPrefix, key), true + } + } + + return serveMux +} + +// Handle associates "h" to the pair of HTTP method and path pattern. +func (s *ServeMux) Handle(meth string, pat Pattern, h HandlerFunc) { + s.handlers[meth] = append(s.handlers[meth], handler{pat: pat, h: h}) +} + +// ServeHTTP dispatches the request to the first handler whose pattern matches to r.Method and r.Path. +func (s *ServeMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + path := r.URL.Path + if !strings.HasPrefix(path, "/") { + if s.protoErrorHandler != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.InvalidArgument, http.StatusText(http.StatusBadRequest)) + s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) + } else { + OtherErrorHandler(w, r, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) + } + return + } + + components := strings.Split(path[1:], "/") + l := len(components) + var verb string + if idx := strings.LastIndex(components[l-1], ":"); idx == 0 { + if s.protoErrorHandler != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented)) + s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) + } else { + OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound) + } + return + } else if idx > 0 { + c := components[l-1] + components[l-1], verb = c[:idx], c[idx+1:] + } + + if override := r.Header.Get("X-HTTP-Method-Override"); override != "" && s.isPathLengthFallback(r) { + r.Method = strings.ToUpper(override) + if err := r.ParseForm(); err != nil { + if s.protoErrorHandler != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.InvalidArgument, err.Error()) + s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) + } else { + OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest) + } + return + } + } + for _, h := range s.handlers[r.Method] { + pathParams, err := h.pat.Match(components, verb) + if err != nil { + continue + } + h.h(w, r, pathParams) + return + } + + // lookup other methods to handle fallback from GET to POST and + // to determine if it is MethodNotAllowed or NotFound. + for m, handlers := range s.handlers { + if m == r.Method { + continue + } + for _, h := range handlers { + pathParams, err := h.pat.Match(components, verb) + if err != nil { + continue + } + // X-HTTP-Method-Override is optional. Always allow fallback to POST. + if s.isPathLengthFallback(r) { + if err := r.ParseForm(); err != nil { + if s.protoErrorHandler != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.InvalidArgument, err.Error()) + s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) + } else { + OtherErrorHandler(w, r, err.Error(), http.StatusBadRequest) + } + return + } + h.h(w, r, pathParams) + return + } + if s.protoErrorHandler != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.Unimplemented, http.StatusText(http.StatusMethodNotAllowed)) + s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) + } else { + OtherErrorHandler(w, r, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) + } + return + } + } + + if s.protoErrorHandler != nil { + _, outboundMarshaler := MarshalerForRequest(s, r) + sterr := status.Error(codes.Unimplemented, http.StatusText(http.StatusNotImplemented)) + s.protoErrorHandler(ctx, s, outboundMarshaler, w, r, sterr) + } else { + OtherErrorHandler(w, r, http.StatusText(http.StatusNotFound), http.StatusNotFound) + } +} + +// GetForwardResponseOptions returns the ForwardResponseOptions associated with this ServeMux. +func (s *ServeMux) GetForwardResponseOptions() []func(context.Context, http.ResponseWriter, proto.Message) error { + return s.forwardResponseOptions +} + +func (s *ServeMux) isPathLengthFallback(r *http.Request) bool { + return !s.disablePathLengthFallback && r.Method == "POST" && r.Header.Get("Content-Type") == "application/x-www-form-urlencoded" +} + +type handler struct { + pat Pattern + h HandlerFunc +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go new file mode 100644 index 000000000..f16a84ad3 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/pattern.go @@ -0,0 +1,227 @@ +package runtime + +import ( + "errors" + "fmt" + "strings" + + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc/grpclog" +) + +var ( + // ErrNotMatch indicates that the given HTTP request path does not match to the pattern. + ErrNotMatch = errors.New("not match to the path pattern") + // ErrInvalidPattern indicates that the given definition of Pattern is not valid. + ErrInvalidPattern = errors.New("invalid pattern") +) + +type op struct { + code utilities.OpCode + operand int +} + +// Pattern is a template pattern of http request paths defined in github.com/googleapis/googleapis/google/api/http.proto. +type Pattern struct { + // ops is a list of operations + ops []op + // pool is a constant pool indexed by the operands or vars. + pool []string + // vars is a list of variables names to be bound by this pattern + vars []string + // stacksize is the max depth of the stack + stacksize int + // tailLen is the length of the fixed-size segments after a deep wildcard + tailLen int + // verb is the VERB part of the path pattern. It is empty if the pattern does not have VERB part. + verb string +} + +// NewPattern returns a new Pattern from the given definition values. +// "ops" is a sequence of op codes. "pool" is a constant pool. +// "verb" is the verb part of the pattern. It is empty if the pattern does not have the part. +// "version" must be 1 for now. +// It returns an error if the given definition is invalid. +func NewPattern(version int, ops []int, pool []string, verb string) (Pattern, error) { + if version != 1 { + grpclog.Infof("unsupported version: %d", version) + return Pattern{}, ErrInvalidPattern + } + + l := len(ops) + if l%2 != 0 { + grpclog.Infof("odd number of ops codes: %d", l) + return Pattern{}, ErrInvalidPattern + } + + var ( + typedOps []op + stack, maxstack int + tailLen int + pushMSeen bool + vars []string + ) + for i := 0; i < l; i += 2 { + op := op{code: utilities.OpCode(ops[i]), operand: ops[i+1]} + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush: + if pushMSeen { + tailLen++ + } + stack++ + case utilities.OpPushM: + if pushMSeen { + grpclog.Infof("pushM appears twice") + return Pattern{}, ErrInvalidPattern + } + pushMSeen = true + stack++ + case utilities.OpLitPush: + if op.operand < 0 || len(pool) <= op.operand { + grpclog.Infof("negative literal index: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + if pushMSeen { + tailLen++ + } + stack++ + case utilities.OpConcatN: + if op.operand <= 0 { + grpclog.Infof("negative concat size: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + stack -= op.operand + if stack < 0 { + grpclog.Print("stack underflow") + return Pattern{}, ErrInvalidPattern + } + stack++ + case utilities.OpCapture: + if op.operand < 0 || len(pool) <= op.operand { + grpclog.Infof("variable name index out of bound: %d", op.operand) + return Pattern{}, ErrInvalidPattern + } + v := pool[op.operand] + op.operand = len(vars) + vars = append(vars, v) + stack-- + if stack < 0 { + grpclog.Infof("stack underflow") + return Pattern{}, ErrInvalidPattern + } + default: + grpclog.Infof("invalid opcode: %d", op.code) + return Pattern{}, ErrInvalidPattern + } + + if maxstack < stack { + maxstack = stack + } + typedOps = append(typedOps, op) + } + return Pattern{ + ops: typedOps, + pool: pool, + vars: vars, + stacksize: maxstack, + tailLen: tailLen, + verb: verb, + }, nil +} + +// MustPattern is a helper function which makes it easier to call NewPattern in variable initialization. +func MustPattern(p Pattern, err error) Pattern { + if err != nil { + grpclog.Fatalf("Pattern initialization failed: %v", err) + } + return p +} + +// Match examines components if it matches to the Pattern. +// If it matches, the function returns a mapping from field paths to their captured values. +// If otherwise, the function returns an error. +func (p Pattern) Match(components []string, verb string) (map[string]string, error) { + if p.verb != verb { + return nil, ErrNotMatch + } + + var pos int + stack := make([]string, 0, p.stacksize) + captured := make([]string, len(p.vars)) + l := len(components) + for _, op := range p.ops { + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush, utilities.OpLitPush: + if pos >= l { + return nil, ErrNotMatch + } + c := components[pos] + if op.code == utilities.OpLitPush { + if lit := p.pool[op.operand]; c != lit { + return nil, ErrNotMatch + } + } + stack = append(stack, c) + pos++ + case utilities.OpPushM: + end := len(components) + if end < pos+p.tailLen { + return nil, ErrNotMatch + } + end -= p.tailLen + stack = append(stack, strings.Join(components[pos:end], "/")) + pos = end + case utilities.OpConcatN: + n := op.operand + l := len(stack) - n + stack = append(stack[:l], strings.Join(stack[l:], "/")) + case utilities.OpCapture: + n := len(stack) - 1 + captured[op.operand] = stack[n] + stack = stack[:n] + } + } + if pos < l { + return nil, ErrNotMatch + } + bindings := make(map[string]string) + for i, val := range captured { + bindings[p.vars[i]] = val + } + return bindings, nil +} + +// Verb returns the verb part of the Pattern. +func (p Pattern) Verb() string { return p.verb } + +func (p Pattern) String() string { + var stack []string + for _, op := range p.ops { + switch op.code { + case utilities.OpNop: + continue + case utilities.OpPush: + stack = append(stack, "*") + case utilities.OpLitPush: + stack = append(stack, p.pool[op.operand]) + case utilities.OpPushM: + stack = append(stack, "**") + case utilities.OpConcatN: + n := op.operand + l := len(stack) - n + stack = append(stack[:l], strings.Join(stack[l:], "/")) + case utilities.OpCapture: + n := len(stack) - 1 + stack[n] = fmt.Sprintf("{%s=%s}", p.vars[op.operand], stack[n]) + } + } + segs := strings.Join(stack, "/") + if p.verb != "" { + return fmt.Sprintf("/%s:%s", segs, p.verb) + } + return "/" + segs +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go new file mode 100644 index 000000000..a3151e2a5 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto2_convert.go @@ -0,0 +1,80 @@ +package runtime + +import ( + "github.com/golang/protobuf/proto" +) + +// StringP returns a pointer to a string whose pointee is same as the given string value. +func StringP(val string) (*string, error) { + return proto.String(val), nil +} + +// BoolP parses the given string representation of a boolean value, +// and returns a pointer to a bool whose value is same as the parsed value. +func BoolP(val string) (*bool, error) { + b, err := Bool(val) + if err != nil { + return nil, err + } + return proto.Bool(b), nil +} + +// Float64P parses the given string representation of a floating point number, +// and returns a pointer to a float64 whose value is same as the parsed number. +func Float64P(val string) (*float64, error) { + f, err := Float64(val) + if err != nil { + return nil, err + } + return proto.Float64(f), nil +} + +// Float32P parses the given string representation of a floating point number, +// and returns a pointer to a float32 whose value is same as the parsed number. +func Float32P(val string) (*float32, error) { + f, err := Float32(val) + if err != nil { + return nil, err + } + return proto.Float32(f), nil +} + +// Int64P parses the given string representation of an integer +// and returns a pointer to a int64 whose value is same as the parsed integer. +func Int64P(val string) (*int64, error) { + i, err := Int64(val) + if err != nil { + return nil, err + } + return proto.Int64(i), nil +} + +// Int32P parses the given string representation of an integer +// and returns a pointer to a int32 whose value is same as the parsed integer. +func Int32P(val string) (*int32, error) { + i, err := Int32(val) + if err != nil { + return nil, err + } + return proto.Int32(i), err +} + +// Uint64P parses the given string representation of an integer +// and returns a pointer to a uint64 whose value is same as the parsed integer. +func Uint64P(val string) (*uint64, error) { + i, err := Uint64(val) + if err != nil { + return nil, err + } + return proto.Uint64(i), err +} + +// Uint32P parses the given string representation of an integer +// and returns a pointer to a uint32 whose value is same as the parsed integer. +func Uint32P(val string) (*uint32, error) { + i, err := Uint32(val) + if err != nil { + return nil, err + } + return proto.Uint32(i), err +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go new file mode 100644 index 000000000..b7fa32e45 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/proto_errors.go @@ -0,0 +1,70 @@ +package runtime + +import ( + "io" + "net/http" + + "context" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// ProtoErrorHandlerFunc handles the error as a gRPC error generated via status package and replies to the request. +type ProtoErrorHandlerFunc func(context.Context, *ServeMux, Marshaler, http.ResponseWriter, *http.Request, error) + +var _ ProtoErrorHandlerFunc = DefaultHTTPProtoErrorHandler + +// DefaultHTTPProtoErrorHandler is an implementation of HTTPError. +// If "err" is an error from gRPC system, the function replies with the status code mapped by HTTPStatusFromCode. +// If otherwise, it replies with http.StatusInternalServerError. +// +// The response body returned by this function is a Status message marshaled by a Marshaler. +// +// Do not set this function to HTTPError variable directly, use WithProtoErrorHandler option instead. +func DefaultHTTPProtoErrorHandler(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, _ *http.Request, err error) { + // return Internal when Marshal failed + const fallback = `{"code": 13, "message": "failed to marshal error message"}` + + s, ok := status.FromError(err) + if !ok { + s = status.New(codes.Unknown, err.Error()) + } + + w.Header().Del("Trailer") + + contentType := marshaler.ContentType() + // Check marshaler on run time in order to keep backwards compatability + // An interface param needs to be added to the ContentType() function on + // the Marshal interface to be able to remove this check + if httpBodyMarshaler, ok := marshaler.(*HTTPBodyMarshaler); ok { + pb := s.Proto() + contentType = httpBodyMarshaler.ContentTypeFromMessage(pb) + } + w.Header().Set("Content-Type", contentType) + + buf, merr := marshaler.Marshal(s.Proto()) + if merr != nil { + grpclog.Infof("Failed to marshal error message %q: %v", s.Proto(), merr) + w.WriteHeader(http.StatusInternalServerError) + if _, err := io.WriteString(w, fallback); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + return + } + + md, ok := ServerMetadataFromContext(ctx) + if !ok { + grpclog.Infof("Failed to extract ServerMetadata from context") + } + + handleForwardResponseServerMetadata(w, mux, md) + handleForwardResponseTrailerHeader(w, md) + st := HTTPStatusFromCode(s.Code()) + w.WriteHeader(st) + if _, err := w.Write(buf); err != nil { + grpclog.Infof("Failed to write response: %v", err) + } + + handleForwardResponseTrailer(w, md) +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go new file mode 100644 index 000000000..bb9359f17 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/runtime/query.go @@ -0,0 +1,392 @@ +package runtime + +import ( + "encoding/base64" + "fmt" + "net/url" + "reflect" + "regexp" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc/grpclog" +) + +// PopulateQueryParameters populates "values" into "msg". +// A value is ignored if its key starts with one of the elements in "filter". +func PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray) error { + for key, values := range values { + re, err := regexp.Compile("^(.*)\\[(.*)\\]$") + if err != nil { + return err + } + match := re.FindStringSubmatch(key) + if len(match) == 3 { + key = match[1] + values = append([]string{match[2]}, values...) + } + fieldPath := strings.Split(key, ".") + if filter.HasCommonPrefix(fieldPath) { + continue + } + if err := populateFieldValueFromPath(msg, fieldPath, values); err != nil { + return err + } + } + return nil +} + +// PopulateFieldFromPath sets a value in a nested Protobuf structure. +// It instantiates missing protobuf fields as it goes. +func PopulateFieldFromPath(msg proto.Message, fieldPathString string, value string) error { + fieldPath := strings.Split(fieldPathString, ".") + return populateFieldValueFromPath(msg, fieldPath, []string{value}) +} + +func populateFieldValueFromPath(msg proto.Message, fieldPath []string, values []string) error { + m := reflect.ValueOf(msg) + if m.Kind() != reflect.Ptr { + return fmt.Errorf("unexpected type %T: %v", msg, msg) + } + var props *proto.Properties + m = m.Elem() + for i, fieldName := range fieldPath { + isLast := i == len(fieldPath)-1 + if !isLast && m.Kind() != reflect.Struct { + return fmt.Errorf("non-aggregate type in the mid of path: %s", strings.Join(fieldPath, ".")) + } + var f reflect.Value + var err error + f, props, err = fieldByProtoName(m, fieldName) + if err != nil { + return err + } else if !f.IsValid() { + grpclog.Infof("field not found in %T: %s", msg, strings.Join(fieldPath, ".")) + return nil + } + + switch f.Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, reflect.String, reflect.Uint32, reflect.Uint64: + if !isLast { + return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], ".")) + } + m = f + case reflect.Slice: + if !isLast { + return fmt.Errorf("unexpected repeated field in %s", strings.Join(fieldPath, ".")) + } + // Handle []byte + if f.Type().Elem().Kind() == reflect.Uint8 { + m = f + break + } + return populateRepeatedField(f, values, props) + case reflect.Ptr: + if f.IsNil() { + m = reflect.New(f.Type().Elem()) + f.Set(m.Convert(f.Type())) + } + m = f.Elem() + continue + case reflect.Struct: + m = f + continue + case reflect.Map: + if !isLast { + return fmt.Errorf("unexpected nested field %s in %s", fieldPath[i+1], strings.Join(fieldPath[:i+1], ".")) + } + return populateMapField(f, values, props) + default: + return fmt.Errorf("unexpected type %s in %T", f.Type(), msg) + } + } + switch len(values) { + case 0: + return fmt.Errorf("no value of field: %s", strings.Join(fieldPath, ".")) + case 1: + default: + grpclog.Infof("too many field values: %s", strings.Join(fieldPath, ".")) + } + return populateField(m, values[0], props) +} + +// fieldByProtoName looks up a field whose corresponding protobuf field name is "name". +// "m" must be a struct value. It returns zero reflect.Value if no such field found. +func fieldByProtoName(m reflect.Value, name string) (reflect.Value, *proto.Properties, error) { + props := proto.GetProperties(m.Type()) + + // look up field name in oneof map + if op, ok := props.OneofTypes[name]; ok { + v := reflect.New(op.Type.Elem()) + field := m.Field(op.Field) + if !field.IsNil() { + return reflect.Value{}, nil, fmt.Errorf("field already set for %s oneof", props.Prop[op.Field].OrigName) + } + field.Set(v) + return v.Elem().Field(0), op.Prop, nil + } + + for _, p := range props.Prop { + if p.OrigName == name { + return m.FieldByName(p.Name), p, nil + } + if p.JSONName == name { + return m.FieldByName(p.Name), p, nil + } + } + return reflect.Value{}, nil, nil +} + +func populateMapField(f reflect.Value, values []string, props *proto.Properties) error { + if len(values) != 2 { + return fmt.Errorf("more than one value provided for key %s in map %s", values[0], props.Name) + } + + key, value := values[0], values[1] + keyType := f.Type().Key() + valueType := f.Type().Elem() + if f.IsNil() { + f.Set(reflect.MakeMap(f.Type())) + } + + keyConv, ok := convFromType[keyType.Kind()] + if !ok { + return fmt.Errorf("unsupported key type %s in map %s", keyType, props.Name) + } + valueConv, ok := convFromType[valueType.Kind()] + if !ok { + return fmt.Errorf("unsupported value type %s in map %s", valueType, props.Name) + } + + keyV := keyConv.Call([]reflect.Value{reflect.ValueOf(key)}) + if err := keyV[1].Interface(); err != nil { + return err.(error) + } + valueV := valueConv.Call([]reflect.Value{reflect.ValueOf(value)}) + if err := valueV[1].Interface(); err != nil { + return err.(error) + } + + f.SetMapIndex(keyV[0].Convert(keyType), valueV[0].Convert(valueType)) + + return nil +} + +func populateRepeatedField(f reflect.Value, values []string, props *proto.Properties) error { + elemType := f.Type().Elem() + + // is the destination field a slice of an enumeration type? + if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil { + return populateFieldEnumRepeated(f, values, enumValMap) + } + + conv, ok := convFromType[elemType.Kind()] + if !ok { + return fmt.Errorf("unsupported field type %s", elemType) + } + f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type())) + for i, v := range values { + result := conv.Call([]reflect.Value{reflect.ValueOf(v)}) + if err := result[1].Interface(); err != nil { + return err.(error) + } + f.Index(i).Set(result[0].Convert(f.Index(i).Type())) + } + return nil +} + +func populateField(f reflect.Value, value string, props *proto.Properties) error { + i := f.Addr().Interface() + + // Handle protobuf well known types + type wkt interface { + XXX_WellKnownType() string + } + if wkt, ok := i.(wkt); ok { + switch wkt.XXX_WellKnownType() { + case "Timestamp": + if value == "null" { + f.Field(0).SetInt(0) + f.Field(1).SetInt(0) + return nil + } + + t, err := time.Parse(time.RFC3339Nano, value) + if err != nil { + return fmt.Errorf("bad Timestamp: %v", err) + } + f.Field(0).SetInt(int64(t.Unix())) + f.Field(1).SetInt(int64(t.Nanosecond())) + return nil + case "Duration": + if value == "null" { + f.Field(0).SetInt(0) + f.Field(1).SetInt(0) + return nil + } + d, err := time.ParseDuration(value) + if err != nil { + return fmt.Errorf("bad Duration: %v", err) + } + + ns := d.Nanoseconds() + s := ns / 1e9 + ns %= 1e9 + f.Field(0).SetInt(s) + f.Field(1).SetInt(ns) + return nil + case "DoubleValue": + fallthrough + case "FloatValue": + float64Val, err := strconv.ParseFloat(value, 64) + if err != nil { + return fmt.Errorf("bad DoubleValue: %s", value) + } + f.Field(0).SetFloat(float64Val) + return nil + case "Int64Value": + fallthrough + case "Int32Value": + int64Val, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return fmt.Errorf("bad DoubleValue: %s", value) + } + f.Field(0).SetInt(int64Val) + return nil + case "UInt64Value": + fallthrough + case "UInt32Value": + uint64Val, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return fmt.Errorf("bad DoubleValue: %s", value) + } + f.Field(0).SetUint(uint64Val) + return nil + case "BoolValue": + if value == "true" { + f.Field(0).SetBool(true) + } else if value == "false" { + f.Field(0).SetBool(false) + } else { + return fmt.Errorf("bad BoolValue: %s", value) + } + return nil + case "StringValue": + f.Field(0).SetString(value) + return nil + case "BytesValue": + bytesVal, err := base64.StdEncoding.DecodeString(value) + if err != nil { + return fmt.Errorf("bad BytesValue: %s", value) + } + f.Field(0).SetBytes(bytesVal) + return nil + } + } + + // Handle google well known types + if gwkt, ok := i.(proto.Message); ok { + switch proto.MessageName(gwkt) { + case "google.protobuf.FieldMask": + p := f.Field(0) + for _, v := range strings.Split(value, ",") { + if v != "" { + p.Set(reflect.Append(p, reflect.ValueOf(v))) + } + } + return nil + } + } + + // Handle Time and Duration stdlib types + switch t := i.(type) { + case *time.Time: + pt, err := time.Parse(time.RFC3339Nano, value) + if err != nil { + return fmt.Errorf("bad Timestamp: %v", err) + } + *t = pt + return nil + case *time.Duration: + d, err := time.ParseDuration(value) + if err != nil { + return fmt.Errorf("bad Duration: %v", err) + } + *t = d + return nil + } + + // is the destination field an enumeration type? + if enumValMap := proto.EnumValueMap(props.Enum); enumValMap != nil { + return populateFieldEnum(f, value, enumValMap) + } + + conv, ok := convFromType[f.Kind()] + if !ok { + return fmt.Errorf("field type %T is not supported in query parameters", i) + } + result := conv.Call([]reflect.Value{reflect.ValueOf(value)}) + if err := result[1].Interface(); err != nil { + return err.(error) + } + f.Set(result[0].Convert(f.Type())) + return nil +} + +func convertEnum(value string, t reflect.Type, enumValMap map[string]int32) (reflect.Value, error) { + // see if it's an enumeration string + if enumVal, ok := enumValMap[value]; ok { + return reflect.ValueOf(enumVal).Convert(t), nil + } + + // check for an integer that matches an enumeration value + eVal, err := strconv.Atoi(value) + if err != nil { + return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t) + } + for _, v := range enumValMap { + if v == int32(eVal) { + return reflect.ValueOf(eVal).Convert(t), nil + } + } + return reflect.Value{}, fmt.Errorf("%s is not a valid %s", value, t) +} + +func populateFieldEnum(f reflect.Value, value string, enumValMap map[string]int32) error { + cval, err := convertEnum(value, f.Type(), enumValMap) + if err != nil { + return err + } + f.Set(cval) + return nil +} + +func populateFieldEnumRepeated(f reflect.Value, values []string, enumValMap map[string]int32) error { + elemType := f.Type().Elem() + f.Set(reflect.MakeSlice(f.Type(), len(values), len(values)).Convert(f.Type())) + for i, v := range values { + result, err := convertEnum(v, elemType, enumValMap) + if err != nil { + return err + } + f.Index(i).Set(result) + } + return nil +} + +var ( + convFromType = map[reflect.Kind]reflect.Value{ + reflect.String: reflect.ValueOf(String), + reflect.Bool: reflect.ValueOf(Bool), + reflect.Float64: reflect.ValueOf(Float64), + reflect.Float32: reflect.ValueOf(Float32), + reflect.Int64: reflect.ValueOf(Int64), + reflect.Int32: reflect.ValueOf(Int32), + reflect.Uint64: reflect.ValueOf(Uint64), + reflect.Uint32: reflect.ValueOf(Uint32), + reflect.Slice: reflect.ValueOf(Bytes), + } +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel new file mode 100644 index 000000000..7109d7932 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/BUILD.bazel @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +package(default_visibility = ["//visibility:public"]) + +go_library( + name = "go_default_library", + srcs = [ + "doc.go", + "pattern.go", + "readerfactory.go", + "trie.go", + ], + importpath = "github.com/grpc-ecosystem/grpc-gateway/utilities", +) + +go_test( + name = "go_default_test", + size = "small", + srcs = ["trie_test.go"], + embed = [":go_default_library"], +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go new file mode 100644 index 000000000..cf79a4d58 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/doc.go @@ -0,0 +1,2 @@ +// Package utilities provides members for internal use in grpc-gateway. +package utilities diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go new file mode 100644 index 000000000..dfe7de486 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/pattern.go @@ -0,0 +1,22 @@ +package utilities + +// An OpCode is a opcode of compiled path patterns. +type OpCode int + +// These constants are the valid values of OpCode. +const ( + // OpNop does nothing + OpNop = OpCode(iota) + // OpPush pushes a component to stack + OpPush + // OpLitPush pushes a component to stack if it matches to the literal + OpLitPush + // OpPushM concatenates the remaining components and pushes it to stack + OpPushM + // OpConcatN pops N items from stack, concatenates them and pushes it back to stack + OpConcatN + // OpCapture pops an item and binds it to the variable + OpCapture + // OpEnd is the least positive invalid opcode. + OpEnd +) diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go new file mode 100644 index 000000000..6dd385466 --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/readerfactory.go @@ -0,0 +1,20 @@ +package utilities + +import ( + "bytes" + "io" + "io/ioutil" +) + +// IOReaderFactory takes in an io.Reader and returns a function that will allow you to create a new reader that begins +// at the start of the stream +func IOReaderFactory(r io.Reader) (func() io.Reader, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + return func() io.Reader { + return bytes.NewReader(b) + }, nil +} diff --git a/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go new file mode 100644 index 000000000..c2b7b30dd --- /dev/null +++ b/vendor/github.com/grpc-ecosystem/grpc-gateway/utilities/trie.go @@ -0,0 +1,177 @@ +package utilities + +import ( + "sort" +) + +// DoubleArray is a Double Array implementation of trie on sequences of strings. +type DoubleArray struct { + // Encoding keeps an encoding from string to int + Encoding map[string]int + // Base is the base array of Double Array + Base []int + // Check is the check array of Double Array + Check []int +} + +// NewDoubleArray builds a DoubleArray from a set of sequences of strings. +func NewDoubleArray(seqs [][]string) *DoubleArray { + da := &DoubleArray{Encoding: make(map[string]int)} + if len(seqs) == 0 { + return da + } + + encoded := registerTokens(da, seqs) + sort.Sort(byLex(encoded)) + + root := node{row: -1, col: -1, left: 0, right: len(encoded)} + addSeqs(da, encoded, 0, root) + + for i := len(da.Base); i > 0; i-- { + if da.Check[i-1] != 0 { + da.Base = da.Base[:i] + da.Check = da.Check[:i] + break + } + } + return da +} + +func registerTokens(da *DoubleArray, seqs [][]string) [][]int { + var result [][]int + for _, seq := range seqs { + var encoded []int + for _, token := range seq { + if _, ok := da.Encoding[token]; !ok { + da.Encoding[token] = len(da.Encoding) + } + encoded = append(encoded, da.Encoding[token]) + } + result = append(result, encoded) + } + for i := range result { + result[i] = append(result[i], len(da.Encoding)) + } + return result +} + +type node struct { + row, col int + left, right int +} + +func (n node) value(seqs [][]int) int { + return seqs[n.row][n.col] +} + +func (n node) children(seqs [][]int) []*node { + var result []*node + lastVal := int(-1) + last := new(node) + for i := n.left; i < n.right; i++ { + if lastVal == seqs[i][n.col+1] { + continue + } + last.right = i + last = &node{ + row: i, + col: n.col + 1, + left: i, + } + result = append(result, last) + } + last.right = n.right + return result +} + +func addSeqs(da *DoubleArray, seqs [][]int, pos int, n node) { + ensureSize(da, pos) + + children := n.children(seqs) + var i int + for i = 1; ; i++ { + ok := func() bool { + for _, child := range children { + code := child.value(seqs) + j := i + code + ensureSize(da, j) + if da.Check[j] != 0 { + return false + } + } + return true + }() + if ok { + break + } + } + da.Base[pos] = i + for _, child := range children { + code := child.value(seqs) + j := i + code + da.Check[j] = pos + 1 + } + terminator := len(da.Encoding) + for _, child := range children { + code := child.value(seqs) + if code == terminator { + continue + } + j := i + code + addSeqs(da, seqs, j, *child) + } +} + +func ensureSize(da *DoubleArray, i int) { + for i >= len(da.Base) { + da.Base = append(da.Base, make([]int, len(da.Base)+1)...) + da.Check = append(da.Check, make([]int, len(da.Check)+1)...) + } +} + +type byLex [][]int + +func (l byLex) Len() int { return len(l) } +func (l byLex) Swap(i, j int) { l[i], l[j] = l[j], l[i] } +func (l byLex) Less(i, j int) bool { + si := l[i] + sj := l[j] + var k int + for k = 0; k < len(si) && k < len(sj); k++ { + if si[k] < sj[k] { + return true + } + if si[k] > sj[k] { + return false + } + } + if k < len(sj) { + return true + } + return false +} + +// HasCommonPrefix determines if any sequence in the DoubleArray is a prefix of the given sequence. +func (da *DoubleArray) HasCommonPrefix(seq []string) bool { + if len(da.Base) == 0 { + return false + } + + var i int + for _, t := range seq { + code, ok := da.Encoding[t] + if !ok { + break + } + j := da.Base[i] + code + if len(da.Check) <= j || da.Check[j] != i+1 { + break + } + i = j + } + j := da.Base[i] + len(da.Encoding) + if len(da.Check) <= j || da.Check[j] != i+1 { + return false + } + return true +} diff --git a/vendor/github.com/hashicorp/golang-lru/LICENSE b/vendor/github.com/hashicorp/golang-lru/LICENSE new file mode 100644 index 000000000..be2cc4dfb --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/LICENSE @@ -0,0 +1,362 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go new file mode 100644 index 000000000..a86c8539e --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go @@ -0,0 +1,177 @@ +package simplelru + +import ( + "container/list" + "errors" +) + +// EvictCallback is used to get a callback when a cache entry is evicted +type EvictCallback func(key interface{}, value interface{}) + +// LRU implements a non-thread safe fixed size LRU cache +type LRU struct { + size int + evictList *list.List + items map[interface{}]*list.Element + onEvict EvictCallback +} + +// entry is used to hold a value in the evictList +type entry struct { + key interface{} + value interface{} +} + +// NewLRU constructs an LRU of the given size +func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { + if size <= 0 { + return nil, errors.New("Must provide a positive size") + } + c := &LRU{ + size: size, + evictList: list.New(), + items: make(map[interface{}]*list.Element), + onEvict: onEvict, + } + return c, nil +} + +// Purge is used to completely clear the cache. +func (c *LRU) Purge() { + for k, v := range c.items { + if c.onEvict != nil { + c.onEvict(k, v.Value.(*entry).value) + } + delete(c.items, k) + } + c.evictList.Init() +} + +// Add adds a value to the cache. Returns true if an eviction occurred. +func (c *LRU) Add(key, value interface{}) (evicted bool) { + // Check for existing item + if ent, ok := c.items[key]; ok { + c.evictList.MoveToFront(ent) + ent.Value.(*entry).value = value + return false + } + + // Add new item + ent := &entry{key, value} + entry := c.evictList.PushFront(ent) + c.items[key] = entry + + evict := c.evictList.Len() > c.size + // Verify size not exceeded + if evict { + c.removeOldest() + } + return evict +} + +// Get looks up a key's value from the cache. +func (c *LRU) Get(key interface{}) (value interface{}, ok bool) { + if ent, ok := c.items[key]; ok { + c.evictList.MoveToFront(ent) + if ent.Value.(*entry) == nil { + return nil, false + } + return ent.Value.(*entry).value, true + } + return +} + +// Contains checks if a key is in the cache, without updating the recent-ness +// or deleting it for being stale. +func (c *LRU) Contains(key interface{}) (ok bool) { + _, ok = c.items[key] + return ok +} + +// Peek returns the key value (or undefined if not found) without updating +// the "recently used"-ness of the key. +func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) { + var ent *list.Element + if ent, ok = c.items[key]; ok { + return ent.Value.(*entry).value, true + } + return nil, ok +} + +// Remove removes the provided key from the cache, returning if the +// key was contained. +func (c *LRU) Remove(key interface{}) (present bool) { + if ent, ok := c.items[key]; ok { + c.removeElement(ent) + return true + } + return false +} + +// RemoveOldest removes the oldest item from the cache. +func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { + ent := c.evictList.Back() + if ent != nil { + c.removeElement(ent) + kv := ent.Value.(*entry) + return kv.key, kv.value, true + } + return nil, nil, false +} + +// GetOldest returns the oldest entry +func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { + ent := c.evictList.Back() + if ent != nil { + kv := ent.Value.(*entry) + return kv.key, kv.value, true + } + return nil, nil, false +} + +// Keys returns a slice of the keys in the cache, from oldest to newest. +func (c *LRU) Keys() []interface{} { + keys := make([]interface{}, len(c.items)) + i := 0 + for ent := c.evictList.Back(); ent != nil; ent = ent.Prev() { + keys[i] = ent.Value.(*entry).key + i++ + } + return keys +} + +// Len returns the number of items in the cache. +func (c *LRU) Len() int { + return c.evictList.Len() +} + +// Resize changes the cache size. +func (c *LRU) Resize(size int) (evicted int) { + diff := c.Len() - size + if diff < 0 { + diff = 0 + } + for i := 0; i < diff; i++ { + c.removeOldest() + } + c.size = size + return diff +} + +// removeOldest removes the oldest item from the cache. +func (c *LRU) removeOldest() { + ent := c.evictList.Back() + if ent != nil { + c.removeElement(ent) + } +} + +// removeElement is used to remove a given list element from the cache +func (c *LRU) removeElement(e *list.Element) { + c.evictList.Remove(e) + kv := e.Value.(*entry) + delete(c.items, kv.key) + if c.onEvict != nil { + c.onEvict(kv.key, kv.value) + } +} diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go new file mode 100644 index 000000000..92d70934d --- /dev/null +++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go @@ -0,0 +1,39 @@ +package simplelru + +// LRUCache is the interface for simple LRU cache. +type LRUCache interface { + // Adds a value to the cache, returns true if an eviction occurred and + // updates the "recently used"-ness of the key. + Add(key, value interface{}) bool + + // Returns key's value from the cache and + // updates the "recently used"-ness of the key. #value, isFound + Get(key interface{}) (value interface{}, ok bool) + + // Checks if a key exists in cache without updating the recent-ness. + Contains(key interface{}) (ok bool) + + // Returns key's value without updating the "recently used"-ness of the key. + Peek(key interface{}) (value interface{}, ok bool) + + // Removes a key from the cache. + Remove(key interface{}) bool + + // Removes the oldest entry from cache. + RemoveOldest() (interface{}, interface{}, bool) + + // Returns the oldest entry from the cache. #key, value, isFound + GetOldest() (interface{}, interface{}, bool) + + // Returns a slice of the keys in the cache, from oldest to newest. + Keys() []interface{} + + // Returns the number of items in the cache. + Len() int + + // Clears all cache entries. + Purge() + + // Resizes cache, returning number evicted + Resize(int) int +} diff --git a/vendor/github.com/iij/doapi/LICENSE.md b/vendor/github.com/iij/doapi/LICENSE.md new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/vendor/github.com/iij/doapi/LICENSE.md @@ -0,0 +1,201 @@ + 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. diff --git a/vendor/github.com/iij/doapi/README.md b/vendor/github.com/iij/doapi/README.md new file mode 100644 index 000000000..7eac75cfd --- /dev/null +++ b/vendor/github.com/iij/doapi/README.md @@ -0,0 +1,39 @@ +# Golang binding for DO API + +DO is IIJ DNS outsource service. + +## Install + +- go get -u github.com/iij/doapi + +# Usage for Golang users + +```go +package main + +// Usage: +// export IIJAPI_ACCESS_KEY= +// export IIJAPI_SECRET_KEY= +// export DOSERVICECODE= + +import ( + "log" + "os" + + "github.com/iij/doapi" + "github.com/iij/doapi/protocol" +) + +func main() { + api := doapi.NewAPI(os.Getenv("IIJAPI_ACCESS_KEY"), os.Getenv("IIJAPI_SECRET_KEY")) + + // List zones + request := protocol.ZoneListGet{ DoServiceCode: os.Getenv("DOSERVICECODE"), } + response := protocol.ZoneListGetResponse{} + if err := doapi.Call(*api, request, &response); err == nil { + for _, zone := range response.ZoneList { + log.Println("zone", zone) + } + } +} +``` diff --git a/vendor/github.com/iij/doapi/api.go b/vendor/github.com/iij/doapi/api.go new file mode 100644 index 000000000..796e06680 --- /dev/null +++ b/vendor/github.com/iij/doapi/api.go @@ -0,0 +1,170 @@ +// Package doapi : DO APIクライアントモジュール +package doapi + +import ( + "bytes" + "crypto/hmac" + "crypto/sha1" + "crypto/sha256" + "crypto/tls" + "encoding/base64" + "encoding/json" + "fmt" + "hash" + "io" + "net/http" + "net/url" + "sort" + "strings" + "time" + + log "github.com/sirupsen/logrus" +) + +const ( + HmacSHA1 = "HmacSHA1" + HmacSHA256 = "HmacSHA256" + SignatureVersion2 = "2" + APIVersion = "20140601" + EndpointJSON = "https://do.api.iij.jp/" + // EndpointJSON = "http://localhost:9999/" + TimeLayout = "2006-01-02T15:04:05Z" + PostContentType = "application/json" +) + +// API の呼び出し先に関連する構造 +type API struct { + AccessKey string + SecretKey string + Endpoint string + SignMethod string + Expires time.Duration + Insecure bool +} + +// NewAPI API構造体のコンストラクタ +func NewAPI(accesskey, secretkey string) *API { + dur, _ := time.ParseDuration("1h") + return &API{AccessKey: accesskey, + SecretKey: secretkey, + Endpoint: EndpointJSON, + SignMethod: HmacSHA256, + Expires: dur, + } +} + +func convert1(r byte) string { + passchar := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_~.-" + if strings.ContainsRune(passchar, rune(r)) { + return string(r) + } + return fmt.Sprintf("%%%02X", r) +} + +// CustomEscape escape string +func CustomEscape(v string) string { + res := "" + for _, c := range []byte(v) { + res += convert1(c) + } + return res +} + +// String2Sign get string to calculate signature +func String2Sign(method string, header http.Header, param url.URL) string { + var keys []string + ctflag := false + for k := range header { + hdr := strings.ToLower(k) + if strings.HasPrefix(hdr, "x-iijapi-") { + keys = append(keys, hdr) + } else if hdr == "content-type" || hdr == "content-md5" { + keys = append(keys, hdr) + ctflag = true + } + } + sort.Strings(keys) + var target []string + target = append(target, method) + target = append(target, "") + if !ctflag { + target = append(target, "") + } + for _, k := range keys { + if k == "content-type" || k == "content-md5" { + target = append(target, header.Get(k)) + } else { + target = append(target, k+":"+header.Get(k)) + } + } + target = append(target, param.Path) + return strings.Join(target, "\n") +} + +// Sign get signature string +func (a API) Sign(method string, header http.Header, param url.URL, signmethod string) http.Header { + header.Set("x-iijapi-Expire", time.Now().Add(a.Expires).UTC().Format(TimeLayout)) + header.Set("x-iijapi-SignatureMethod", signmethod) + header.Set("x-iijapi-SignatureVersion", SignatureVersion2) + tgtstr := String2Sign(method, header, param) + var hfn func() hash.Hash + switch signmethod { + case HmacSHA1: + hfn = sha1.New + case HmacSHA256: + hfn = sha256.New + } + mac := hmac.New(hfn, []byte(a.SecretKey)) + io.WriteString(mac, tgtstr) + macstr := mac.Sum(nil) + header.Set("Authorization", "IIJAPI "+a.AccessKey+":"+base64.StdEncoding.EncodeToString(macstr)) + return header +} + +// Get : low-level Get +func (a API) Get(param url.URL) (resp *http.Response, err error) { + return a.PostSome("GET", param, nil) +} + +// PostSome : low-level Call +func (a API) PostSome(method string, param url.URL, body interface{}) (resp *http.Response, err error) { + cl := http.Client{} + if a.Insecure { + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + cl.Transport = tr + } + log.Debug("param", param) + var buf *bytes.Buffer + if body != nil { + var bufb []byte + bufb, err = json.Marshal(body) + if err != nil { + return nil, err + } + if len(bufb) > 2 { + log.Debug("call with body", method, string(bufb)) + buf = bytes.NewBuffer(bufb) + } else { + // string(bufb)=="{}" + log.Debug("call without body(empty)", method) + buf = bytes.NewBufferString("") + body = nil + } + } else { + log.Debug("call without body(nil)", method) + buf = bytes.NewBufferString("") + } + req, err := http.NewRequest(method, param.String(), buf) + if err != nil { + return nil, err + } + if body != nil { + req.Header.Add("content-type", PostContentType) + } + req.Header = a.Sign(method, req.Header, param, HmacSHA256) + log.Debug("sign", req.Header) + resp, err = cl.Do(req) + return +} diff --git a/vendor/github.com/iij/doapi/parse.go b/vendor/github.com/iij/doapi/parse.go new file mode 100644 index 000000000..61401e33e --- /dev/null +++ b/vendor/github.com/iij/doapi/parse.go @@ -0,0 +1,267 @@ +package doapi + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "strings" + "text/template" + + log "github.com/sirupsen/logrus" + + "github.com/iij/doapi/protocol" +) + +func execTemplate(name string, tmplstr string, arg interface{}) string { + tmpl, err := template.New(name).Parse(tmplstr) + if err != nil { + panic(err) + } + buf := new(bytes.Buffer) + if err = tmpl.Execute(buf, arg); err != nil { + panic(err) + } + return buf.String() +} + +// GetPath APIのURIのパス部分を求める +func GetPath(arg protocol.CommonArg) string { + return "/r/" + APIVersion + execTemplate(arg.APIName(), arg.URI(), arg) +} + +// GetParam APIのクエリストリング部分を求める +func GetParam(api API, arg protocol.CommonArg) *url.URL { + param, err := url.Parse(api.Endpoint) + if err != nil { + panic(err) + } + param.Path = GetPath(arg) + q := param.Query() + _, toQuery, _ := ArgumentListType(arg) + typs := reflect.TypeOf(arg) + vals := reflect.ValueOf(arg) + for _, key := range toQuery { + if _, flag := typs.FieldByName(key); !flag { + log.Info("no field", key) + continue + } + if val := vals.FieldByName(key).String(); len(val) != 0 { + q.Set(key, val) + } + } + param.RawQuery = q.Encode() + return param +} + +// GetBody API呼び出しのリクエストボディ(JSON文字列)を求める +func GetBody(arg protocol.CommonArg) string { + b, err := json.Marshal(arg) + if err != nil { + panic(err) + } + return string(b) +} + +// Call API呼び出しを実行し、レスポンスを得る +func Call(api API, arg protocol.CommonArg, resp interface{}) (err error) { + if err = Validate(arg); err != nil { + return + } + var res *http.Response + param := GetParam(api, arg) + log.Debug("method", arg.Method(), "param", param, "arg", arg) + if res, err = api.PostSome(arg.Method(), *param, arg); err != nil { + log.Error("PostSome", err) + return + } + log.Debug("res", res, "err", err) + var b []byte + if b, err = ioutil.ReadAll(res.Body); err != nil { + log.Error("ioutil.ReadAll", err) + return + } + log.Debug("data", string(b)) + if err = json.Unmarshal(b, &resp); err != nil { + log.Error("json.Unmarshal", err) + return + } + var cresp = protocol.CommonResponse{} + err = json.Unmarshal(b, &cresp) + if err == nil && cresp.ErrorResponse.ErrorType != "" { + return fmt.Errorf("%s: %s", cresp.ErrorResponse.ErrorType, cresp.ErrorResponse.ErrorMessage) + } + return +} + +// Validate APIの必須引数が入っているかどうかをチェック +func Validate(arg protocol.CommonArg) error { + var res []string + typs := reflect.TypeOf(arg) + vals := reflect.ValueOf(arg) + for i := 0; i < typs.NumField(); i++ { + fld := typs.Field(i) + tagstrJSON := fld.Tag.Get("json") + tagstrP2 := fld.Tag.Get("p2pub") + if strings.Contains(tagstrJSON, "omitempty") { + // optional argument + continue + } + if strings.Contains(tagstrP2, "query") { + // optional argument + continue + } + if val := vals.Field(i).String(); len(val) == 0 { + res = append(res, fld.Name) + } + } + if len(res) != 0 { + return fmt.Errorf("missing arguments: %+v", res) + } + return nil +} + +// ArgumentList API引数のリストを求める。必須とオプションに分類 +func ArgumentList(arg protocol.CommonArg) (required, optional []string) { + typs := reflect.TypeOf(arg) + for i := 0; i < typs.NumField(); i++ { + fld := typs.Field(i) + tagstrJSON := fld.Tag.Get("json") + tagstrP2 := fld.Tag.Get("p2pub") + if strings.Contains(tagstrJSON, "omitempty") || strings.Contains(tagstrP2, "query") { + optional = append(optional, fld.Name) + } else { + required = append(required, fld.Name) + } + } + return +} + +// ArgumentListType API引数のリストを求める。URI埋め込み、クエリストリング、JSONに分類 +func ArgumentListType(arg protocol.CommonArg) (toURI, toQuery, toJSON []string) { + typs := reflect.TypeOf(arg) + for i := 0; i < typs.NumField(); i++ { + fld := typs.Field(i) + tagstrJSON := fld.Tag.Get("json") + tagstrP2 := fld.Tag.Get("p2pub") + if strings.Contains(tagstrP2, "query") { + toQuery = append(toQuery, fld.Name) + } else if strings.HasPrefix(tagstrJSON, "-") { + toURI = append(toURI, fld.Name) + } else { + toJSON = append(toJSON, fld.Name) + } + } + return +} + +func argumentAltKeyList(arg protocol.CommonArg) (toAltQuery, toAltJSON map[string]string) { + toAltQuery = make(map[string]string) + toAltJSON = make(map[string]string) + typs := reflect.TypeOf(arg) + for i := 0; i < typs.NumField(); i++ { + fld := typs.Field(i) + tagstrJSON := fld.Tag.Get("json") + tagstrP2 := fld.Tag.Get("p2pub") + altKey := strings.Split(tagstrJSON, ",")[0] + if altKey == "" || altKey == "-" { + continue + } + if strings.Contains(tagstrP2, "query") { + toAltQuery[fld.Name] = altKey + } else { + toAltJSON[fld.Name] = altKey + } + } + return +} + +// ValidateMap APIの必須引数が入っているかどうかをチェック +func ValidateMap(name string, data map[string]string) error { + var res []string + typs := protocol.TypeMap[name] + for i := 0; i < typs.NumField(); i++ { + fld := typs.Field(i) + tagstrJSON := fld.Tag.Get("json") + tagstrP2 := fld.Tag.Get("p2pub") + if strings.Contains(tagstrJSON, "omitempty") { + // optional argument + continue + } + if strings.Contains(tagstrP2, "query") { + // optional argument + continue + } + if data[fld.Name] == "" { + res = append(res, fld.Name) + } + } + if len(res) != 0 { + return fmt.Errorf("missing arguments: %+v", res) + } + return nil +} + +// CallWithMap API呼び出しを実行する。引数と戻り値が構造体ではなくmap +func CallWithMap(api API, name string, data map[string]string, resp map[string]interface{}) error { + if err := ValidateMap(name, data); err != nil { + return err + } + argt := protocol.TypeMap[name] + arg := reflect.Zero(argt).Interface().(protocol.CommonArg) + var res *http.Response + param, err := url.Parse(api.Endpoint) + if err != nil { + panic(err) + } + param.Path = "/r/" + APIVersion + execTemplate(name, arg.URI(), data) + q := param.Query() + _, toQuery, toJSON := ArgumentListType(arg) + log.Debug("query", toQuery, "json", toJSON, "path", param.Path) + toAltQuery, toAltJSON := argumentAltKeyList(arg) + log.Debug("query altkey - ", toAltQuery, " json altkey - ", toAltJSON) + var jsonmap = map[string]interface{}{} + for _, v := range toJSON { + if len(data[v]) != 0 { + if altkey, ok := toAltJSON[v]; ok { + jsonmap[altkey] = data[v] + } else { + jsonmap[v] = data[v] + } + } + } + for _, v := range toQuery { + if len(data[v]) != 0 { + if altkey, ok := toAltQuery[v]; ok { + q.Set(altkey, data[v]) + } else { + q.Set(v, data[v]) + } + } + } + param.RawQuery = q.Encode() + if res, err = api.PostSome(arg.Method(), *param, jsonmap); err != nil { + log.Error("PostSome", err) + return err + } + log.Debug("res", res) + var b []byte + if b, err = ioutil.ReadAll(res.Body); err != nil { + log.Error("ioutil.ReadAll", err) + return err + } + log.Debug("data", string(b)) + if err = json.Unmarshal(b, &resp); err != nil { + log.Error("json.Unmarshal", err) + return err + } + if val, ok := resp["ErrorResponse"]; ok { + errstr := execTemplate("ErrorResponse", "{{.ErrorType}}: {{.ErrorMessage}}", val) + return errors.New(errstr) + } + return nil +} diff --git a/vendor/github.com/iij/doapi/protocol/Commit.go b/vendor/github.com/iij/doapi/protocol/Commit.go new file mode 100644 index 000000000..2b23bb856 --- /dev/null +++ b/vendor/github.com/iij/doapi/protocol/Commit.go @@ -0,0 +1,44 @@ +package protocol + +import ( + "reflect" +) + +// Commit +type Commit struct { + DoServiceCode string `json:"-"` // DO契約のサービスコード(do########) +} + +// URI /{{.DoServiceCode}}/commit.json +func (t Commit) URI() string { + return "/{{.DoServiceCode}}/commit.json" +} + +// APIName Commit +func (t Commit) APIName() string { + return "Commit" +} + +// Method PUT +func (t Commit) Method() string { + return "PUT" +} + +// http://manual.iij.jp/dns/doapi/754632.html +func (t Commit) Document() string { + return "http://manual.iij.jp/dns/doapi/754632.html" +} + +// JPName PUT Commit +func (t Commit) JPName() string { + return "PUT commit" +} +func init() { + APIlist = append(APIlist, Commit{}) + TypeMap["Commit"] = reflect.TypeOf(Commit{}) +} + +// CommitResponse PUT Commitのレスポンス +type CommitResponse struct { + *CommonResponse +} diff --git a/vendor/github.com/iij/doapi/protocol/RecordAdd.go b/vendor/github.com/iij/doapi/protocol/RecordAdd.go new file mode 100644 index 000000000..0f165b098 --- /dev/null +++ b/vendor/github.com/iij/doapi/protocol/RecordAdd.go @@ -0,0 +1,51 @@ +package protocol + +import ( + "reflect" +) + +// RecordAdd POST record (同期) +// http://manual.iij.jp/dns/doapi/754517.html +type RecordAdd struct { + DoServiceCode string `json:"-"` // DO契約のサービスコード(do########) + ZoneName string `json:"-"` // Zone Name + Owner string // owner of record + TTL string // TTL of record + RecordType string // type of record + RData string // data of record +} + +// URI /:GisServiceCode/fw-lbs/:IflServiceCode/filters/:IpVersion/:Direction.json +func (t RecordAdd) URI() string { + return "/{{.DoServiceCode}}/{{.ZoneName}}/record.json" +} + +// APIName RecordAdd +func (t RecordAdd) APIName() string { + return "RecordAdd" +} + +// Method POST +func (t RecordAdd) Method() string { + return "POST" +} + +// http://manual.iij.jp/dns/doapi/754517.html +func (t RecordAdd) Document() string { + return "http://manual.iij.jp/dns/doapi/754517.html" +} + +// JPName POST record +func (t RecordAdd) JPName() string { + return "POST record" +} +func init() { + APIlist = append(APIlist, RecordAdd{}) + TypeMap["RecordAdd"] = reflect.TypeOf(RecordAdd{}) +} + +// RecordAddResponse POST recordのレスポンス +type RecordAddResponse struct { + *CommonResponse + Record ResourceRecord +} diff --git a/vendor/github.com/iij/doapi/protocol/RecordDelete.go b/vendor/github.com/iij/doapi/protocol/RecordDelete.go new file mode 100644 index 000000000..5d087df3f --- /dev/null +++ b/vendor/github.com/iij/doapi/protocol/RecordDelete.go @@ -0,0 +1,47 @@ +package protocol + +import ( + "reflect" +) + +// RecordDelete DELETE record +// http://manual.iij.jp/dns/doapi/754525.html +type RecordDelete struct { + DoServiceCode string `json:"-"` // DO契約のサービスコード(do########) + ZoneName string `json:"-"` // Zone Name + RecordID string `json:"-"` // Record ID +} + +// URI /{{.DoServiceCode}}/{{.ZoneName}}/record/{{.RecordID}}.json +func (t RecordDelete) URI() string { + return "/{{.DoServiceCode}}/{{.ZoneName}}/record/{{.RecordID}}.json" +} + +// APIName RecordDelete +func (t RecordDelete) APIName() string { + return "RecordDelete" +} + +// Method DELETE +func (t RecordDelete) Method() string { + return "DELETE" +} + +// http://manual.iij.jp/dns/doapi/754525.html +func (t RecordDelete) Document() string { + return "http://manual.iij.jp/dns/doapi/754525.html" +} + +// JPName DELETE record +func (t RecordDelete) JPName() string { + return "DELETE record" +} +func init() { + APIlist = append(APIlist, RecordDelete{}) + TypeMap["RecordDelete"] = reflect.TypeOf(RecordDelete{}) +} + +// RecordDeleteResponse DELETE recordのレスポンス +type RecordDeleteResponse struct { + *CommonResponse +} diff --git a/vendor/github.com/iij/doapi/protocol/RecordGet.go b/vendor/github.com/iij/doapi/protocol/RecordGet.go new file mode 100644 index 000000000..051bb6595 --- /dev/null +++ b/vendor/github.com/iij/doapi/protocol/RecordGet.go @@ -0,0 +1,48 @@ +package protocol + +import ( + "reflect" +) + +// GET records +// http://manual.iij.jp/dns/doapi/754619.html +type RecordGet struct { + DoServiceCode string `json:"-"` // DO契約のサービスコード(do########) + ZoneName string `json:"-"` // ゾーン名 + RecordID string `json:"-"` // +} + +// URI /{{.DoServiceCode}}/{{.ZoneName}}/record/{{.RecordID}}.json +func (t RecordGet) URI() string { + return "/{{.DoServiceCode}}/{{.ZoneName}}/record/{{.RecordID}}.json" +} + +// APIName RecordGet +func (t RecordGet) APIName() string { + return "RecordGet" +} + +// Method GET +func (t RecordGet) Method() string { + return "GET" +} + +// http://manual.iij.jp/dns/doapi/754503.html +func (t RecordGet) Document() string { + return "http://manual.iij.jp/dns/doapi/754503.html" +} + +// JPName GET record +func (t RecordGet) JPName() string { + return "GET record" +} +func init() { + APIlist = append(APIlist, RecordGet{}) + TypeMap["RecordGet"] = reflect.TypeOf(RecordGet{}) +} + +// RecordGetResponse フィルタリングルール情報取得のレスポンス +type RecordGetResponse struct { + *CommonResponse + Record ResourceRecord +} diff --git a/vendor/github.com/iij/doapi/protocol/RecordListGet.go b/vendor/github.com/iij/doapi/protocol/RecordListGet.go new file mode 100644 index 000000000..3e4b9d637 --- /dev/null +++ b/vendor/github.com/iij/doapi/protocol/RecordListGet.go @@ -0,0 +1,47 @@ +package protocol + +import ( + "reflect" +) + +// GET records +type RecordListGet struct { + DoServiceCode string `json:"-"` // DO契約のサービスコード(do########) + ZoneName string `json:"-"` // ゾーン名 +} + +// URI /{{.DoServiceCode}}/{{.ZoneName}}/records/DETAIL.json +func (t RecordListGet) URI() string { + return "/{{.DoServiceCode}}/{{.ZoneName}}/records/DETAIL.json" +} + +// APIName RecordListGet +func (t RecordListGet) APIName() string { + return "RecordListGet" +} + +// Method GET +func (t RecordListGet) Method() string { + return "GET" +} + +// http://manual.iij.jp/dns/doapi/754619.html +func (t RecordListGet) Document() string { + return "http://manual.iij.jp/dns/doapi/754619.html" +} + +// JPName GET records +func (t RecordListGet) JPName() string { + return "GET records" +} +func init() { + APIlist = append(APIlist, RecordListGet{}) + TypeMap["RecordListGet"] = reflect.TypeOf(RecordListGet{}) +} + +// RecordListGetResponse GET recordsのレスポンス +type RecordListGetResponse struct { + *CommonResponse + RecordList []ResourceRecord + StaticRecordList []ResourceRecord +} diff --git a/vendor/github.com/iij/doapi/protocol/Reset.go b/vendor/github.com/iij/doapi/protocol/Reset.go new file mode 100644 index 000000000..0a26056fb --- /dev/null +++ b/vendor/github.com/iij/doapi/protocol/Reset.go @@ -0,0 +1,45 @@ +package protocol + +import ( + "reflect" +) + +// Reset PUT reset (同期) +type Reset struct { + DoServiceCode string `json:"-"` // DO契約のサービスコード(do########) + ZoneName string `json:"-"` // Zone name +} + +// URI /{{.DoServiceCode}}/{{.ZoneName}}/reset.json +func (t Reset) URI() string { + return "/{{.DoServiceCode}}/{{.ZoneName}}/reset.json" +} + +// APIName Reset +func (t Reset) APIName() string { + return "Reset" +} + +// Method PUT +func (t Reset) Method() string { + return "PUT" +} + +// http://manual.iij.jp/dns/doapi/754610.html +func (t Reset) Document() string { + return "http://manual.iij.jp/dns/doapi/754610.html" +} + +// JPName PUT reset +func (t Reset) JPName() string { + return "PUT Reset" +} +func init() { + APIlist = append(APIlist, Reset{}) + TypeMap["Reset"] = reflect.TypeOf(Reset{}) +} + +// ResetResponse PUT resetのレスポンス +type ResetResponse struct { + *CommonResponse +} diff --git a/vendor/github.com/iij/doapi/protocol/ZoneListGet.go b/vendor/github.com/iij/doapi/protocol/ZoneListGet.go new file mode 100644 index 000000000..20258a4db --- /dev/null +++ b/vendor/github.com/iij/doapi/protocol/ZoneListGet.go @@ -0,0 +1,45 @@ +package protocol + +import ( + "reflect" +) + +// GET zones +type ZoneListGet struct { + DoServiceCode string `json:"-"` // DO契約のサービスコード(do########) +} + +// URI /{{.DoServiceCode}}/zones.json +func (t ZoneListGet) URI() string { + return "/{{.DoServiceCode}}/zones.json" +} + +// APIName ZoneListGet +func (t ZoneListGet) APIName() string { + return "ZoneListGet" +} + +// Method GET +func (t ZoneListGet) Method() string { + return "GET" +} + +// http://manual.iij.jp/dns/doapi/754466.html +func (t ZoneListGet) Document() string { + return "http://manual.iij.jp/dns/doapi/754466.html" +} + +// JPName GET zones +func (t ZoneListGet) JPName() string { + return "GET zones" +} +func init() { + APIlist = append(APIlist, ZoneListGet{}) + TypeMap["ZoneListGet"] = reflect.TypeOf(ZoneListGet{}) +} + +// ZoneListGetResponse GET zonesのレスポンス +type ZoneListGetResponse struct { + *CommonResponse + ZoneList []string +} diff --git a/vendor/github.com/iij/doapi/protocol/common.go b/vendor/github.com/iij/doapi/protocol/common.go new file mode 100644 index 000000000..77f7a2e5c --- /dev/null +++ b/vendor/github.com/iij/doapi/protocol/common.go @@ -0,0 +1,53 @@ +package protocol + +//go:generate python doc2struct.py + +import ( + "fmt" + "reflect" +) + +type CommonArg interface { + APIName() string + Method() string + URI() string + Document() string + JPName() string +} + +type CommonResponse struct { + RequestId string + ErrorResponse struct { + RequestId string + ErrorType string + ErrorMessage string + } +} + +var APIlist []CommonArg + +var TypeMap = map[string]reflect.Type{} + +type ResourceRecord struct { + Id string `json:",omitempty"` + Status string + Owner string + TTL string + RecordType string + RData string +} + +func (r *ResourceRecord) String() string { + return fmt.Sprintf("%s %s IN %s %s", r.Owner, r.TTL, r.RecordType, r.RData) +} + +func (r *ResourceRecord) FQDN(zone string) string { + return fmt.Sprintf("%s.%s %s IN %s %s", r.Owner, zone, r.TTL, r.RecordType, r.RData) +} + +const ( + UNCAHNGED = "UNCHANGED" + ADDING = "ADDING" + DELETING = "DELETING" + DELETED = "DELETED" +) diff --git a/vendor/github.com/jmespath/go-jmespath/.gitignore b/vendor/github.com/jmespath/go-jmespath/.gitignore new file mode 100644 index 000000000..5091fb073 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/.gitignore @@ -0,0 +1,4 @@ +/jpgo +jmespath-fuzz.zip +cpu.out +go-jmespath.test diff --git a/vendor/github.com/jmespath/go-jmespath/.travis.yml b/vendor/github.com/jmespath/go-jmespath/.travis.yml new file mode 100644 index 000000000..1f9807757 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/.travis.yml @@ -0,0 +1,9 @@ +language: go + +sudo: false + +go: + - 1.4 + +install: go get -v -t ./... +script: make test diff --git a/vendor/github.com/jmespath/go-jmespath/LICENSE b/vendor/github.com/jmespath/go-jmespath/LICENSE new file mode 100644 index 000000000..b03310a91 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/LICENSE @@ -0,0 +1,13 @@ +Copyright 2015 James Saryerwinnie + +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. diff --git a/vendor/github.com/jmespath/go-jmespath/Makefile b/vendor/github.com/jmespath/go-jmespath/Makefile new file mode 100644 index 000000000..a828d2848 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/Makefile @@ -0,0 +1,44 @@ + +CMD = jpgo + +help: + @echo "Please use \`make ' where is one of" + @echo " test to run all the tests" + @echo " build to build the library and jp executable" + @echo " generate to run codegen" + + +generate: + go generate ./... + +build: + rm -f $(CMD) + go build ./... + rm -f cmd/$(CMD)/$(CMD) && cd cmd/$(CMD)/ && go build ./... + mv cmd/$(CMD)/$(CMD) . + +test: + go test -v ./... + +check: + go vet ./... + @echo "golint ./..." + @lint=`golint ./...`; \ + lint=`echo "$$lint" | grep -v "astnodetype_string.go" | grep -v "toktype_string.go"`; \ + echo "$$lint"; \ + if [ "$$lint" != "" ]; then exit 1; fi + +htmlc: + go test -coverprofile="/tmp/jpcov" && go tool cover -html="/tmp/jpcov" && unlink /tmp/jpcov + +buildfuzz: + go-fuzz-build github.com/jmespath/go-jmespath/fuzz + +fuzz: buildfuzz + go-fuzz -bin=./jmespath-fuzz.zip -workdir=fuzz/testdata + +bench: + go test -bench . -cpuprofile cpu.out + +pprof-cpu: + go tool pprof ./go-jmespath.test ./cpu.out diff --git a/vendor/github.com/jmespath/go-jmespath/README.md b/vendor/github.com/jmespath/go-jmespath/README.md new file mode 100644 index 000000000..187ef676d --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/README.md @@ -0,0 +1,7 @@ +# go-jmespath - A JMESPath implementation in Go + +[![Build Status](https://img.shields.io/travis/jmespath/go-jmespath.svg)](https://travis-ci.org/jmespath/go-jmespath) + + + +See http://jmespath.org for more info. diff --git a/vendor/github.com/jmespath/go-jmespath/api.go b/vendor/github.com/jmespath/go-jmespath/api.go new file mode 100644 index 000000000..8e26ffeec --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/api.go @@ -0,0 +1,49 @@ +package jmespath + +import "strconv" + +// JMESPath is the epresentation of a compiled JMES path query. A JMESPath is +// safe for concurrent use by multiple goroutines. +type JMESPath struct { + ast ASTNode + intr *treeInterpreter +} + +// Compile parses a JMESPath expression and returns, if successful, a JMESPath +// object that can be used to match against data. +func Compile(expression string) (*JMESPath, error) { + parser := NewParser() + ast, err := parser.Parse(expression) + if err != nil { + return nil, err + } + jmespath := &JMESPath{ast: ast, intr: newInterpreter()} + return jmespath, nil +} + +// MustCompile is like Compile but panics if the expression cannot be parsed. +// It simplifies safe initialization of global variables holding compiled +// JMESPaths. +func MustCompile(expression string) *JMESPath { + jmespath, err := Compile(expression) + if err != nil { + panic(`jmespath: Compile(` + strconv.Quote(expression) + `): ` + err.Error()) + } + return jmespath +} + +// Search evaluates a JMESPath expression against input data and returns the result. +func (jp *JMESPath) Search(data interface{}) (interface{}, error) { + return jp.intr.Execute(jp.ast, data) +} + +// Search evaluates a JMESPath expression against input data and returns the result. +func Search(expression string, data interface{}) (interface{}, error) { + intr := newInterpreter() + parser := NewParser() + ast, err := parser.Parse(expression) + if err != nil { + return nil, err + } + return intr.Execute(ast, data) +} diff --git a/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go new file mode 100644 index 000000000..1cd2d239c --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go @@ -0,0 +1,16 @@ +// generated by stringer -type astNodeType; DO NOT EDIT + +package jmespath + +import "fmt" + +const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection" + +var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307} + +func (i astNodeType) String() string { + if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) { + return fmt.Sprintf("astNodeType(%d)", i) + } + return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]] +} diff --git a/vendor/github.com/jmespath/go-jmespath/functions.go b/vendor/github.com/jmespath/go-jmespath/functions.go new file mode 100644 index 000000000..9b7cd89b4 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/functions.go @@ -0,0 +1,842 @@ +package jmespath + +import ( + "encoding/json" + "errors" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "strings" + "unicode/utf8" +) + +type jpFunction func(arguments []interface{}) (interface{}, error) + +type jpType string + +const ( + jpUnknown jpType = "unknown" + jpNumber jpType = "number" + jpString jpType = "string" + jpArray jpType = "array" + jpObject jpType = "object" + jpArrayNumber jpType = "array[number]" + jpArrayString jpType = "array[string]" + jpExpref jpType = "expref" + jpAny jpType = "any" +) + +type functionEntry struct { + name string + arguments []argSpec + handler jpFunction + hasExpRef bool +} + +type argSpec struct { + types []jpType + variadic bool +} + +type byExprString struct { + intr *treeInterpreter + node ASTNode + items []interface{} + hasError bool +} + +func (a *byExprString) Len() int { + return len(a.items) +} +func (a *byExprString) Swap(i, j int) { + a.items[i], a.items[j] = a.items[j], a.items[i] +} +func (a *byExprString) Less(i, j int) bool { + first, err := a.intr.Execute(a.node, a.items[i]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + ith, ok := first.(string) + if !ok { + a.hasError = true + return true + } + second, err := a.intr.Execute(a.node, a.items[j]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + jth, ok := second.(string) + if !ok { + a.hasError = true + return true + } + return ith < jth +} + +type byExprFloat struct { + intr *treeInterpreter + node ASTNode + items []interface{} + hasError bool +} + +func (a *byExprFloat) Len() int { + return len(a.items) +} +func (a *byExprFloat) Swap(i, j int) { + a.items[i], a.items[j] = a.items[j], a.items[i] +} +func (a *byExprFloat) Less(i, j int) bool { + first, err := a.intr.Execute(a.node, a.items[i]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + ith, ok := first.(float64) + if !ok { + a.hasError = true + return true + } + second, err := a.intr.Execute(a.node, a.items[j]) + if err != nil { + a.hasError = true + // Return a dummy value. + return true + } + jth, ok := second.(float64) + if !ok { + a.hasError = true + return true + } + return ith < jth +} + +type functionCaller struct { + functionTable map[string]functionEntry +} + +func newFunctionCaller() *functionCaller { + caller := &functionCaller{} + caller.functionTable = map[string]functionEntry{ + "length": { + name: "length", + arguments: []argSpec{ + {types: []jpType{jpString, jpArray, jpObject}}, + }, + handler: jpfLength, + }, + "starts_with": { + name: "starts_with", + arguments: []argSpec{ + {types: []jpType{jpString}}, + {types: []jpType{jpString}}, + }, + handler: jpfStartsWith, + }, + "abs": { + name: "abs", + arguments: []argSpec{ + {types: []jpType{jpNumber}}, + }, + handler: jpfAbs, + }, + "avg": { + name: "avg", + arguments: []argSpec{ + {types: []jpType{jpArrayNumber}}, + }, + handler: jpfAvg, + }, + "ceil": { + name: "ceil", + arguments: []argSpec{ + {types: []jpType{jpNumber}}, + }, + handler: jpfCeil, + }, + "contains": { + name: "contains", + arguments: []argSpec{ + {types: []jpType{jpArray, jpString}}, + {types: []jpType{jpAny}}, + }, + handler: jpfContains, + }, + "ends_with": { + name: "ends_with", + arguments: []argSpec{ + {types: []jpType{jpString}}, + {types: []jpType{jpString}}, + }, + handler: jpfEndsWith, + }, + "floor": { + name: "floor", + arguments: []argSpec{ + {types: []jpType{jpNumber}}, + }, + handler: jpfFloor, + }, + "map": { + name: "amp", + arguments: []argSpec{ + {types: []jpType{jpExpref}}, + {types: []jpType{jpArray}}, + }, + handler: jpfMap, + hasExpRef: true, + }, + "max": { + name: "max", + arguments: []argSpec{ + {types: []jpType{jpArrayNumber, jpArrayString}}, + }, + handler: jpfMax, + }, + "merge": { + name: "merge", + arguments: []argSpec{ + {types: []jpType{jpObject}, variadic: true}, + }, + handler: jpfMerge, + }, + "max_by": { + name: "max_by", + arguments: []argSpec{ + {types: []jpType{jpArray}}, + {types: []jpType{jpExpref}}, + }, + handler: jpfMaxBy, + hasExpRef: true, + }, + "sum": { + name: "sum", + arguments: []argSpec{ + {types: []jpType{jpArrayNumber}}, + }, + handler: jpfSum, + }, + "min": { + name: "min", + arguments: []argSpec{ + {types: []jpType{jpArrayNumber, jpArrayString}}, + }, + handler: jpfMin, + }, + "min_by": { + name: "min_by", + arguments: []argSpec{ + {types: []jpType{jpArray}}, + {types: []jpType{jpExpref}}, + }, + handler: jpfMinBy, + hasExpRef: true, + }, + "type": { + name: "type", + arguments: []argSpec{ + {types: []jpType{jpAny}}, + }, + handler: jpfType, + }, + "keys": { + name: "keys", + arguments: []argSpec{ + {types: []jpType{jpObject}}, + }, + handler: jpfKeys, + }, + "values": { + name: "values", + arguments: []argSpec{ + {types: []jpType{jpObject}}, + }, + handler: jpfValues, + }, + "sort": { + name: "sort", + arguments: []argSpec{ + {types: []jpType{jpArrayString, jpArrayNumber}}, + }, + handler: jpfSort, + }, + "sort_by": { + name: "sort_by", + arguments: []argSpec{ + {types: []jpType{jpArray}}, + {types: []jpType{jpExpref}}, + }, + handler: jpfSortBy, + hasExpRef: true, + }, + "join": { + name: "join", + arguments: []argSpec{ + {types: []jpType{jpString}}, + {types: []jpType{jpArrayString}}, + }, + handler: jpfJoin, + }, + "reverse": { + name: "reverse", + arguments: []argSpec{ + {types: []jpType{jpArray, jpString}}, + }, + handler: jpfReverse, + }, + "to_array": { + name: "to_array", + arguments: []argSpec{ + {types: []jpType{jpAny}}, + }, + handler: jpfToArray, + }, + "to_string": { + name: "to_string", + arguments: []argSpec{ + {types: []jpType{jpAny}}, + }, + handler: jpfToString, + }, + "to_number": { + name: "to_number", + arguments: []argSpec{ + {types: []jpType{jpAny}}, + }, + handler: jpfToNumber, + }, + "not_null": { + name: "not_null", + arguments: []argSpec{ + {types: []jpType{jpAny}, variadic: true}, + }, + handler: jpfNotNull, + }, + } + return caller +} + +func (e *functionEntry) resolveArgs(arguments []interface{}) ([]interface{}, error) { + if len(e.arguments) == 0 { + return arguments, nil + } + if !e.arguments[len(e.arguments)-1].variadic { + if len(e.arguments) != len(arguments) { + return nil, errors.New("incorrect number of args") + } + for i, spec := range e.arguments { + userArg := arguments[i] + err := spec.typeCheck(userArg) + if err != nil { + return nil, err + } + } + return arguments, nil + } + if len(arguments) < len(e.arguments) { + return nil, errors.New("Invalid arity.") + } + return arguments, nil +} + +func (a *argSpec) typeCheck(arg interface{}) error { + for _, t := range a.types { + switch t { + case jpNumber: + if _, ok := arg.(float64); ok { + return nil + } + case jpString: + if _, ok := arg.(string); ok { + return nil + } + case jpArray: + if isSliceType(arg) { + return nil + } + case jpObject: + if _, ok := arg.(map[string]interface{}); ok { + return nil + } + case jpArrayNumber: + if _, ok := toArrayNum(arg); ok { + return nil + } + case jpArrayString: + if _, ok := toArrayStr(arg); ok { + return nil + } + case jpAny: + return nil + case jpExpref: + if _, ok := arg.(expRef); ok { + return nil + } + } + } + return fmt.Errorf("Invalid type for: %v, expected: %#v", arg, a.types) +} + +func (f *functionCaller) CallFunction(name string, arguments []interface{}, intr *treeInterpreter) (interface{}, error) { + entry, ok := f.functionTable[name] + if !ok { + return nil, errors.New("unknown function: " + name) + } + resolvedArgs, err := entry.resolveArgs(arguments) + if err != nil { + return nil, err + } + if entry.hasExpRef { + var extra []interface{} + extra = append(extra, intr) + resolvedArgs = append(extra, resolvedArgs...) + } + return entry.handler(resolvedArgs) +} + +func jpfAbs(arguments []interface{}) (interface{}, error) { + num := arguments[0].(float64) + return math.Abs(num), nil +} + +func jpfLength(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if c, ok := arg.(string); ok { + return float64(utf8.RuneCountInString(c)), nil + } else if isSliceType(arg) { + v := reflect.ValueOf(arg) + return float64(v.Len()), nil + } else if c, ok := arg.(map[string]interface{}); ok { + return float64(len(c)), nil + } + return nil, errors.New("could not compute length()") +} + +func jpfStartsWith(arguments []interface{}) (interface{}, error) { + search := arguments[0].(string) + prefix := arguments[1].(string) + return strings.HasPrefix(search, prefix), nil +} + +func jpfAvg(arguments []interface{}) (interface{}, error) { + // We've already type checked the value so we can safely use + // type assertions. + args := arguments[0].([]interface{}) + length := float64(len(args)) + numerator := 0.0 + for _, n := range args { + numerator += n.(float64) + } + return numerator / length, nil +} +func jpfCeil(arguments []interface{}) (interface{}, error) { + val := arguments[0].(float64) + return math.Ceil(val), nil +} +func jpfContains(arguments []interface{}) (interface{}, error) { + search := arguments[0] + el := arguments[1] + if searchStr, ok := search.(string); ok { + if elStr, ok := el.(string); ok { + return strings.Index(searchStr, elStr) != -1, nil + } + return false, nil + } + // Otherwise this is a generic contains for []interface{} + general := search.([]interface{}) + for _, item := range general { + if item == el { + return true, nil + } + } + return false, nil +} +func jpfEndsWith(arguments []interface{}) (interface{}, error) { + search := arguments[0].(string) + suffix := arguments[1].(string) + return strings.HasSuffix(search, suffix), nil +} +func jpfFloor(arguments []interface{}) (interface{}, error) { + val := arguments[0].(float64) + return math.Floor(val), nil +} +func jpfMap(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + exp := arguments[1].(expRef) + node := exp.ref + arr := arguments[2].([]interface{}) + mapped := make([]interface{}, 0, len(arr)) + for _, value := range arr { + current, err := intr.Execute(node, value) + if err != nil { + return nil, err + } + mapped = append(mapped, current) + } + return mapped, nil +} +func jpfMax(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item > best { + best = item + } + } + return best, nil + } + // Otherwise we're dealing with a max() of strings. + items, _ := toArrayStr(arguments[0]) + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item > best { + best = item + } + } + return best, nil +} +func jpfMerge(arguments []interface{}) (interface{}, error) { + final := make(map[string]interface{}) + for _, m := range arguments { + mapped := m.(map[string]interface{}) + for key, value := range mapped { + final[key] = value + } + } + return final, nil +} +func jpfMaxBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return nil, nil + } else if len(arr) == 1 { + return arr[0], nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + switch t := start.(type) { + case float64: + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(float64) + if !ok { + return nil, errors.New("invalid type, must be number") + } + if current > bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + case string: + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(string) + if !ok { + return nil, errors.New("invalid type, must be string") + } + if current > bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + default: + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfSum(arguments []interface{}) (interface{}, error) { + items, _ := toArrayNum(arguments[0]) + sum := 0.0 + for _, item := range items { + sum += item + } + return sum, nil +} + +func jpfMin(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item < best { + best = item + } + } + return best, nil + } + items, _ := toArrayStr(arguments[0]) + if len(items) == 0 { + return nil, nil + } + if len(items) == 1 { + return items[0], nil + } + best := items[0] + for _, item := range items[1:] { + if item < best { + best = item + } + } + return best, nil +} + +func jpfMinBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return nil, nil + } else if len(arr) == 1 { + return arr[0], nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + if t, ok := start.(float64); ok { + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(float64) + if !ok { + return nil, errors.New("invalid type, must be number") + } + if current < bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + } else if t, ok := start.(string); ok { + bestVal := t + bestItem := arr[0] + for _, item := range arr[1:] { + result, err := intr.Execute(node, item) + if err != nil { + return nil, err + } + current, ok := result.(string) + if !ok { + return nil, errors.New("invalid type, must be string") + } + if current < bestVal { + bestVal = current + bestItem = item + } + } + return bestItem, nil + } else { + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfType(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if _, ok := arg.(float64); ok { + return "number", nil + } + if _, ok := arg.(string); ok { + return "string", nil + } + if _, ok := arg.([]interface{}); ok { + return "array", nil + } + if _, ok := arg.(map[string]interface{}); ok { + return "object", nil + } + if arg == nil { + return "null", nil + } + if arg == true || arg == false { + return "boolean", nil + } + return nil, errors.New("unknown type") +} +func jpfKeys(arguments []interface{}) (interface{}, error) { + arg := arguments[0].(map[string]interface{}) + collected := make([]interface{}, 0, len(arg)) + for key := range arg { + collected = append(collected, key) + } + return collected, nil +} +func jpfValues(arguments []interface{}) (interface{}, error) { + arg := arguments[0].(map[string]interface{}) + collected := make([]interface{}, 0, len(arg)) + for _, value := range arg { + collected = append(collected, value) + } + return collected, nil +} +func jpfSort(arguments []interface{}) (interface{}, error) { + if items, ok := toArrayNum(arguments[0]); ok { + d := sort.Float64Slice(items) + sort.Stable(d) + final := make([]interface{}, len(d)) + for i, val := range d { + final[i] = val + } + return final, nil + } + // Otherwise we're dealing with sort()'ing strings. + items, _ := toArrayStr(arguments[0]) + d := sort.StringSlice(items) + sort.Stable(d) + final := make([]interface{}, len(d)) + for i, val := range d { + final[i] = val + } + return final, nil +} +func jpfSortBy(arguments []interface{}) (interface{}, error) { + intr := arguments[0].(*treeInterpreter) + arr := arguments[1].([]interface{}) + exp := arguments[2].(expRef) + node := exp.ref + if len(arr) == 0 { + return arr, nil + } else if len(arr) == 1 { + return arr, nil + } + start, err := intr.Execute(node, arr[0]) + if err != nil { + return nil, err + } + if _, ok := start.(float64); ok { + sortable := &byExprFloat{intr, node, arr, false} + sort.Stable(sortable) + if sortable.hasError { + return nil, errors.New("error in sort_by comparison") + } + return arr, nil + } else if _, ok := start.(string); ok { + sortable := &byExprString{intr, node, arr, false} + sort.Stable(sortable) + if sortable.hasError { + return nil, errors.New("error in sort_by comparison") + } + return arr, nil + } else { + return nil, errors.New("invalid type, must be number of string") + } +} +func jpfJoin(arguments []interface{}) (interface{}, error) { + sep := arguments[0].(string) + // We can't just do arguments[1].([]string), we have to + // manually convert each item to a string. + arrayStr := []string{} + for _, item := range arguments[1].([]interface{}) { + arrayStr = append(arrayStr, item.(string)) + } + return strings.Join(arrayStr, sep), nil +} +func jpfReverse(arguments []interface{}) (interface{}, error) { + if s, ok := arguments[0].(string); ok { + r := []rune(s) + for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { + r[i], r[j] = r[j], r[i] + } + return string(r), nil + } + items := arguments[0].([]interface{}) + length := len(items) + reversed := make([]interface{}, length) + for i, item := range items { + reversed[length-(i+1)] = item + } + return reversed, nil +} +func jpfToArray(arguments []interface{}) (interface{}, error) { + if _, ok := arguments[0].([]interface{}); ok { + return arguments[0], nil + } + return arguments[:1:1], nil +} +func jpfToString(arguments []interface{}) (interface{}, error) { + if v, ok := arguments[0].(string); ok { + return v, nil + } + result, err := json.Marshal(arguments[0]) + if err != nil { + return nil, err + } + return string(result), nil +} +func jpfToNumber(arguments []interface{}) (interface{}, error) { + arg := arguments[0] + if v, ok := arg.(float64); ok { + return v, nil + } + if v, ok := arg.(string); ok { + conv, err := strconv.ParseFloat(v, 64) + if err != nil { + return nil, nil + } + return conv, nil + } + if _, ok := arg.([]interface{}); ok { + return nil, nil + } + if _, ok := arg.(map[string]interface{}); ok { + return nil, nil + } + if arg == nil { + return nil, nil + } + if arg == true || arg == false { + return nil, nil + } + return nil, errors.New("unknown type") +} +func jpfNotNull(arguments []interface{}) (interface{}, error) { + for _, arg := range arguments { + if arg != nil { + return arg, nil + } + } + return nil, nil +} diff --git a/vendor/github.com/jmespath/go-jmespath/interpreter.go b/vendor/github.com/jmespath/go-jmespath/interpreter.go new file mode 100644 index 000000000..13c74604c --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/interpreter.go @@ -0,0 +1,418 @@ +package jmespath + +import ( + "errors" + "reflect" + "unicode" + "unicode/utf8" +) + +/* This is a tree based interpreter. It walks the AST and directly + interprets the AST to search through a JSON document. +*/ + +type treeInterpreter struct { + fCall *functionCaller +} + +func newInterpreter() *treeInterpreter { + interpreter := treeInterpreter{} + interpreter.fCall = newFunctionCaller() + return &interpreter +} + +type expRef struct { + ref ASTNode +} + +// Execute takes an ASTNode and input data and interprets the AST directly. +// It will produce the result of applying the JMESPath expression associated +// with the ASTNode to the input data "value". +func (intr *treeInterpreter) Execute(node ASTNode, value interface{}) (interface{}, error) { + switch node.nodeType { + case ASTComparator: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + right, err := intr.Execute(node.children[1], value) + if err != nil { + return nil, err + } + switch node.value { + case tEQ: + return objsEqual(left, right), nil + case tNE: + return !objsEqual(left, right), nil + } + leftNum, ok := left.(float64) + if !ok { + return nil, nil + } + rightNum, ok := right.(float64) + if !ok { + return nil, nil + } + switch node.value { + case tGT: + return leftNum > rightNum, nil + case tGTE: + return leftNum >= rightNum, nil + case tLT: + return leftNum < rightNum, nil + case tLTE: + return leftNum <= rightNum, nil + } + case ASTExpRef: + return expRef{ref: node.children[0]}, nil + case ASTFunctionExpression: + resolvedArgs := []interface{}{} + for _, arg := range node.children { + current, err := intr.Execute(arg, value) + if err != nil { + return nil, err + } + resolvedArgs = append(resolvedArgs, current) + } + return intr.fCall.CallFunction(node.value.(string), resolvedArgs, intr) + case ASTField: + if m, ok := value.(map[string]interface{}); ok { + key := node.value.(string) + return m[key], nil + } + return intr.fieldFromStruct(node.value.(string), value) + case ASTFilterProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + sliceType, ok := left.([]interface{}) + if !ok { + if isSliceType(left) { + return intr.filterProjectionWithReflection(node, left) + } + return nil, nil + } + compareNode := node.children[2] + collected := []interface{}{} + for _, element := range sliceType { + result, err := intr.Execute(compareNode, element) + if err != nil { + return nil, err + } + if !isFalse(result) { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + } + return collected, nil + case ASTFlatten: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + sliceType, ok := left.([]interface{}) + if !ok { + // If we can't type convert to []interface{}, there's + // a chance this could still work via reflection if we're + // dealing with user provided types. + if isSliceType(left) { + return intr.flattenWithReflection(left) + } + return nil, nil + } + flattened := []interface{}{} + for _, element := range sliceType { + if elementSlice, ok := element.([]interface{}); ok { + flattened = append(flattened, elementSlice...) + } else if isSliceType(element) { + reflectFlat := []interface{}{} + v := reflect.ValueOf(element) + for i := 0; i < v.Len(); i++ { + reflectFlat = append(reflectFlat, v.Index(i).Interface()) + } + flattened = append(flattened, reflectFlat...) + } else { + flattened = append(flattened, element) + } + } + return flattened, nil + case ASTIdentity, ASTCurrentNode: + return value, nil + case ASTIndex: + if sliceType, ok := value.([]interface{}); ok { + index := node.value.(int) + if index < 0 { + index += len(sliceType) + } + if index < len(sliceType) && index >= 0 { + return sliceType[index], nil + } + return nil, nil + } + // Otherwise try via reflection. + rv := reflect.ValueOf(value) + if rv.Kind() == reflect.Slice { + index := node.value.(int) + if index < 0 { + index += rv.Len() + } + if index < rv.Len() && index >= 0 { + v := rv.Index(index) + return v.Interface(), nil + } + } + return nil, nil + case ASTKeyValPair: + return intr.Execute(node.children[0], value) + case ASTLiteral: + return node.value, nil + case ASTMultiSelectHash: + if value == nil { + return nil, nil + } + collected := make(map[string]interface{}) + for _, child := range node.children { + current, err := intr.Execute(child, value) + if err != nil { + return nil, err + } + key := child.value.(string) + collected[key] = current + } + return collected, nil + case ASTMultiSelectList: + if value == nil { + return nil, nil + } + collected := []interface{}{} + for _, child := range node.children { + current, err := intr.Execute(child, value) + if err != nil { + return nil, err + } + collected = append(collected, current) + } + return collected, nil + case ASTOrExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + matched, err = intr.Execute(node.children[1], value) + if err != nil { + return nil, err + } + } + return matched, nil + case ASTAndExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + return matched, nil + } + return intr.Execute(node.children[1], value) + case ASTNotExpression: + matched, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + if isFalse(matched) { + return true, nil + } + return false, nil + case ASTPipe: + result := value + var err error + for _, child := range node.children { + result, err = intr.Execute(child, result) + if err != nil { + return nil, err + } + } + return result, nil + case ASTProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + sliceType, ok := left.([]interface{}) + if !ok { + if isSliceType(left) { + return intr.projectWithReflection(node, left) + } + return nil, nil + } + collected := []interface{}{} + var current interface{} + for _, element := range sliceType { + current, err = intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + return collected, nil + case ASTSubexpression, ASTIndexExpression: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, err + } + return intr.Execute(node.children[1], left) + case ASTSlice: + sliceType, ok := value.([]interface{}) + if !ok { + if isSliceType(value) { + return intr.sliceWithReflection(node, value) + } + return nil, nil + } + parts := node.value.([]*int) + sliceParams := make([]sliceParam, 3) + for i, part := range parts { + if part != nil { + sliceParams[i].Specified = true + sliceParams[i].N = *part + } + } + return slice(sliceType, sliceParams) + case ASTValueProjection: + left, err := intr.Execute(node.children[0], value) + if err != nil { + return nil, nil + } + mapType, ok := left.(map[string]interface{}) + if !ok { + return nil, nil + } + values := make([]interface{}, len(mapType)) + for _, value := range mapType { + values = append(values, value) + } + collected := []interface{}{} + for _, element := range values { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + return collected, nil + } + return nil, errors.New("Unknown AST node: " + node.nodeType.String()) +} + +func (intr *treeInterpreter) fieldFromStruct(key string, value interface{}) (interface{}, error) { + rv := reflect.ValueOf(value) + first, n := utf8.DecodeRuneInString(key) + fieldName := string(unicode.ToUpper(first)) + key[n:] + if rv.Kind() == reflect.Struct { + v := rv.FieldByName(fieldName) + if !v.IsValid() { + return nil, nil + } + return v.Interface(), nil + } else if rv.Kind() == reflect.Ptr { + // Handle multiple levels of indirection? + if rv.IsNil() { + return nil, nil + } + rv = rv.Elem() + v := rv.FieldByName(fieldName) + if !v.IsValid() { + return nil, nil + } + return v.Interface(), nil + } + return nil, nil +} + +func (intr *treeInterpreter) flattenWithReflection(value interface{}) (interface{}, error) { + v := reflect.ValueOf(value) + flattened := []interface{}{} + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + if reflect.TypeOf(element).Kind() == reflect.Slice { + // Then insert the contents of the element + // slice into the flattened slice, + // i.e flattened = append(flattened, mySlice...) + elementV := reflect.ValueOf(element) + for j := 0; j < elementV.Len(); j++ { + flattened = append( + flattened, elementV.Index(j).Interface()) + } + } else { + flattened = append(flattened, element) + } + } + return flattened, nil +} + +func (intr *treeInterpreter) sliceWithReflection(node ASTNode, value interface{}) (interface{}, error) { + v := reflect.ValueOf(value) + parts := node.value.([]*int) + sliceParams := make([]sliceParam, 3) + for i, part := range parts { + if part != nil { + sliceParams[i].Specified = true + sliceParams[i].N = *part + } + } + final := []interface{}{} + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + final = append(final, element) + } + return slice(final, sliceParams) +} + +func (intr *treeInterpreter) filterProjectionWithReflection(node ASTNode, value interface{}) (interface{}, error) { + compareNode := node.children[2] + collected := []interface{}{} + v := reflect.ValueOf(value) + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + result, err := intr.Execute(compareNode, element) + if err != nil { + return nil, err + } + if !isFalse(result) { + current, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if current != nil { + collected = append(collected, current) + } + } + } + return collected, nil +} + +func (intr *treeInterpreter) projectWithReflection(node ASTNode, value interface{}) (interface{}, error) { + collected := []interface{}{} + v := reflect.ValueOf(value) + for i := 0; i < v.Len(); i++ { + element := v.Index(i).Interface() + result, err := intr.Execute(node.children[1], element) + if err != nil { + return nil, err + } + if result != nil { + collected = append(collected, result) + } + } + return collected, nil +} diff --git a/vendor/github.com/jmespath/go-jmespath/lexer.go b/vendor/github.com/jmespath/go-jmespath/lexer.go new file mode 100644 index 000000000..817900c8f --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/lexer.go @@ -0,0 +1,420 @@ +package jmespath + +import ( + "bytes" + "encoding/json" + "fmt" + "strconv" + "strings" + "unicode/utf8" +) + +type token struct { + tokenType tokType + value string + position int + length int +} + +type tokType int + +const eof = -1 + +// Lexer contains information about the expression being tokenized. +type Lexer struct { + expression string // The expression provided by the user. + currentPos int // The current position in the string. + lastWidth int // The width of the current rune. This + buf bytes.Buffer // Internal buffer used for building up values. +} + +// SyntaxError is the main error used whenever a lexing or parsing error occurs. +type SyntaxError struct { + msg string // Error message displayed to user + Expression string // Expression that generated a SyntaxError + Offset int // The location in the string where the error occurred +} + +func (e SyntaxError) Error() string { + // In the future, it would be good to underline the specific + // location where the error occurred. + return "SyntaxError: " + e.msg +} + +// HighlightLocation will show where the syntax error occurred. +// It will place a "^" character on a line below the expression +// at the point where the syntax error occurred. +func (e SyntaxError) HighlightLocation() string { + return e.Expression + "\n" + strings.Repeat(" ", e.Offset) + "^" +} + +//go:generate stringer -type=tokType +const ( + tUnknown tokType = iota + tStar + tDot + tFilter + tFlatten + tLparen + tRparen + tLbracket + tRbracket + tLbrace + tRbrace + tOr + tPipe + tNumber + tUnquotedIdentifier + tQuotedIdentifier + tComma + tColon + tLT + tLTE + tGT + tGTE + tEQ + tNE + tJSONLiteral + tStringLiteral + tCurrent + tExpref + tAnd + tNot + tEOF +) + +var basicTokens = map[rune]tokType{ + '.': tDot, + '*': tStar, + ',': tComma, + ':': tColon, + '{': tLbrace, + '}': tRbrace, + ']': tRbracket, // tLbracket not included because it could be "[]" + '(': tLparen, + ')': tRparen, + '@': tCurrent, +} + +// Bit mask for [a-zA-Z_] shifted down 64 bits to fit in a single uint64. +// When using this bitmask just be sure to shift the rune down 64 bits +// before checking against identifierStartBits. +const identifierStartBits uint64 = 576460745995190270 + +// Bit mask for [a-zA-Z0-9], 128 bits -> 2 uint64s. +var identifierTrailingBits = [2]uint64{287948901175001088, 576460745995190270} + +var whiteSpace = map[rune]bool{ + ' ': true, '\t': true, '\n': true, '\r': true, +} + +func (t token) String() string { + return fmt.Sprintf("Token{%+v, %s, %d, %d}", + t.tokenType, t.value, t.position, t.length) +} + +// NewLexer creates a new JMESPath lexer. +func NewLexer() *Lexer { + lexer := Lexer{} + return &lexer +} + +func (lexer *Lexer) next() rune { + if lexer.currentPos >= len(lexer.expression) { + lexer.lastWidth = 0 + return eof + } + r, w := utf8.DecodeRuneInString(lexer.expression[lexer.currentPos:]) + lexer.lastWidth = w + lexer.currentPos += w + return r +} + +func (lexer *Lexer) back() { + lexer.currentPos -= lexer.lastWidth +} + +func (lexer *Lexer) peek() rune { + t := lexer.next() + lexer.back() + return t +} + +// tokenize takes an expression and returns corresponding tokens. +func (lexer *Lexer) tokenize(expression string) ([]token, error) { + var tokens []token + lexer.expression = expression + lexer.currentPos = 0 + lexer.lastWidth = 0 +loop: + for { + r := lexer.next() + if identifierStartBits&(1<<(uint64(r)-64)) > 0 { + t := lexer.consumeUnquotedIdentifier() + tokens = append(tokens, t) + } else if val, ok := basicTokens[r]; ok { + // Basic single char token. + t := token{ + tokenType: val, + value: string(r), + position: lexer.currentPos - lexer.lastWidth, + length: 1, + } + tokens = append(tokens, t) + } else if r == '-' || (r >= '0' && r <= '9') { + t := lexer.consumeNumber() + tokens = append(tokens, t) + } else if r == '[' { + t := lexer.consumeLBracket() + tokens = append(tokens, t) + } else if r == '"' { + t, err := lexer.consumeQuotedIdentifier() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '\'' { + t, err := lexer.consumeRawStringLiteral() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '`' { + t, err := lexer.consumeLiteral() + if err != nil { + return tokens, err + } + tokens = append(tokens, t) + } else if r == '|' { + t := lexer.matchOrElse(r, '|', tOr, tPipe) + tokens = append(tokens, t) + } else if r == '<' { + t := lexer.matchOrElse(r, '=', tLTE, tLT) + tokens = append(tokens, t) + } else if r == '>' { + t := lexer.matchOrElse(r, '=', tGTE, tGT) + tokens = append(tokens, t) + } else if r == '!' { + t := lexer.matchOrElse(r, '=', tNE, tNot) + tokens = append(tokens, t) + } else if r == '=' { + t := lexer.matchOrElse(r, '=', tEQ, tUnknown) + tokens = append(tokens, t) + } else if r == '&' { + t := lexer.matchOrElse(r, '&', tAnd, tExpref) + tokens = append(tokens, t) + } else if r == eof { + break loop + } else if _, ok := whiteSpace[r]; ok { + // Ignore whitespace + } else { + return tokens, lexer.syntaxError(fmt.Sprintf("Unknown char: %s", strconv.QuoteRuneToASCII(r))) + } + } + tokens = append(tokens, token{tEOF, "", len(lexer.expression), 0}) + return tokens, nil +} + +// Consume characters until the ending rune "r" is reached. +// If the end of the expression is reached before seeing the +// terminating rune "r", then an error is returned. +// If no error occurs then the matching substring is returned. +// The returned string will not include the ending rune. +func (lexer *Lexer) consumeUntil(end rune) (string, error) { + start := lexer.currentPos + current := lexer.next() + for current != end && current != eof { + if current == '\\' && lexer.peek() != eof { + lexer.next() + } + current = lexer.next() + } + if lexer.lastWidth == 0 { + // Then we hit an EOF so we never reached the closing + // delimiter. + return "", SyntaxError{ + msg: "Unclosed delimiter: " + string(end), + Expression: lexer.expression, + Offset: len(lexer.expression), + } + } + return lexer.expression[start : lexer.currentPos-lexer.lastWidth], nil +} + +func (lexer *Lexer) consumeLiteral() (token, error) { + start := lexer.currentPos + value, err := lexer.consumeUntil('`') + if err != nil { + return token{}, err + } + value = strings.Replace(value, "\\`", "`", -1) + return token{ + tokenType: tJSONLiteral, + value: value, + position: start, + length: len(value), + }, nil +} + +func (lexer *Lexer) consumeRawStringLiteral() (token, error) { + start := lexer.currentPos + currentIndex := start + current := lexer.next() + for current != '\'' && lexer.peek() != eof { + if current == '\\' && lexer.peek() == '\'' { + chunk := lexer.expression[currentIndex : lexer.currentPos-1] + lexer.buf.WriteString(chunk) + lexer.buf.WriteString("'") + lexer.next() + currentIndex = lexer.currentPos + } + current = lexer.next() + } + if lexer.lastWidth == 0 { + // Then we hit an EOF so we never reached the closing + // delimiter. + return token{}, SyntaxError{ + msg: "Unclosed delimiter: '", + Expression: lexer.expression, + Offset: len(lexer.expression), + } + } + if currentIndex < lexer.currentPos { + lexer.buf.WriteString(lexer.expression[currentIndex : lexer.currentPos-1]) + } + value := lexer.buf.String() + // Reset the buffer so it can reused again. + lexer.buf.Reset() + return token{ + tokenType: tStringLiteral, + value: value, + position: start, + length: len(value), + }, nil +} + +func (lexer *Lexer) syntaxError(msg string) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: lexer.expression, + Offset: lexer.currentPos - 1, + } +} + +// Checks for a two char token, otherwise matches a single character +// token. This is used whenever a two char token overlaps a single +// char token, e.g. "||" -> tPipe, "|" -> tOr. +func (lexer *Lexer) matchOrElse(first rune, second rune, matchedType tokType, singleCharType tokType) token { + start := lexer.currentPos - lexer.lastWidth + nextRune := lexer.next() + var t token + if nextRune == second { + t = token{ + tokenType: matchedType, + value: string(first) + string(second), + position: start, + length: 2, + } + } else { + lexer.back() + t = token{ + tokenType: singleCharType, + value: string(first), + position: start, + length: 1, + } + } + return t +} + +func (lexer *Lexer) consumeLBracket() token { + // There's three options here: + // 1. A filter expression "[?" + // 2. A flatten operator "[]" + // 3. A bare rbracket "[" + start := lexer.currentPos - lexer.lastWidth + nextRune := lexer.next() + var t token + if nextRune == '?' { + t = token{ + tokenType: tFilter, + value: "[?", + position: start, + length: 2, + } + } else if nextRune == ']' { + t = token{ + tokenType: tFlatten, + value: "[]", + position: start, + length: 2, + } + } else { + t = token{ + tokenType: tLbracket, + value: "[", + position: start, + length: 1, + } + lexer.back() + } + return t +} + +func (lexer *Lexer) consumeQuotedIdentifier() (token, error) { + start := lexer.currentPos + value, err := lexer.consumeUntil('"') + if err != nil { + return token{}, err + } + var decoded string + asJSON := []byte("\"" + value + "\"") + if err := json.Unmarshal([]byte(asJSON), &decoded); err != nil { + return token{}, err + } + return token{ + tokenType: tQuotedIdentifier, + value: decoded, + position: start - 1, + length: len(decoded), + }, nil +} + +func (lexer *Lexer) consumeUnquotedIdentifier() token { + // Consume runes until we reach the end of an unquoted + // identifier. + start := lexer.currentPos - lexer.lastWidth + for { + r := lexer.next() + if r < 0 || r > 128 || identifierTrailingBits[uint64(r)/64]&(1<<(uint64(r)%64)) == 0 { + lexer.back() + break + } + } + value := lexer.expression[start:lexer.currentPos] + return token{ + tokenType: tUnquotedIdentifier, + value: value, + position: start, + length: lexer.currentPos - start, + } +} + +func (lexer *Lexer) consumeNumber() token { + // Consume runes until we reach something that's not a number. + start := lexer.currentPos - lexer.lastWidth + for { + r := lexer.next() + if r < '0' || r > '9' { + lexer.back() + break + } + } + value := lexer.expression[start:lexer.currentPos] + return token{ + tokenType: tNumber, + value: value, + position: start, + length: lexer.currentPos - start, + } +} diff --git a/vendor/github.com/jmespath/go-jmespath/parser.go b/vendor/github.com/jmespath/go-jmespath/parser.go new file mode 100644 index 000000000..1240a1755 --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/parser.go @@ -0,0 +1,603 @@ +package jmespath + +import ( + "encoding/json" + "fmt" + "strconv" + "strings" +) + +type astNodeType int + +//go:generate stringer -type astNodeType +const ( + ASTEmpty astNodeType = iota + ASTComparator + ASTCurrentNode + ASTExpRef + ASTFunctionExpression + ASTField + ASTFilterProjection + ASTFlatten + ASTIdentity + ASTIndex + ASTIndexExpression + ASTKeyValPair + ASTLiteral + ASTMultiSelectHash + ASTMultiSelectList + ASTOrExpression + ASTAndExpression + ASTNotExpression + ASTPipe + ASTProjection + ASTSubexpression + ASTSlice + ASTValueProjection +) + +// ASTNode represents the abstract syntax tree of a JMESPath expression. +type ASTNode struct { + nodeType astNodeType + value interface{} + children []ASTNode +} + +func (node ASTNode) String() string { + return node.PrettyPrint(0) +} + +// PrettyPrint will pretty print the parsed AST. +// The AST is an implementation detail and this pretty print +// function is provided as a convenience method to help with +// debugging. You should not rely on its output as the internal +// structure of the AST may change at any time. +func (node ASTNode) PrettyPrint(indent int) string { + spaces := strings.Repeat(" ", indent) + output := fmt.Sprintf("%s%s {\n", spaces, node.nodeType) + nextIndent := indent + 2 + if node.value != nil { + if converted, ok := node.value.(fmt.Stringer); ok { + // Account for things like comparator nodes + // that are enums with a String() method. + output += fmt.Sprintf("%svalue: %s\n", strings.Repeat(" ", nextIndent), converted.String()) + } else { + output += fmt.Sprintf("%svalue: %#v\n", strings.Repeat(" ", nextIndent), node.value) + } + } + lastIndex := len(node.children) + if lastIndex > 0 { + output += fmt.Sprintf("%schildren: {\n", strings.Repeat(" ", nextIndent)) + childIndent := nextIndent + 2 + for _, elem := range node.children { + output += elem.PrettyPrint(childIndent) + } + } + output += fmt.Sprintf("%s}\n", spaces) + return output +} + +var bindingPowers = map[tokType]int{ + tEOF: 0, + tUnquotedIdentifier: 0, + tQuotedIdentifier: 0, + tRbracket: 0, + tRparen: 0, + tComma: 0, + tRbrace: 0, + tNumber: 0, + tCurrent: 0, + tExpref: 0, + tColon: 0, + tPipe: 1, + tOr: 2, + tAnd: 3, + tEQ: 5, + tLT: 5, + tLTE: 5, + tGT: 5, + tGTE: 5, + tNE: 5, + tFlatten: 9, + tStar: 20, + tFilter: 21, + tDot: 40, + tNot: 45, + tLbrace: 50, + tLbracket: 55, + tLparen: 60, +} + +// Parser holds state about the current expression being parsed. +type Parser struct { + expression string + tokens []token + index int +} + +// NewParser creates a new JMESPath parser. +func NewParser() *Parser { + p := Parser{} + return &p +} + +// Parse will compile a JMESPath expression. +func (p *Parser) Parse(expression string) (ASTNode, error) { + lexer := NewLexer() + p.expression = expression + p.index = 0 + tokens, err := lexer.tokenize(expression) + if err != nil { + return ASTNode{}, err + } + p.tokens = tokens + parsed, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if p.current() != tEOF { + return ASTNode{}, p.syntaxError(fmt.Sprintf( + "Unexpected token at the end of the expresssion: %s", p.current())) + } + return parsed, nil +} + +func (p *Parser) parseExpression(bindingPower int) (ASTNode, error) { + var err error + leftToken := p.lookaheadToken(0) + p.advance() + leftNode, err := p.nud(leftToken) + if err != nil { + return ASTNode{}, err + } + currentToken := p.current() + for bindingPower < bindingPowers[currentToken] { + p.advance() + leftNode, err = p.led(currentToken, leftNode) + if err != nil { + return ASTNode{}, err + } + currentToken = p.current() + } + return leftNode, nil +} + +func (p *Parser) parseIndexExpression() (ASTNode, error) { + if p.lookahead(0) == tColon || p.lookahead(1) == tColon { + return p.parseSliceExpression() + } + indexStr := p.lookaheadToken(0).value + parsedInt, err := strconv.Atoi(indexStr) + if err != nil { + return ASTNode{}, err + } + indexNode := ASTNode{nodeType: ASTIndex, value: parsedInt} + p.advance() + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + return indexNode, nil +} + +func (p *Parser) parseSliceExpression() (ASTNode, error) { + parts := []*int{nil, nil, nil} + index := 0 + current := p.current() + for current != tRbracket && index < 3 { + if current == tColon { + index++ + p.advance() + } else if current == tNumber { + parsedInt, err := strconv.Atoi(p.lookaheadToken(0).value) + if err != nil { + return ASTNode{}, err + } + parts[index] = &parsedInt + p.advance() + } else { + return ASTNode{}, p.syntaxError( + "Expected tColon or tNumber" + ", received: " + p.current().String()) + } + current = p.current() + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTSlice, + value: parts, + }, nil +} + +func (p *Parser) match(tokenType tokType) error { + if p.current() == tokenType { + p.advance() + return nil + } + return p.syntaxError("Expected " + tokenType.String() + ", received: " + p.current().String()) +} + +func (p *Parser) led(tokenType tokType, node ASTNode) (ASTNode, error) { + switch tokenType { + case tDot: + if p.current() != tStar { + right, err := p.parseDotRHS(bindingPowers[tDot]) + return ASTNode{ + nodeType: ASTSubexpression, + children: []ASTNode{node, right}, + }, err + } + p.advance() + right, err := p.parseProjectionRHS(bindingPowers[tDot]) + return ASTNode{ + nodeType: ASTValueProjection, + children: []ASTNode{node, right}, + }, err + case tPipe: + right, err := p.parseExpression(bindingPowers[tPipe]) + return ASTNode{nodeType: ASTPipe, children: []ASTNode{node, right}}, err + case tOr: + right, err := p.parseExpression(bindingPowers[tOr]) + return ASTNode{nodeType: ASTOrExpression, children: []ASTNode{node, right}}, err + case tAnd: + right, err := p.parseExpression(bindingPowers[tAnd]) + return ASTNode{nodeType: ASTAndExpression, children: []ASTNode{node, right}}, err + case tLparen: + name := node.value + var args []ASTNode + for p.current() != tRparen { + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if p.current() == tComma { + if err := p.match(tComma); err != nil { + return ASTNode{}, err + } + } + args = append(args, expression) + } + if err := p.match(tRparen); err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTFunctionExpression, + value: name, + children: args, + }, nil + case tFilter: + return p.parseFilter(node) + case tFlatten: + left := ASTNode{nodeType: ASTFlatten, children: []ASTNode{node}} + right, err := p.parseProjectionRHS(bindingPowers[tFlatten]) + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{left, right}, + }, err + case tEQ, tNE, tGT, tGTE, tLT, tLTE: + right, err := p.parseExpression(bindingPowers[tokenType]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTComparator, + value: tokenType, + children: []ASTNode{node, right}, + }, nil + case tLbracket: + tokenType := p.current() + var right ASTNode + var err error + if tokenType == tNumber || tokenType == tColon { + right, err = p.parseIndexExpression() + if err != nil { + return ASTNode{}, err + } + return p.projectIfSlice(node, right) + } + // Otherwise this is a projection. + if err := p.match(tStar); err != nil { + return ASTNode{}, err + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + right, err = p.parseProjectionRHS(bindingPowers[tStar]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{node, right}, + }, nil + } + return ASTNode{}, p.syntaxError("Unexpected token: " + tokenType.String()) +} + +func (p *Parser) nud(token token) (ASTNode, error) { + switch token.tokenType { + case tJSONLiteral: + var parsed interface{} + err := json.Unmarshal([]byte(token.value), &parsed) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTLiteral, value: parsed}, nil + case tStringLiteral: + return ASTNode{nodeType: ASTLiteral, value: token.value}, nil + case tUnquotedIdentifier: + return ASTNode{ + nodeType: ASTField, + value: token.value, + }, nil + case tQuotedIdentifier: + node := ASTNode{nodeType: ASTField, value: token.value} + if p.current() == tLparen { + return ASTNode{}, p.syntaxErrorToken("Can't have quoted identifier as function name.", token) + } + return node, nil + case tStar: + left := ASTNode{nodeType: ASTIdentity} + var right ASTNode + var err error + if p.current() == tRbracket { + right = ASTNode{nodeType: ASTIdentity} + } else { + right, err = p.parseProjectionRHS(bindingPowers[tStar]) + } + return ASTNode{nodeType: ASTValueProjection, children: []ASTNode{left, right}}, err + case tFilter: + return p.parseFilter(ASTNode{nodeType: ASTIdentity}) + case tLbrace: + return p.parseMultiSelectHash() + case tFlatten: + left := ASTNode{ + nodeType: ASTFlatten, + children: []ASTNode{{nodeType: ASTIdentity}}, + } + right, err := p.parseProjectionRHS(bindingPowers[tFlatten]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTProjection, children: []ASTNode{left, right}}, nil + case tLbracket: + tokenType := p.current() + //var right ASTNode + if tokenType == tNumber || tokenType == tColon { + right, err := p.parseIndexExpression() + if err != nil { + return ASTNode{}, nil + } + return p.projectIfSlice(ASTNode{nodeType: ASTIdentity}, right) + } else if tokenType == tStar && p.lookahead(1) == tRbracket { + p.advance() + p.advance() + right, err := p.parseProjectionRHS(bindingPowers[tStar]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{{nodeType: ASTIdentity}, right}, + }, nil + } else { + return p.parseMultiSelectList() + } + case tCurrent: + return ASTNode{nodeType: ASTCurrentNode}, nil + case tExpref: + expression, err := p.parseExpression(bindingPowers[tExpref]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTExpRef, children: []ASTNode{expression}}, nil + case tNot: + expression, err := p.parseExpression(bindingPowers[tNot]) + if err != nil { + return ASTNode{}, err + } + return ASTNode{nodeType: ASTNotExpression, children: []ASTNode{expression}}, nil + case tLparen: + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if err := p.match(tRparen); err != nil { + return ASTNode{}, err + } + return expression, nil + case tEOF: + return ASTNode{}, p.syntaxErrorToken("Incomplete expression", token) + } + + return ASTNode{}, p.syntaxErrorToken("Invalid token: "+token.tokenType.String(), token) +} + +func (p *Parser) parseMultiSelectList() (ASTNode, error) { + var expressions []ASTNode + for { + expression, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + expressions = append(expressions, expression) + if p.current() == tRbracket { + break + } + err = p.match(tComma) + if err != nil { + return ASTNode{}, err + } + } + err := p.match(tRbracket) + if err != nil { + return ASTNode{}, err + } + return ASTNode{ + nodeType: ASTMultiSelectList, + children: expressions, + }, nil +} + +func (p *Parser) parseMultiSelectHash() (ASTNode, error) { + var children []ASTNode + for { + keyToken := p.lookaheadToken(0) + if err := p.match(tUnquotedIdentifier); err != nil { + if err := p.match(tQuotedIdentifier); err != nil { + return ASTNode{}, p.syntaxError("Expected tQuotedIdentifier or tUnquotedIdentifier") + } + } + keyName := keyToken.value + err := p.match(tColon) + if err != nil { + return ASTNode{}, err + } + value, err := p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + node := ASTNode{ + nodeType: ASTKeyValPair, + value: keyName, + children: []ASTNode{value}, + } + children = append(children, node) + if p.current() == tComma { + err := p.match(tComma) + if err != nil { + return ASTNode{}, nil + } + } else if p.current() == tRbrace { + err := p.match(tRbrace) + if err != nil { + return ASTNode{}, nil + } + break + } + } + return ASTNode{ + nodeType: ASTMultiSelectHash, + children: children, + }, nil +} + +func (p *Parser) projectIfSlice(left ASTNode, right ASTNode) (ASTNode, error) { + indexExpr := ASTNode{ + nodeType: ASTIndexExpression, + children: []ASTNode{left, right}, + } + if right.nodeType == ASTSlice { + right, err := p.parseProjectionRHS(bindingPowers[tStar]) + return ASTNode{ + nodeType: ASTProjection, + children: []ASTNode{indexExpr, right}, + }, err + } + return indexExpr, nil +} +func (p *Parser) parseFilter(node ASTNode) (ASTNode, error) { + var right, condition ASTNode + var err error + condition, err = p.parseExpression(0) + if err != nil { + return ASTNode{}, err + } + if err := p.match(tRbracket); err != nil { + return ASTNode{}, err + } + if p.current() == tFlatten { + right = ASTNode{nodeType: ASTIdentity} + } else { + right, err = p.parseProjectionRHS(bindingPowers[tFilter]) + if err != nil { + return ASTNode{}, err + } + } + + return ASTNode{ + nodeType: ASTFilterProjection, + children: []ASTNode{node, right, condition}, + }, nil +} + +func (p *Parser) parseDotRHS(bindingPower int) (ASTNode, error) { + lookahead := p.current() + if tokensOneOf([]tokType{tQuotedIdentifier, tUnquotedIdentifier, tStar}, lookahead) { + return p.parseExpression(bindingPower) + } else if lookahead == tLbracket { + if err := p.match(tLbracket); err != nil { + return ASTNode{}, err + } + return p.parseMultiSelectList() + } else if lookahead == tLbrace { + if err := p.match(tLbrace); err != nil { + return ASTNode{}, err + } + return p.parseMultiSelectHash() + } + return ASTNode{}, p.syntaxError("Expected identifier, lbracket, or lbrace") +} + +func (p *Parser) parseProjectionRHS(bindingPower int) (ASTNode, error) { + current := p.current() + if bindingPowers[current] < 10 { + return ASTNode{nodeType: ASTIdentity}, nil + } else if current == tLbracket { + return p.parseExpression(bindingPower) + } else if current == tFilter { + return p.parseExpression(bindingPower) + } else if current == tDot { + err := p.match(tDot) + if err != nil { + return ASTNode{}, err + } + return p.parseDotRHS(bindingPower) + } else { + return ASTNode{}, p.syntaxError("Error") + } +} + +func (p *Parser) lookahead(number int) tokType { + return p.lookaheadToken(number).tokenType +} + +func (p *Parser) current() tokType { + return p.lookahead(0) +} + +func (p *Parser) lookaheadToken(number int) token { + return p.tokens[p.index+number] +} + +func (p *Parser) advance() { + p.index++ +} + +func tokensOneOf(elements []tokType, token tokType) bool { + for _, elem := range elements { + if elem == token { + return true + } + } + return false +} + +func (p *Parser) syntaxError(msg string) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: p.expression, + Offset: p.lookaheadToken(0).position, + } +} + +// Create a SyntaxError based on the provided token. +// This differs from syntaxError() which creates a SyntaxError +// based on the current lookahead token. +func (p *Parser) syntaxErrorToken(msg string, t token) SyntaxError { + return SyntaxError{ + msg: msg, + Expression: p.expression, + Offset: t.position, + } +} diff --git a/vendor/github.com/jmespath/go-jmespath/toktype_string.go b/vendor/github.com/jmespath/go-jmespath/toktype_string.go new file mode 100644 index 000000000..dae79cbdf --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/toktype_string.go @@ -0,0 +1,16 @@ +// generated by stringer -type=tokType; DO NOT EDIT + +package jmespath + +import "fmt" + +const _tokType_name = "tUnknowntStartDottFiltertFlattentLparentRparentLbrackettRbrackettLbracetRbracetOrtPipetNumbertUnquotedIdentifiertQuotedIdentifiertCommatColontLTtLTEtGTtGTEtEQtNEtJSONLiteraltStringLiteraltCurrenttExpreftAndtNottEOF" + +var _tokType_index = [...]uint8{0, 8, 13, 17, 24, 32, 39, 46, 55, 64, 71, 78, 81, 86, 93, 112, 129, 135, 141, 144, 148, 151, 155, 158, 161, 173, 187, 195, 202, 206, 210, 214} + +func (i tokType) String() string { + if i < 0 || i >= tokType(len(_tokType_index)-1) { + return fmt.Sprintf("tokType(%d)", i) + } + return _tokType_name[_tokType_index[i]:_tokType_index[i+1]] +} diff --git a/vendor/github.com/jmespath/go-jmespath/util.go b/vendor/github.com/jmespath/go-jmespath/util.go new file mode 100644 index 000000000..ddc1b7d7d --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/util.go @@ -0,0 +1,185 @@ +package jmespath + +import ( + "errors" + "reflect" +) + +// IsFalse determines if an object is false based on the JMESPath spec. +// JMESPath defines false values to be any of: +// - An empty string array, or hash. +// - The boolean value false. +// - nil +func isFalse(value interface{}) bool { + switch v := value.(type) { + case bool: + return !v + case []interface{}: + return len(v) == 0 + case map[string]interface{}: + return len(v) == 0 + case string: + return len(v) == 0 + case nil: + return true + } + // Try the reflection cases before returning false. + rv := reflect.ValueOf(value) + switch rv.Kind() { + case reflect.Struct: + // A struct type will never be false, even if + // all of its values are the zero type. + return false + case reflect.Slice, reflect.Map: + return rv.Len() == 0 + case reflect.Ptr: + if rv.IsNil() { + return true + } + // If it's a pointer type, we'll try to deref the pointer + // and evaluate the pointer value for isFalse. + element := rv.Elem() + return isFalse(element.Interface()) + } + return false +} + +// ObjsEqual is a generic object equality check. +// It will take two arbitrary objects and recursively determine +// if they are equal. +func objsEqual(left interface{}, right interface{}) bool { + return reflect.DeepEqual(left, right) +} + +// SliceParam refers to a single part of a slice. +// A slice consists of a start, a stop, and a step, similar to +// python slices. +type sliceParam struct { + N int + Specified bool +} + +// Slice supports [start:stop:step] style slicing that's supported in JMESPath. +func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) { + computed, err := computeSliceParams(len(slice), parts) + if err != nil { + return nil, err + } + start, stop, step := computed[0], computed[1], computed[2] + result := []interface{}{} + if step > 0 { + for i := start; i < stop; i += step { + result = append(result, slice[i]) + } + } else { + for i := start; i > stop; i += step { + result = append(result, slice[i]) + } + } + return result, nil +} + +func computeSliceParams(length int, parts []sliceParam) ([]int, error) { + var start, stop, step int + if !parts[2].Specified { + step = 1 + } else if parts[2].N == 0 { + return nil, errors.New("Invalid slice, step cannot be 0") + } else { + step = parts[2].N + } + var stepValueNegative bool + if step < 0 { + stepValueNegative = true + } else { + stepValueNegative = false + } + + if !parts[0].Specified { + if stepValueNegative { + start = length - 1 + } else { + start = 0 + } + } else { + start = capSlice(length, parts[0].N, step) + } + + if !parts[1].Specified { + if stepValueNegative { + stop = -1 + } else { + stop = length + } + } else { + stop = capSlice(length, parts[1].N, step) + } + return []int{start, stop, step}, nil +} + +func capSlice(length int, actual int, step int) int { + if actual < 0 { + actual += length + if actual < 0 { + if step < 0 { + actual = -1 + } else { + actual = 0 + } + } + } else if actual >= length { + if step < 0 { + actual = length - 1 + } else { + actual = length + } + } + return actual +} + +// ToArrayNum converts an empty interface type to a slice of float64. +// If any element in the array cannot be converted, then nil is returned +// along with a second value of false. +func toArrayNum(data interface{}) ([]float64, bool) { + // Is there a better way to do this with reflect? + if d, ok := data.([]interface{}); ok { + result := make([]float64, len(d)) + for i, el := range d { + item, ok := el.(float64) + if !ok { + return nil, false + } + result[i] = item + } + return result, true + } + return nil, false +} + +// ToArrayStr converts an empty interface type to a slice of strings. +// If any element in the array cannot be converted, then nil is returned +// along with a second value of false. If the input data could be entirely +// converted, then the converted data, along with a second value of true, +// will be returned. +func toArrayStr(data interface{}) ([]string, bool) { + // Is there a better way to do this with reflect? + if d, ok := data.([]interface{}); ok { + result := make([]string, len(d)) + for i, el := range d { + item, ok := el.(string) + if !ok { + return nil, false + } + result[i] = item + } + return result, true + } + return nil, false +} + +func isSliceType(v interface{}) bool { + if v == nil { + return false + } + return reflect.TypeOf(v).Kind() == reflect.Slice +} diff --git a/vendor/github.com/json-iterator/go/.codecov.yml b/vendor/github.com/json-iterator/go/.codecov.yml new file mode 100644 index 000000000..955dc0be5 --- /dev/null +++ b/vendor/github.com/json-iterator/go/.codecov.yml @@ -0,0 +1,3 @@ +ignore: + - "output_tests/.*" + diff --git a/vendor/github.com/json-iterator/go/.gitignore b/vendor/github.com/json-iterator/go/.gitignore new file mode 100644 index 000000000..15556530a --- /dev/null +++ b/vendor/github.com/json-iterator/go/.gitignore @@ -0,0 +1,4 @@ +/vendor +/bug_test.go +/coverage.txt +/.idea diff --git a/vendor/github.com/json-iterator/go/.travis.yml b/vendor/github.com/json-iterator/go/.travis.yml new file mode 100644 index 000000000..449e67cd0 --- /dev/null +++ b/vendor/github.com/json-iterator/go/.travis.yml @@ -0,0 +1,14 @@ +language: go + +go: + - 1.8.x + - 1.x + +before_install: + - go get -t -v ./... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/json-iterator/go/Gopkg.lock b/vendor/github.com/json-iterator/go/Gopkg.lock new file mode 100644 index 000000000..c8a9fbb38 --- /dev/null +++ b/vendor/github.com/json-iterator/go/Gopkg.lock @@ -0,0 +1,21 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/modern-go/concurrent" + packages = ["."] + revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a" + version = "1.0.0" + +[[projects]] + name = "github.com/modern-go/reflect2" + packages = ["."] + revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd" + version = "1.0.1" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "ea54a775e5a354cb015502d2e7aa4b74230fc77e894f34a838b268c25ec8eeb8" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/json-iterator/go/Gopkg.toml b/vendor/github.com/json-iterator/go/Gopkg.toml new file mode 100644 index 000000000..313a0f887 --- /dev/null +++ b/vendor/github.com/json-iterator/go/Gopkg.toml @@ -0,0 +1,26 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + +ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"] + +[[constraint]] + name = "github.com/modern-go/reflect2" + version = "1.0.1" diff --git a/vendor/github.com/json-iterator/go/LICENSE b/vendor/github.com/json-iterator/go/LICENSE new file mode 100644 index 000000000..2cf4f5ab2 --- /dev/null +++ b/vendor/github.com/json-iterator/go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 json-iterator + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/json-iterator/go/README.md b/vendor/github.com/json-iterator/go/README.md new file mode 100644 index 000000000..54d5afe95 --- /dev/null +++ b/vendor/github.com/json-iterator/go/README.md @@ -0,0 +1,91 @@ +[![Sourcegraph](https://sourcegraph.com/github.com/json-iterator/go/-/badge.svg)](https://sourcegraph.com/github.com/json-iterator/go?badge) +[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/json-iterator/go) +[![Build Status](https://travis-ci.org/json-iterator/go.svg?branch=master)](https://travis-ci.org/json-iterator/go) +[![codecov](https://codecov.io/gh/json-iterator/go/branch/master/graph/badge.svg)](https://codecov.io/gh/json-iterator/go) +[![rcard](https://goreportcard.com/badge/github.com/json-iterator/go)](https://goreportcard.com/report/github.com/json-iterator/go) +[![License](http://img.shields.io/badge/license-mit-blue.svg?style=flat-square)](https://raw.githubusercontent.com/json-iterator/go/master/LICENSE) +[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) + +A high-performance 100% compatible drop-in replacement of "encoding/json" + +You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go) + +``` +Go开发者们请加入我们,滴滴出行平台技术部 taowen@didichuxing.com +``` + +# Benchmark + +![benchmark](http://jsoniter.com/benchmarks/go-benchmark.png) + +Source code: https://github.com/json-iterator/go-benchmark/blob/master/src/github.com/json-iterator/go-benchmark/benchmark_medium_payload_test.go + +Raw Result (easyjson requires static code generation) + +| | ns/op | allocation bytes | allocation times | +| --- | --- | --- | --- | +| std decode | 35510 ns/op | 1960 B/op | 99 allocs/op | +| easyjson decode | 8499 ns/op | 160 B/op | 4 allocs/op | +| jsoniter decode | 5623 ns/op | 160 B/op | 3 allocs/op | +| std encode | 2213 ns/op | 712 B/op | 5 allocs/op | +| easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op | +| jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op | + +Always benchmark with your own workload. +The result depends heavily on the data input. + +# Usage + +100% compatibility with standard lib + +Replace + +```go +import "encoding/json" +json.Marshal(&data) +``` + +with + +```go +import "github.com/json-iterator/go" + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Marshal(&data) +``` + +Replace + +```go +import "encoding/json" +json.Unmarshal(input, &data) +``` + +with + +```go +import "github.com/json-iterator/go" + +var json = jsoniter.ConfigCompatibleWithStandardLibrary +json.Unmarshal(input, &data) +``` + +[More documentation](http://jsoniter.com/migrate-from-go-std.html) + +# How to get + +``` +go get github.com/json-iterator/go +``` + +# Contribution Welcomed ! + +Contributors + +* [thockin](https://github.com/thockin) +* [mattn](https://github.com/mattn) +* [cch123](https://github.com/cch123) +* [Oleg Shaldybin](https://github.com/olegshaldybin) +* [Jason Toffaletti](https://github.com/toffaletti) + +Report issue or pull request, or email taowen@gmail.com, or [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby) diff --git a/vendor/github.com/json-iterator/go/adapter.go b/vendor/github.com/json-iterator/go/adapter.go new file mode 100644 index 000000000..e674d0f39 --- /dev/null +++ b/vendor/github.com/json-iterator/go/adapter.go @@ -0,0 +1,150 @@ +package jsoniter + +import ( + "bytes" + "io" +) + +// RawMessage to make replace json with jsoniter +type RawMessage []byte + +// Unmarshal adapts to json/encoding Unmarshal API +// +// Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. +// Refer to https://godoc.org/encoding/json#Unmarshal for more information +func Unmarshal(data []byte, v interface{}) error { + return ConfigDefault.Unmarshal(data, v) +} + +// UnmarshalFromString convenient method to read from string instead of []byte +func UnmarshalFromString(str string, v interface{}) error { + return ConfigDefault.UnmarshalFromString(str, v) +} + +// Get quick method to get value from deeply nested JSON structure +func Get(data []byte, path ...interface{}) Any { + return ConfigDefault.Get(data, path...) +} + +// Marshal adapts to json/encoding Marshal API +// +// Marshal returns the JSON encoding of v, adapts to json/encoding Marshal API +// Refer to https://godoc.org/encoding/json#Marshal for more information +func Marshal(v interface{}) ([]byte, error) { + return ConfigDefault.Marshal(v) +} + +// MarshalIndent same as json.MarshalIndent. Prefix is not supported. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + return ConfigDefault.MarshalIndent(v, prefix, indent) +} + +// MarshalToString convenient method to write as string instead of []byte +func MarshalToString(v interface{}) (string, error) { + return ConfigDefault.MarshalToString(v) +} + +// NewDecoder adapts to json/stream NewDecoder API. +// +// NewDecoder returns a new decoder that reads from r. +// +// Instead of a json/encoding Decoder, an Decoder is returned +// Refer to https://godoc.org/encoding/json#NewDecoder for more information +func NewDecoder(reader io.Reader) *Decoder { + return ConfigDefault.NewDecoder(reader) +} + +// Decoder reads and decodes JSON values from an input stream. +// Decoder provides identical APIs with json/stream Decoder (Token() and UseNumber() are in progress) +type Decoder struct { + iter *Iterator +} + +// Decode decode JSON into interface{} +func (adapter *Decoder) Decode(obj interface{}) error { + if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil { + if !adapter.iter.loadMore() { + return io.EOF + } + } + adapter.iter.ReadVal(obj) + err := adapter.iter.Error + if err == io.EOF { + return nil + } + return adapter.iter.Error +} + +// More is there more? +func (adapter *Decoder) More() bool { + iter := adapter.iter + if iter.Error != nil { + return false + } + c := iter.nextToken() + if c == 0 { + return false + } + iter.unreadByte() + return c != ']' && c != '}' +} + +// Buffered remaining buffer +func (adapter *Decoder) Buffered() io.Reader { + remaining := adapter.iter.buf[adapter.iter.head:adapter.iter.tail] + return bytes.NewReader(remaining) +} + +// UseNumber causes the Decoder to unmarshal a number into an interface{} as a +// Number instead of as a float64. +func (adapter *Decoder) UseNumber() { + cfg := adapter.iter.cfg.configBeforeFrozen + cfg.UseNumber = true + adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) +} + +// DisallowUnknownFields causes the Decoder to return an error when the destination +// is a struct and the input contains object keys which do not match any +// non-ignored, exported fields in the destination. +func (adapter *Decoder) DisallowUnknownFields() { + cfg := adapter.iter.cfg.configBeforeFrozen + cfg.DisallowUnknownFields = true + adapter.iter.cfg = cfg.frozeWithCacheReuse(adapter.iter.cfg.extraExtensions) +} + +// NewEncoder same as json.NewEncoder +func NewEncoder(writer io.Writer) *Encoder { + return ConfigDefault.NewEncoder(writer) +} + +// Encoder same as json.Encoder +type Encoder struct { + stream *Stream +} + +// Encode encode interface{} as JSON to io.Writer +func (adapter *Encoder) Encode(val interface{}) error { + adapter.stream.WriteVal(val) + adapter.stream.WriteRaw("\n") + adapter.stream.Flush() + return adapter.stream.Error +} + +// SetIndent set the indention. Prefix is not supported +func (adapter *Encoder) SetIndent(prefix, indent string) { + config := adapter.stream.cfg.configBeforeFrozen + config.IndentionStep = len(indent) + adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) +} + +// SetEscapeHTML escape html by default, set to false to disable +func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) { + config := adapter.stream.cfg.configBeforeFrozen + config.EscapeHTML = escapeHTML + adapter.stream.cfg = config.frozeWithCacheReuse(adapter.stream.cfg.extraExtensions) +} + +// Valid reports whether data is a valid JSON encoding. +func Valid(data []byte) bool { + return ConfigDefault.Valid(data) +} diff --git a/vendor/github.com/json-iterator/go/any.go b/vendor/github.com/json-iterator/go/any.go new file mode 100644 index 000000000..daecfed61 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any.go @@ -0,0 +1,321 @@ +package jsoniter + +import ( + "errors" + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "strconv" + "unsafe" +) + +// Any generic object representation. +// The lazy json implementation holds []byte and parse lazily. +type Any interface { + LastError() error + ValueType() ValueType + MustBeValid() Any + ToBool() bool + ToInt() int + ToInt32() int32 + ToInt64() int64 + ToUint() uint + ToUint32() uint32 + ToUint64() uint64 + ToFloat32() float32 + ToFloat64() float64 + ToString() string + ToVal(val interface{}) + Get(path ...interface{}) Any + Size() int + Keys() []string + GetInterface() interface{} + WriteTo(stream *Stream) +} + +type baseAny struct{} + +func (any *baseAny) Get(path ...interface{}) Any { + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} +} + +func (any *baseAny) Size() int { + return 0 +} + +func (any *baseAny) Keys() []string { + return []string{} +} + +func (any *baseAny) ToVal(obj interface{}) { + panic("not implemented") +} + +// WrapInt32 turn int32 into Any interface +func WrapInt32(val int32) Any { + return &int32Any{baseAny{}, val} +} + +// WrapInt64 turn int64 into Any interface +func WrapInt64(val int64) Any { + return &int64Any{baseAny{}, val} +} + +// WrapUint32 turn uint32 into Any interface +func WrapUint32(val uint32) Any { + return &uint32Any{baseAny{}, val} +} + +// WrapUint64 turn uint64 into Any interface +func WrapUint64(val uint64) Any { + return &uint64Any{baseAny{}, val} +} + +// WrapFloat64 turn float64 into Any interface +func WrapFloat64(val float64) Any { + return &floatAny{baseAny{}, val} +} + +// WrapString turn string into Any interface +func WrapString(val string) Any { + return &stringAny{baseAny{}, val} +} + +// Wrap turn a go object into Any interface +func Wrap(val interface{}) Any { + if val == nil { + return &nilAny{} + } + asAny, isAny := val.(Any) + if isAny { + return asAny + } + typ := reflect2.TypeOf(val) + switch typ.Kind() { + case reflect.Slice: + return wrapArray(val) + case reflect.Struct: + return wrapStruct(val) + case reflect.Map: + return wrapMap(val) + case reflect.String: + return WrapString(val.(string)) + case reflect.Int: + if strconv.IntSize == 32 { + return WrapInt32(int32(val.(int))) + } + return WrapInt64(int64(val.(int))) + case reflect.Int8: + return WrapInt32(int32(val.(int8))) + case reflect.Int16: + return WrapInt32(int32(val.(int16))) + case reflect.Int32: + return WrapInt32(val.(int32)) + case reflect.Int64: + return WrapInt64(val.(int64)) + case reflect.Uint: + if strconv.IntSize == 32 { + return WrapUint32(uint32(val.(uint))) + } + return WrapUint64(uint64(val.(uint))) + case reflect.Uintptr: + if ptrSize == 32 { + return WrapUint32(uint32(val.(uintptr))) + } + return WrapUint64(uint64(val.(uintptr))) + case reflect.Uint8: + return WrapUint32(uint32(val.(uint8))) + case reflect.Uint16: + return WrapUint32(uint32(val.(uint16))) + case reflect.Uint32: + return WrapUint32(uint32(val.(uint32))) + case reflect.Uint64: + return WrapUint64(val.(uint64)) + case reflect.Float32: + return WrapFloat64(float64(val.(float32))) + case reflect.Float64: + return WrapFloat64(val.(float64)) + case reflect.Bool: + if val.(bool) == true { + return &trueAny{} + } + return &falseAny{} + } + return &invalidAny{baseAny{}, fmt.Errorf("unsupported type: %v", typ)} +} + +// ReadAny read next JSON element as an Any object. It is a better json.RawMessage. +func (iter *Iterator) ReadAny() Any { + return iter.readAny() +} + +func (iter *Iterator) readAny() Any { + c := iter.nextToken() + switch c { + case '"': + iter.unreadByte() + return &stringAny{baseAny{}, iter.ReadString()} + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + return &nilAny{} + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + return &trueAny{} + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + return &falseAny{} + case '{': + return iter.readObjectAny() + case '[': + return iter.readArrayAny() + case '-': + return iter.readNumberAny(false) + case 0: + return &invalidAny{baseAny{}, errors.New("input is empty")} + default: + return iter.readNumberAny(true) + } +} + +func (iter *Iterator) readNumberAny(positive bool) Any { + iter.startCapture(iter.head - 1) + iter.skipNumber() + lazyBuf := iter.stopCapture() + return &numberLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readObjectAny() Any { + iter.startCapture(iter.head - 1) + iter.skipObject() + lazyBuf := iter.stopCapture() + return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func (iter *Iterator) readArrayAny() Any { + iter.startCapture(iter.head - 1) + iter.skipArray() + lazyBuf := iter.stopCapture() + return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil} +} + +func locateObjectField(iter *Iterator, target string) []byte { + var found []byte + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + if field == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + return true + }) + return found +} + +func locateArrayElement(iter *Iterator, target int) []byte { + var found []byte + n := 0 + iter.ReadArrayCB(func(iter *Iterator) bool { + if n == target { + found = iter.SkipAndReturnBytes() + return false + } + iter.Skip() + n++ + return true + }) + return found +} + +func locatePath(iter *Iterator, path []interface{}) Any { + for i, pathKeyObj := range path { + switch pathKey := pathKeyObj.(type) { + case string: + valueBytes := locateObjectField(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int: + valueBytes := locateArrayElement(iter, pathKey) + if valueBytes == nil { + return newInvalidAny(path[i:]) + } + iter.ResetBytes(valueBytes) + case int32: + if '*' == pathKey { + return iter.readAny().Get(path[i:]...) + } + return newInvalidAny(path[i:]) + default: + return newInvalidAny(path[i:]) + } + } + if iter.Error != nil && iter.Error != io.EOF { + return &invalidAny{baseAny{}, iter.Error} + } + return iter.readAny() +} + +var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem() + +func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ == anyType { + return &directAnyCodec{} + } + if typ.Implements(anyType) { + return &anyCodec{ + valType: typ, + } + } + return nil +} + +func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == anyType { + return &directAnyCodec{} + } + if typ.Implements(anyType) { + return &anyCodec{ + valType: typ, + } + } + return nil +} + +type anyCodec struct { + valType reflect2.Type +} + +func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + panic("not implemented") +} + +func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + any.WriteTo(stream) +} + +func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool { + obj := codec.valType.UnsafeIndirect(ptr) + any := obj.(Any) + return any.Size() == 0 +} + +type directAnyCodec struct { +} + +func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *(*Any)(ptr) = iter.readAny() +} + +func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + any := *(*Any)(ptr) + any.WriteTo(stream) +} + +func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool { + any := *(*Any)(ptr) + return any.Size() == 0 +} diff --git a/vendor/github.com/json-iterator/go/any_array.go b/vendor/github.com/json-iterator/go/any_array.go new file mode 100644 index 000000000..0449e9aa4 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_array.go @@ -0,0 +1,278 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type arrayLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *arrayLazyAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayLazyAny) MustBeValid() Any { + return any +} + +func (any *arrayLazyAny) LastError() error { + return any.err +} + +func (any *arrayLazyAny) ToBool() bool { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.ReadArray() +} + +func (any *arrayLazyAny) ToInt() int { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt32() int32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToInt64() int64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint() uint { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint32() uint32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToUint64() uint64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat32() float32 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToFloat64() float64 { + if any.ToBool() { + return 1 + } + return 0 +} + +func (any *arrayLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *arrayLazyAny) ToVal(val interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(val) +} + +func (any *arrayLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateArrayElement(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + arr := make([]Any, 0) + iter.ReadArrayCB(func(iter *Iterator) bool { + found := iter.readAny().Get(path[1:]...) + if found.ValueType() != InvalidValue { + arr = append(arr, found) + } + return true + }) + return wrapArray(arr) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadArrayCB(func(iter *Iterator) bool { + size++ + iter.Skip() + return true + }) + return size +} + +func (any *arrayLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *arrayLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type arrayAny struct { + baseAny + val reflect.Value +} + +func wrapArray(val interface{}) *arrayAny { + return &arrayAny{baseAny{}, reflect.ValueOf(val)} +} + +func (any *arrayAny) ValueType() ValueType { + return ArrayValue +} + +func (any *arrayAny) MustBeValid() Any { + return any +} + +func (any *arrayAny) LastError() error { + return nil +} + +func (any *arrayAny) ToBool() bool { + return any.val.Len() != 0 +} + +func (any *arrayAny) ToInt() int { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt32() int32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToInt64() int64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint() uint { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint32() uint32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToUint64() uint64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat32() float32 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToFloat64() float64 { + if any.val.Len() == 0 { + return 0 + } + return 1 +} + +func (any *arrayAny) ToString() string { + str, _ := MarshalToString(any.val.Interface()) + return str +} + +func (any *arrayAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int: + if firstPath < 0 || firstPath >= any.val.Len() { + return newInvalidAny(path) + } + return Wrap(any.val.Index(firstPath).Interface()) + case int32: + if '*' == firstPath { + mappedAll := make([]Any, 0) + for i := 0; i < any.val.Len(); i++ { + mapped := Wrap(any.val.Index(i).Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll = append(mappedAll, mapped) + } + } + return wrapArray(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *arrayAny) Size() int { + return any.val.Len() +} + +func (any *arrayAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *arrayAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/vendor/github.com/json-iterator/go/any_bool.go b/vendor/github.com/json-iterator/go/any_bool.go new file mode 100644 index 000000000..9452324af --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_bool.go @@ -0,0 +1,137 @@ +package jsoniter + +type trueAny struct { + baseAny +} + +func (any *trueAny) LastError() error { + return nil +} + +func (any *trueAny) ToBool() bool { + return true +} + +func (any *trueAny) ToInt() int { + return 1 +} + +func (any *trueAny) ToInt32() int32 { + return 1 +} + +func (any *trueAny) ToInt64() int64 { + return 1 +} + +func (any *trueAny) ToUint() uint { + return 1 +} + +func (any *trueAny) ToUint32() uint32 { + return 1 +} + +func (any *trueAny) ToUint64() uint64 { + return 1 +} + +func (any *trueAny) ToFloat32() float32 { + return 1 +} + +func (any *trueAny) ToFloat64() float64 { + return 1 +} + +func (any *trueAny) ToString() string { + return "true" +} + +func (any *trueAny) WriteTo(stream *Stream) { + stream.WriteTrue() +} + +func (any *trueAny) Parse() *Iterator { + return nil +} + +func (any *trueAny) GetInterface() interface{} { + return true +} + +func (any *trueAny) ValueType() ValueType { + return BoolValue +} + +func (any *trueAny) MustBeValid() Any { + return any +} + +type falseAny struct { + baseAny +} + +func (any *falseAny) LastError() error { + return nil +} + +func (any *falseAny) ToBool() bool { + return false +} + +func (any *falseAny) ToInt() int { + return 0 +} + +func (any *falseAny) ToInt32() int32 { + return 0 +} + +func (any *falseAny) ToInt64() int64 { + return 0 +} + +func (any *falseAny) ToUint() uint { + return 0 +} + +func (any *falseAny) ToUint32() uint32 { + return 0 +} + +func (any *falseAny) ToUint64() uint64 { + return 0 +} + +func (any *falseAny) ToFloat32() float32 { + return 0 +} + +func (any *falseAny) ToFloat64() float64 { + return 0 +} + +func (any *falseAny) ToString() string { + return "false" +} + +func (any *falseAny) WriteTo(stream *Stream) { + stream.WriteFalse() +} + +func (any *falseAny) Parse() *Iterator { + return nil +} + +func (any *falseAny) GetInterface() interface{} { + return false +} + +func (any *falseAny) ValueType() ValueType { + return BoolValue +} + +func (any *falseAny) MustBeValid() Any { + return any +} diff --git a/vendor/github.com/json-iterator/go/any_float.go b/vendor/github.com/json-iterator/go/any_float.go new file mode 100644 index 000000000..35fdb0949 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_float.go @@ -0,0 +1,83 @@ +package jsoniter + +import ( + "strconv" +) + +type floatAny struct { + baseAny + val float64 +} + +func (any *floatAny) Parse() *Iterator { + return nil +} + +func (any *floatAny) ValueType() ValueType { + return NumberValue +} + +func (any *floatAny) MustBeValid() Any { + return any +} + +func (any *floatAny) LastError() error { + return nil +} + +func (any *floatAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *floatAny) ToInt() int { + return int(any.val) +} + +func (any *floatAny) ToInt32() int32 { + return int32(any.val) +} + +func (any *floatAny) ToInt64() int64 { + return int64(any.val) +} + +func (any *floatAny) ToUint() uint { + if any.val > 0 { + return uint(any.val) + } + return 0 +} + +func (any *floatAny) ToUint32() uint32 { + if any.val > 0 { + return uint32(any.val) + } + return 0 +} + +func (any *floatAny) ToUint64() uint64 { + if any.val > 0 { + return uint64(any.val) + } + return 0 +} + +func (any *floatAny) ToFloat32() float32 { + return float32(any.val) +} + +func (any *floatAny) ToFloat64() float64 { + return any.val +} + +func (any *floatAny) ToString() string { + return strconv.FormatFloat(any.val, 'E', -1, 64) +} + +func (any *floatAny) WriteTo(stream *Stream) { + stream.WriteFloat64(any.val) +} + +func (any *floatAny) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_int32.go b/vendor/github.com/json-iterator/go/any_int32.go new file mode 100644 index 000000000..1b56f3991 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_int32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int32Any struct { + baseAny + val int32 +} + +func (any *int32Any) LastError() error { + return nil +} + +func (any *int32Any) ValueType() ValueType { + return NumberValue +} + +func (any *int32Any) MustBeValid() Any { + return any +} + +func (any *int32Any) ToBool() bool { + return any.val != 0 +} + +func (any *int32Any) ToInt() int { + return int(any.val) +} + +func (any *int32Any) ToInt32() int32 { + return any.val +} + +func (any *int32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *int32Any) ToUint() uint { + return uint(any.val) +} + +func (any *int32Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *int32Any) WriteTo(stream *Stream) { + stream.WriteInt32(any.val) +} + +func (any *int32Any) Parse() *Iterator { + return nil +} + +func (any *int32Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_int64.go b/vendor/github.com/json-iterator/go/any_int64.go new file mode 100644 index 000000000..c440d72b6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_int64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type int64Any struct { + baseAny + val int64 +} + +func (any *int64Any) LastError() error { + return nil +} + +func (any *int64Any) ValueType() ValueType { + return NumberValue +} + +func (any *int64Any) MustBeValid() Any { + return any +} + +func (any *int64Any) ToBool() bool { + return any.val != 0 +} + +func (any *int64Any) ToInt() int { + return int(any.val) +} + +func (any *int64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *int64Any) ToInt64() int64 { + return any.val +} + +func (any *int64Any) ToUint() uint { + return uint(any.val) +} + +func (any *int64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *int64Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *int64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *int64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *int64Any) ToString() string { + return strconv.FormatInt(any.val, 10) +} + +func (any *int64Any) WriteTo(stream *Stream) { + stream.WriteInt64(any.val) +} + +func (any *int64Any) Parse() *Iterator { + return nil +} + +func (any *int64Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_invalid.go b/vendor/github.com/json-iterator/go/any_invalid.go new file mode 100644 index 000000000..1d859eac3 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_invalid.go @@ -0,0 +1,82 @@ +package jsoniter + +import "fmt" + +type invalidAny struct { + baseAny + err error +} + +func newInvalidAny(path []interface{}) *invalidAny { + return &invalidAny{baseAny{}, fmt.Errorf("%v not found", path)} +} + +func (any *invalidAny) LastError() error { + return any.err +} + +func (any *invalidAny) ValueType() ValueType { + return InvalidValue +} + +func (any *invalidAny) MustBeValid() Any { + panic(any.err) +} + +func (any *invalidAny) ToBool() bool { + return false +} + +func (any *invalidAny) ToInt() int { + return 0 +} + +func (any *invalidAny) ToInt32() int32 { + return 0 +} + +func (any *invalidAny) ToInt64() int64 { + return 0 +} + +func (any *invalidAny) ToUint() uint { + return 0 +} + +func (any *invalidAny) ToUint32() uint32 { + return 0 +} + +func (any *invalidAny) ToUint64() uint64 { + return 0 +} + +func (any *invalidAny) ToFloat32() float32 { + return 0 +} + +func (any *invalidAny) ToFloat64() float64 { + return 0 +} + +func (any *invalidAny) ToString() string { + return "" +} + +func (any *invalidAny) WriteTo(stream *Stream) { +} + +func (any *invalidAny) Get(path ...interface{}) Any { + if any.err == nil { + return &invalidAny{baseAny{}, fmt.Errorf("get %v from invalid", path)} + } + return &invalidAny{baseAny{}, fmt.Errorf("%v, get %v from invalid", any.err, path)} +} + +func (any *invalidAny) Parse() *Iterator { + return nil +} + +func (any *invalidAny) GetInterface() interface{} { + return nil +} diff --git a/vendor/github.com/json-iterator/go/any_nil.go b/vendor/github.com/json-iterator/go/any_nil.go new file mode 100644 index 000000000..d04cb54c1 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_nil.go @@ -0,0 +1,69 @@ +package jsoniter + +type nilAny struct { + baseAny +} + +func (any *nilAny) LastError() error { + return nil +} + +func (any *nilAny) ValueType() ValueType { + return NilValue +} + +func (any *nilAny) MustBeValid() Any { + return any +} + +func (any *nilAny) ToBool() bool { + return false +} + +func (any *nilAny) ToInt() int { + return 0 +} + +func (any *nilAny) ToInt32() int32 { + return 0 +} + +func (any *nilAny) ToInt64() int64 { + return 0 +} + +func (any *nilAny) ToUint() uint { + return 0 +} + +func (any *nilAny) ToUint32() uint32 { + return 0 +} + +func (any *nilAny) ToUint64() uint64 { + return 0 +} + +func (any *nilAny) ToFloat32() float32 { + return 0 +} + +func (any *nilAny) ToFloat64() float64 { + return 0 +} + +func (any *nilAny) ToString() string { + return "" +} + +func (any *nilAny) WriteTo(stream *Stream) { + stream.WriteNil() +} + +func (any *nilAny) Parse() *Iterator { + return nil +} + +func (any *nilAny) GetInterface() interface{} { + return nil +} diff --git a/vendor/github.com/json-iterator/go/any_number.go b/vendor/github.com/json-iterator/go/any_number.go new file mode 100644 index 000000000..9d1e901a6 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_number.go @@ -0,0 +1,123 @@ +package jsoniter + +import ( + "io" + "unsafe" +) + +type numberLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *numberLazyAny) ValueType() ValueType { + return NumberValue +} + +func (any *numberLazyAny) MustBeValid() Any { + return any +} + +func (any *numberLazyAny) LastError() error { + return any.err +} + +func (any *numberLazyAny) ToBool() bool { + return any.ToFloat64() != 0 +} + +func (any *numberLazyAny) ToInt() int { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToInt32() int32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToInt64() int64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadInt64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint() uint { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint32() uint32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToUint64() uint64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadUint64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToFloat32() float32 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat32() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToFloat64() float64 { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + val := iter.ReadFloat64() + if iter.Error != nil && iter.Error != io.EOF { + any.err = iter.Error + } + return val +} + +func (any *numberLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *numberLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *numberLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} diff --git a/vendor/github.com/json-iterator/go/any_object.go b/vendor/github.com/json-iterator/go/any_object.go new file mode 100644 index 000000000..c44ef5c98 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_object.go @@ -0,0 +1,374 @@ +package jsoniter + +import ( + "reflect" + "unsafe" +) + +type objectLazyAny struct { + baseAny + cfg *frozenConfig + buf []byte + err error +} + +func (any *objectLazyAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectLazyAny) MustBeValid() Any { + return any +} + +func (any *objectLazyAny) LastError() error { + return any.err +} + +func (any *objectLazyAny) ToBool() bool { + return true +} + +func (any *objectLazyAny) ToInt() int { + return 0 +} + +func (any *objectLazyAny) ToInt32() int32 { + return 0 +} + +func (any *objectLazyAny) ToInt64() int64 { + return 0 +} + +func (any *objectLazyAny) ToUint() uint { + return 0 +} + +func (any *objectLazyAny) ToUint32() uint32 { + return 0 +} + +func (any *objectLazyAny) ToUint64() uint64 { + return 0 +} + +func (any *objectLazyAny) ToFloat32() float32 { + return 0 +} + +func (any *objectLazyAny) ToFloat64() float64 { + return 0 +} + +func (any *objectLazyAny) ToString() string { + return *(*string)(unsafe.Pointer(&any.buf)) +} + +func (any *objectLazyAny) ToVal(obj interface{}) { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadVal(obj) +} + +func (any *objectLazyAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + valueBytes := locateObjectField(iter, firstPath) + if valueBytes == nil { + return newInvalidAny(path) + } + iter.ResetBytes(valueBytes) + return locatePath(iter, path[1:]) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + mapped := locatePath(iter, path[1:]) + if mapped.ValueType() != InvalidValue { + mappedAll[field] = mapped + } + return true + }) + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectLazyAny) Keys() []string { + keys := []string{} + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadMapCB(func(iter *Iterator, field string) bool { + iter.Skip() + keys = append(keys, field) + return true + }) + return keys +} + +func (any *objectLazyAny) Size() int { + size := 0 + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + size++ + return true + }) + return size +} + +func (any *objectLazyAny) WriteTo(stream *Stream) { + stream.Write(any.buf) +} + +func (any *objectLazyAny) GetInterface() interface{} { + iter := any.cfg.BorrowIterator(any.buf) + defer any.cfg.ReturnIterator(iter) + return iter.Read() +} + +type objectAny struct { + baseAny + err error + val reflect.Value +} + +func wrapStruct(val interface{}) *objectAny { + return &objectAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *objectAny) ValueType() ValueType { + return ObjectValue +} + +func (any *objectAny) MustBeValid() Any { + return any +} + +func (any *objectAny) Parse() *Iterator { + return nil +} + +func (any *objectAny) LastError() error { + return any.err +} + +func (any *objectAny) ToBool() bool { + return any.val.NumField() != 0 +} + +func (any *objectAny) ToInt() int { + return 0 +} + +func (any *objectAny) ToInt32() int32 { + return 0 +} + +func (any *objectAny) ToInt64() int64 { + return 0 +} + +func (any *objectAny) ToUint() uint { + return 0 +} + +func (any *objectAny) ToUint32() uint32 { + return 0 +} + +func (any *objectAny) ToUint64() uint64 { + return 0 +} + +func (any *objectAny) ToFloat32() float32 { + return 0 +} + +func (any *objectAny) ToFloat64() float64 { + return 0 +} + +func (any *objectAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *objectAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case string: + field := any.val.FieldByName(firstPath) + if !field.IsValid() { + return newInvalidAny(path) + } + return Wrap(field.Interface()) + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for i := 0; i < any.val.NumField(); i++ { + field := any.val.Field(i) + if field.CanInterface() { + mapped := Wrap(field.Interface()).Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[any.val.Type().Field(i).Name] = mapped + } + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + return newInvalidAny(path) + } +} + +func (any *objectAny) Keys() []string { + keys := make([]string, 0, any.val.NumField()) + for i := 0; i < any.val.NumField(); i++ { + keys = append(keys, any.val.Type().Field(i).Name) + } + return keys +} + +func (any *objectAny) Size() int { + return any.val.NumField() +} + +func (any *objectAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *objectAny) GetInterface() interface{} { + return any.val.Interface() +} + +type mapAny struct { + baseAny + err error + val reflect.Value +} + +func wrapMap(val interface{}) *mapAny { + return &mapAny{baseAny{}, nil, reflect.ValueOf(val)} +} + +func (any *mapAny) ValueType() ValueType { + return ObjectValue +} + +func (any *mapAny) MustBeValid() Any { + return any +} + +func (any *mapAny) Parse() *Iterator { + return nil +} + +func (any *mapAny) LastError() error { + return any.err +} + +func (any *mapAny) ToBool() bool { + return true +} + +func (any *mapAny) ToInt() int { + return 0 +} + +func (any *mapAny) ToInt32() int32 { + return 0 +} + +func (any *mapAny) ToInt64() int64 { + return 0 +} + +func (any *mapAny) ToUint() uint { + return 0 +} + +func (any *mapAny) ToUint32() uint32 { + return 0 +} + +func (any *mapAny) ToUint64() uint64 { + return 0 +} + +func (any *mapAny) ToFloat32() float32 { + return 0 +} + +func (any *mapAny) ToFloat64() float64 { + return 0 +} + +func (any *mapAny) ToString() string { + str, err := MarshalToString(any.val.Interface()) + any.err = err + return str +} + +func (any *mapAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + switch firstPath := path[0].(type) { + case int32: + if '*' == firstPath { + mappedAll := map[string]Any{} + for _, key := range any.val.MapKeys() { + keyAsStr := key.String() + element := Wrap(any.val.MapIndex(key).Interface()) + mapped := element.Get(path[1:]...) + if mapped.ValueType() != InvalidValue { + mappedAll[keyAsStr] = mapped + } + } + return wrapMap(mappedAll) + } + return newInvalidAny(path) + default: + value := any.val.MapIndex(reflect.ValueOf(firstPath)) + if !value.IsValid() { + return newInvalidAny(path) + } + return Wrap(value.Interface()) + } +} + +func (any *mapAny) Keys() []string { + keys := make([]string, 0, any.val.Len()) + for _, key := range any.val.MapKeys() { + keys = append(keys, key.String()) + } + return keys +} + +func (any *mapAny) Size() int { + return any.val.Len() +} + +func (any *mapAny) WriteTo(stream *Stream) { + stream.WriteVal(any.val) +} + +func (any *mapAny) GetInterface() interface{} { + return any.val.Interface() +} diff --git a/vendor/github.com/json-iterator/go/any_str.go b/vendor/github.com/json-iterator/go/any_str.go new file mode 100644 index 000000000..a4b93c78c --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_str.go @@ -0,0 +1,166 @@ +package jsoniter + +import ( + "fmt" + "strconv" +) + +type stringAny struct { + baseAny + val string +} + +func (any *stringAny) Get(path ...interface{}) Any { + if len(path) == 0 { + return any + } + return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)} +} + +func (any *stringAny) Parse() *Iterator { + return nil +} + +func (any *stringAny) ValueType() ValueType { + return StringValue +} + +func (any *stringAny) MustBeValid() Any { + return any +} + +func (any *stringAny) LastError() error { + return nil +} + +func (any *stringAny) ToBool() bool { + str := any.ToString() + if str == "0" { + return false + } + for _, c := range str { + switch c { + case ' ', '\n', '\r', '\t': + default: + return true + } + } + return false +} + +func (any *stringAny) ToInt() int { + return int(any.ToInt64()) + +} + +func (any *stringAny) ToInt32() int32 { + return int32(any.ToInt64()) +} + +func (any *stringAny) ToInt64() int64 { + if any.val == "" { + return 0 + } + + flag := 1 + startPos := 0 + endPos := 0 + if any.val[0] == '+' || any.val[0] == '-' { + startPos = 1 + } + + if any.val[0] == '-' { + flag = -1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseInt(any.val[startPos:endPos], 10, 64) + return int64(flag) * parsed +} + +func (any *stringAny) ToUint() uint { + return uint(any.ToUint64()) +} + +func (any *stringAny) ToUint32() uint32 { + return uint32(any.ToUint64()) +} + +func (any *stringAny) ToUint64() uint64 { + if any.val == "" { + return 0 + } + + startPos := 0 + endPos := 0 + + if any.val[0] == '-' { + return 0 + } + if any.val[0] == '+' { + startPos = 1 + } + + for i := startPos; i < len(any.val); i++ { + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + break + } + } + parsed, _ := strconv.ParseUint(any.val[startPos:endPos], 10, 64) + return parsed +} + +func (any *stringAny) ToFloat32() float32 { + return float32(any.ToFloat64()) +} + +func (any *stringAny) ToFloat64() float64 { + if len(any.val) == 0 { + return 0 + } + + // first char invalid + if any.val[0] != '+' && any.val[0] != '-' && (any.val[0] > '9' || any.val[0] < '0') { + return 0 + } + + // extract valid num expression from string + // eg 123true => 123, -12.12xxa => -12.12 + endPos := 1 + for i := 1; i < len(any.val); i++ { + if any.val[i] == '.' || any.val[i] == 'e' || any.val[i] == 'E' || any.val[i] == '+' || any.val[i] == '-' { + endPos = i + 1 + continue + } + + // end position is the first char which is not digit + if any.val[i] >= '0' && any.val[i] <= '9' { + endPos = i + 1 + } else { + endPos = i + break + } + } + parsed, _ := strconv.ParseFloat(any.val[:endPos], 64) + return parsed +} + +func (any *stringAny) ToString() string { + return any.val +} + +func (any *stringAny) WriteTo(stream *Stream) { + stream.WriteString(any.val) +} + +func (any *stringAny) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_uint32.go b/vendor/github.com/json-iterator/go/any_uint32.go new file mode 100644 index 000000000..656bbd33d --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_uint32.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint32Any struct { + baseAny + val uint32 +} + +func (any *uint32Any) LastError() error { + return nil +} + +func (any *uint32Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint32Any) MustBeValid() Any { + return any +} + +func (any *uint32Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint32Any) ToInt() int { + return int(any.val) +} + +func (any *uint32Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint32Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint32Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint32Any) ToUint32() uint32 { + return any.val +} + +func (any *uint32Any) ToUint64() uint64 { + return uint64(any.val) +} + +func (any *uint32Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint32Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint32Any) ToString() string { + return strconv.FormatInt(int64(any.val), 10) +} + +func (any *uint32Any) WriteTo(stream *Stream) { + stream.WriteUint32(any.val) +} + +func (any *uint32Any) Parse() *Iterator { + return nil +} + +func (any *uint32Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/any_uint64.go b/vendor/github.com/json-iterator/go/any_uint64.go new file mode 100644 index 000000000..7df2fce33 --- /dev/null +++ b/vendor/github.com/json-iterator/go/any_uint64.go @@ -0,0 +1,74 @@ +package jsoniter + +import ( + "strconv" +) + +type uint64Any struct { + baseAny + val uint64 +} + +func (any *uint64Any) LastError() error { + return nil +} + +func (any *uint64Any) ValueType() ValueType { + return NumberValue +} + +func (any *uint64Any) MustBeValid() Any { + return any +} + +func (any *uint64Any) ToBool() bool { + return any.val != 0 +} + +func (any *uint64Any) ToInt() int { + return int(any.val) +} + +func (any *uint64Any) ToInt32() int32 { + return int32(any.val) +} + +func (any *uint64Any) ToInt64() int64 { + return int64(any.val) +} + +func (any *uint64Any) ToUint() uint { + return uint(any.val) +} + +func (any *uint64Any) ToUint32() uint32 { + return uint32(any.val) +} + +func (any *uint64Any) ToUint64() uint64 { + return any.val +} + +func (any *uint64Any) ToFloat32() float32 { + return float32(any.val) +} + +func (any *uint64Any) ToFloat64() float64 { + return float64(any.val) +} + +func (any *uint64Any) ToString() string { + return strconv.FormatUint(any.val, 10) +} + +func (any *uint64Any) WriteTo(stream *Stream) { + stream.WriteUint64(any.val) +} + +func (any *uint64Any) Parse() *Iterator { + return nil +} + +func (any *uint64Any) GetInterface() interface{} { + return any.val +} diff --git a/vendor/github.com/json-iterator/go/build.sh b/vendor/github.com/json-iterator/go/build.sh new file mode 100644 index 000000000..b45ef6883 --- /dev/null +++ b/vendor/github.com/json-iterator/go/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +set -x + +if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then + mkdir -p /tmp/build-golang/src/github.com/json-iterator + ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go +fi +export GOPATH=/tmp/build-golang +go get -u github.com/golang/dep/cmd/dep +cd /tmp/build-golang/src/github.com/json-iterator/go +exec $GOPATH/bin/dep ensure -update diff --git a/vendor/github.com/json-iterator/go/config.go b/vendor/github.com/json-iterator/go/config.go new file mode 100644 index 000000000..8c58fcba5 --- /dev/null +++ b/vendor/github.com/json-iterator/go/config.go @@ -0,0 +1,375 @@ +package jsoniter + +import ( + "encoding/json" + "io" + "reflect" + "sync" + "unsafe" + + "github.com/modern-go/concurrent" + "github.com/modern-go/reflect2" +) + +// Config customize how the API should behave. +// The API is created from Config by Froze. +type Config struct { + IndentionStep int + MarshalFloatWith6Digits bool + EscapeHTML bool + SortMapKeys bool + UseNumber bool + DisallowUnknownFields bool + TagKey string + OnlyTaggedField bool + ValidateJsonRawMessage bool + ObjectFieldMustBeSimpleString bool + CaseSensitive bool +} + +// API the public interface of this package. +// Primary Marshal and Unmarshal. +type API interface { + IteratorPool + StreamPool + MarshalToString(v interface{}) (string, error) + Marshal(v interface{}) ([]byte, error) + MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) + UnmarshalFromString(str string, v interface{}) error + Unmarshal(data []byte, v interface{}) error + Get(data []byte, path ...interface{}) Any + NewEncoder(writer io.Writer) *Encoder + NewDecoder(reader io.Reader) *Decoder + Valid(data []byte) bool + RegisterExtension(extension Extension) + DecoderOf(typ reflect2.Type) ValDecoder + EncoderOf(typ reflect2.Type) ValEncoder +} + +// ConfigDefault the default API +var ConfigDefault = Config{ + EscapeHTML: true, +}.Froze() + +// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior +var ConfigCompatibleWithStandardLibrary = Config{ + EscapeHTML: true, + SortMapKeys: true, + ValidateJsonRawMessage: true, +}.Froze() + +// ConfigFastest marshals float with only 6 digits precision +var ConfigFastest = Config{ + EscapeHTML: false, + MarshalFloatWith6Digits: true, // will lose precession + ObjectFieldMustBeSimpleString: true, // do not unescape object field +}.Froze() + +type frozenConfig struct { + configBeforeFrozen Config + sortMapKeys bool + indentionStep int + objectFieldMustBeSimpleString bool + onlyTaggedField bool + disallowUnknownFields bool + decoderCache *concurrent.Map + encoderCache *concurrent.Map + encoderExtension Extension + decoderExtension Extension + extraExtensions []Extension + streamPool *sync.Pool + iteratorPool *sync.Pool + caseSensitive bool +} + +func (cfg *frozenConfig) initCache() { + cfg.decoderCache = concurrent.NewMap() + cfg.encoderCache = concurrent.NewMap() +} + +func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) { + cfg.decoderCache.Store(cacheKey, decoder) +} + +func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) { + cfg.encoderCache.Store(cacheKey, encoder) +} + +func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder { + decoder, found := cfg.decoderCache.Load(cacheKey) + if found { + return decoder.(ValDecoder) + } + return nil +} + +func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder { + encoder, found := cfg.encoderCache.Load(cacheKey) + if found { + return encoder.(ValEncoder) + } + return nil +} + +var cfgCache = concurrent.NewMap() + +func getFrozenConfigFromCache(cfg Config) *frozenConfig { + obj, found := cfgCache.Load(cfg) + if found { + return obj.(*frozenConfig) + } + return nil +} + +func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) { + cfgCache.Store(cfg, frozenConfig) +} + +// Froze forge API from config +func (cfg Config) Froze() API { + api := &frozenConfig{ + sortMapKeys: cfg.SortMapKeys, + indentionStep: cfg.IndentionStep, + objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString, + onlyTaggedField: cfg.OnlyTaggedField, + disallowUnknownFields: cfg.DisallowUnknownFields, + caseSensitive: cfg.CaseSensitive, + } + api.streamPool = &sync.Pool{ + New: func() interface{} { + return NewStream(api, nil, 512) + }, + } + api.iteratorPool = &sync.Pool{ + New: func() interface{} { + return NewIterator(api) + }, + } + api.initCache() + encoderExtension := EncoderExtension{} + decoderExtension := DecoderExtension{} + if cfg.MarshalFloatWith6Digits { + api.marshalFloatWith6Digits(encoderExtension) + } + if cfg.EscapeHTML { + api.escapeHTML(encoderExtension) + } + if cfg.UseNumber { + api.useNumber(decoderExtension) + } + if cfg.ValidateJsonRawMessage { + api.validateJsonRawMessage(encoderExtension) + } + api.encoderExtension = encoderExtension + api.decoderExtension = decoderExtension + api.configBeforeFrozen = cfg + return api +} + +func (cfg Config) frozeWithCacheReuse(extraExtensions []Extension) *frozenConfig { + api := getFrozenConfigFromCache(cfg) + if api != nil { + return api + } + api = cfg.Froze().(*frozenConfig) + for _, extension := range extraExtensions { + api.RegisterExtension(extension) + } + addFrozenConfigToCache(cfg, api) + return api +} + +func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) { + encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) { + rawMessage := *(*json.RawMessage)(ptr) + iter := cfg.BorrowIterator([]byte(rawMessage)) + iter.Read() + if iter.Error != nil { + stream.WriteRaw("null") + } else { + cfg.ReturnIterator(iter) + stream.WriteRaw(string(rawMessage)) + } + }, func(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 + }} + extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder + extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder +} + +func (cfg *frozenConfig) useNumber(extension DecoderExtension) { + extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) { + exitingValue := *((*interface{})(ptr)) + if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr { + iter.ReadVal(exitingValue) + return + } + if iter.WhatIsNext() == NumberValue { + *((*interface{})(ptr)) = json.Number(iter.readNumberAsString()) + } else { + *((*interface{})(ptr)) = iter.Read() + } + }} +} +func (cfg *frozenConfig) getTagKey() string { + tagKey := cfg.configBeforeFrozen.TagKey + if tagKey == "" { + return "json" + } + return tagKey +} + +func (cfg *frozenConfig) RegisterExtension(extension Extension) { + cfg.extraExtensions = append(cfg.extraExtensions, extension) + copied := cfg.configBeforeFrozen + cfg.configBeforeFrozen = copied +} + +type lossyFloat32Encoder struct { +} + +func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32Lossy(*((*float32)(ptr))) +} + +func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type lossyFloat64Encoder struct { +} + +func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64Lossy(*((*float64)(ptr))) +} + +func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +// EnableLossyFloatMarshalling keeps 10**(-6) precision +// for float variables for better performance. +func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) { + // for better performance + extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{} + extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{} +} + +type htmlEscapedStringEncoder struct { +} + +func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteStringWithHTMLEscaped(str) +} + +func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) { + encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{} +} + +func (cfg *frozenConfig) cleanDecoders() { + typeDecoders = map[string]ValDecoder{} + fieldDecoders = map[string]ValDecoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) cleanEncoders() { + typeEncoders = map[string]ValEncoder{} + fieldEncoders = map[string]ValEncoder{} + *cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig)) +} + +func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return "", stream.Error + } + return string(stream.Buffer()), nil +} + +func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) { + stream := cfg.BorrowStream(nil) + defer cfg.ReturnStream(stream) + stream.WriteVal(v) + if stream.Error != nil { + return nil, stream.Error + } + result := stream.Buffer() + copied := make([]byte, len(result)) + copy(copied, result) + return copied, nil +} + +func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + if prefix != "" { + panic("prefix is not supported") + } + for _, r := range indent { + if r != ' ' { + panic("indent can only be space") + } + } + newCfg := cfg.configBeforeFrozen + newCfg.IndentionStep = len(indent) + return newCfg.frozeWithCacheReuse(cfg.extraExtensions).Marshal(v) +} + +func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error { + data := []byte(str) + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + c := iter.nextToken() + if c == 0 { + if iter.Error == io.EOF { + return nil + } + return iter.Error + } + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + return iter.Error +} + +func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + return locatePath(iter, path) +} + +func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.ReadVal(v) + c := iter.nextToken() + if c == 0 { + if iter.Error == io.EOF { + return nil + } + return iter.Error + } + iter.ReportError("Unmarshal", "there are bytes left after unmarshal") + return iter.Error +} + +func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder { + stream := NewStream(cfg, writer, 512) + return &Encoder{stream} +} + +func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder { + iter := Parse(cfg, reader, 512) + return &Decoder{iter} +} + +func (cfg *frozenConfig) Valid(data []byte) bool { + iter := cfg.BorrowIterator(data) + defer cfg.ReturnIterator(iter) + iter.Skip() + return iter.Error == nil +} diff --git a/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md new file mode 100644 index 000000000..3095662b0 --- /dev/null +++ b/vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md @@ -0,0 +1,7 @@ +| json type \ dest type | bool | int | uint | float |string| +| --- | --- | --- | --- |--|--| +| number | positive => true
negative => true
zero => false| 23.2 => 23
-32.1 => -32| 12.1 => 12
-12.1 => 0|as normal|same as origin| +| string | empty string => false
string "0" => false
other strings => true | "123.32" => 123
"-123.4" => -123
"123.23xxxw" => 123
"abcde12" => 0
"-32.1" => -32| 13.2 => 13
-1.1 => 0 |12.1 => 12.1
-12.3 => -12.3
12.4xxa => 12.4
+1.1e2 =>110 |same as origin| +| bool | true => true
false => false| true => 1
false => 0 | true => 1
false => 0 |true => 1
false => 0|true => "true"
false => "false"| +| object | true | 0 | 0 |0|originnal json| +| array | empty array => false
nonempty array => true| [] => 0
[1,2] => 1 | [] => 0
[1,2] => 1 |[] => 0
[1,2] => 1|original json| \ No newline at end of file diff --git a/vendor/github.com/json-iterator/go/iter.go b/vendor/github.com/json-iterator/go/iter.go new file mode 100644 index 000000000..95ae54fbf --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter.go @@ -0,0 +1,322 @@ +package jsoniter + +import ( + "encoding/json" + "fmt" + "io" +) + +// ValueType the type for JSON element +type ValueType int + +const ( + // InvalidValue invalid JSON element + InvalidValue ValueType = iota + // StringValue JSON element "string" + StringValue + // NumberValue JSON element 100 or 0.10 + NumberValue + // NilValue JSON element null + NilValue + // BoolValue JSON element true or false + BoolValue + // ArrayValue JSON element [] + ArrayValue + // ObjectValue JSON element {} + ObjectValue +) + +var hexDigits []byte +var valueTypes []ValueType + +func init() { + hexDigits = make([]byte, 256) + for i := 0; i < len(hexDigits); i++ { + hexDigits[i] = 255 + } + for i := '0'; i <= '9'; i++ { + hexDigits[i] = byte(i - '0') + } + for i := 'a'; i <= 'f'; i++ { + hexDigits[i] = byte((i - 'a') + 10) + } + for i := 'A'; i <= 'F'; i++ { + hexDigits[i] = byte((i - 'A') + 10) + } + valueTypes = make([]ValueType, 256) + for i := 0; i < len(valueTypes); i++ { + valueTypes[i] = InvalidValue + } + valueTypes['"'] = StringValue + valueTypes['-'] = NumberValue + valueTypes['0'] = NumberValue + valueTypes['1'] = NumberValue + valueTypes['2'] = NumberValue + valueTypes['3'] = NumberValue + valueTypes['4'] = NumberValue + valueTypes['5'] = NumberValue + valueTypes['6'] = NumberValue + valueTypes['7'] = NumberValue + valueTypes['8'] = NumberValue + valueTypes['9'] = NumberValue + valueTypes['t'] = BoolValue + valueTypes['f'] = BoolValue + valueTypes['n'] = NilValue + valueTypes['['] = ArrayValue + valueTypes['{'] = ObjectValue +} + +// Iterator is a io.Reader like object, with JSON specific read functions. +// Error is not returned as return value, but stored as Error member on this iterator instance. +type Iterator struct { + cfg *frozenConfig + reader io.Reader + buf []byte + head int + tail int + captureStartedAt int + captured []byte + Error error + Attachment interface{} // open for customized decoder +} + +// NewIterator creates an empty Iterator instance +func NewIterator(cfg API) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: nil, + head: 0, + tail: 0, + } +} + +// Parse creates an Iterator instance from io.Reader +func Parse(cfg API, reader io.Reader, bufSize int) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: reader, + buf: make([]byte, bufSize), + head: 0, + tail: 0, + } +} + +// ParseBytes creates an Iterator instance from byte array +func ParseBytes(cfg API, input []byte) *Iterator { + return &Iterator{ + cfg: cfg.(*frozenConfig), + reader: nil, + buf: input, + head: 0, + tail: len(input), + } +} + +// ParseString creates an Iterator instance from string +func ParseString(cfg API, input string) *Iterator { + return ParseBytes(cfg, []byte(input)) +} + +// Pool returns a pool can provide more iterator with same configuration +func (iter *Iterator) Pool() IteratorPool { + return iter.cfg +} + +// Reset reuse iterator instance by specifying another reader +func (iter *Iterator) Reset(reader io.Reader) *Iterator { + iter.reader = reader + iter.head = 0 + iter.tail = 0 + return iter +} + +// ResetBytes reuse iterator instance by specifying another byte array as input +func (iter *Iterator) ResetBytes(input []byte) *Iterator { + iter.reader = nil + iter.buf = input + iter.head = 0 + iter.tail = len(input) + return iter +} + +// WhatIsNext gets ValueType of relatively next json element +func (iter *Iterator) WhatIsNext() ValueType { + valueType := valueTypes[iter.nextToken()] + iter.unreadByte() + return valueType +} + +func (iter *Iterator) skipWhitespacesWithoutLoadMore() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + return false + } + return true +} + +func (iter *Iterator) isObjectEnd() bool { + c := iter.nextToken() + if c == ',' { + return false + } + if c == '}' { + return true + } + iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c})) + return true +} + +func (iter *Iterator) nextToken() byte { + // a variation of skip whitespaces, returning the next non-whitespace token + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\t', '\r': + continue + } + iter.head = i + 1 + return c + } + if !iter.loadMore() { + return 0 + } + } +} + +// ReportError record a error in iterator instance with current position. +func (iter *Iterator) ReportError(operation string, msg string) { + if iter.Error != nil { + if iter.Error != io.EOF { + return + } + } + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + peekEnd := iter.head + 10 + if peekEnd > iter.tail { + peekEnd = iter.tail + } + parsing := string(iter.buf[peekStart:peekEnd]) + contextStart := iter.head - 50 + if contextStart < 0 { + contextStart = 0 + } + contextEnd := iter.head + 50 + if contextEnd > iter.tail { + contextEnd = iter.tail + } + context := string(iter.buf[contextStart:contextEnd]) + iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...", + operation, msg, iter.head-peekStart, parsing, context) +} + +// CurrentBuffer gets current buffer as string for debugging purpose +func (iter *Iterator) CurrentBuffer() string { + peekStart := iter.head - 10 + if peekStart < 0 { + peekStart = 0 + } + return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head, + string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail])) +} + +func (iter *Iterator) readByte() (ret byte) { + if iter.head == iter.tail { + if iter.loadMore() { + ret = iter.buf[iter.head] + iter.head++ + return ret + } + return 0 + } + ret = iter.buf[iter.head] + iter.head++ + return ret +} + +func (iter *Iterator) loadMore() bool { + if iter.reader == nil { + if iter.Error == nil { + iter.head = iter.tail + iter.Error = io.EOF + } + return false + } + if iter.captured != nil { + iter.captured = append(iter.captured, + iter.buf[iter.captureStartedAt:iter.tail]...) + iter.captureStartedAt = 0 + } + for { + n, err := iter.reader.Read(iter.buf) + if n == 0 { + if err != nil { + if iter.Error == nil { + iter.Error = err + } + return false + } + } else { + iter.head = 0 + iter.tail = n + return true + } + } +} + +func (iter *Iterator) unreadByte() { + if iter.Error != nil { + return + } + iter.head-- + return +} + +// Read read the next JSON element as generic interface{}. +func (iter *Iterator) Read() interface{} { + valueType := iter.WhatIsNext() + switch valueType { + case StringValue: + return iter.ReadString() + case NumberValue: + if iter.cfg.configBeforeFrozen.UseNumber { + return json.Number(iter.readNumberAsString()) + } + return iter.ReadFloat64() + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + return nil + case BoolValue: + return iter.ReadBool() + case ArrayValue: + arr := []interface{}{} + iter.ReadArrayCB(func(iter *Iterator) bool { + var elem interface{} + iter.ReadVal(&elem) + arr = append(arr, elem) + return true + }) + return arr + case ObjectValue: + obj := map[string]interface{}{} + iter.ReadMapCB(func(Iter *Iterator, field string) bool { + var elem interface{} + iter.ReadVal(&elem) + obj[field] = elem + return true + }) + return obj + default: + iter.ReportError("Read", fmt.Sprintf("unexpected value type: %v", valueType)) + return nil + } +} diff --git a/vendor/github.com/json-iterator/go/iter_array.go b/vendor/github.com/json-iterator/go/iter_array.go new file mode 100644 index 000000000..6188cb457 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_array.go @@ -0,0 +1,58 @@ +package jsoniter + +// ReadArray read array element, tells if the array has more element to read. +func (iter *Iterator) ReadArray() (ret bool) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return false // null + case '[': + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + return true + } + return false + case ']': + return false + case ',': + return true + default: + iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c})) + return + } +} + +// ReadArrayCB read array with callback +func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) { + c := iter.nextToken() + if c == '[' { + c = iter.nextToken() + if c != ']' { + iter.unreadByte() + if !callback(iter) { + return false + } + c = iter.nextToken() + for c == ',' { + if !callback(iter) { + return false + } + c = iter.nextToken() + } + if c != ']' { + iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c})) + return false + } + return true + } + return true + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c})) + return false +} diff --git a/vendor/github.com/json-iterator/go/iter_float.go b/vendor/github.com/json-iterator/go/iter_float.go new file mode 100644 index 000000000..4f883c095 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_float.go @@ -0,0 +1,347 @@ +package jsoniter + +import ( + "encoding/json" + "io" + "math/big" + "strconv" + "strings" + "unsafe" +) + +var floatDigits []int8 + +const invalidCharForNumber = int8(-1) +const endOfNumber = int8(-2) +const dotInNumber = int8(-3) + +func init() { + floatDigits = make([]int8, 256) + for i := 0; i < len(floatDigits); i++ { + floatDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + floatDigits[i] = i - int8('0') + } + floatDigits[','] = endOfNumber + floatDigits[']'] = endOfNumber + floatDigits['}'] = endOfNumber + floatDigits[' '] = endOfNumber + floatDigits['\t'] = endOfNumber + floatDigits['\n'] = endOfNumber + floatDigits['.'] = dotInNumber +} + +// ReadBigFloat read big.Float +func (iter *Iterator) ReadBigFloat() (ret *big.Float) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + prec := 64 + if len(str) > prec { + prec = len(str) + } + val, _, err := big.ParseFloat(str, 10, uint(prec), big.ToZero) + if err != nil { + iter.Error = err + return nil + } + return val +} + +// ReadBigInt read big.Int +func (iter *Iterator) ReadBigInt() (ret *big.Int) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return nil + } + ret = big.NewInt(0) + var success bool + ret, success = ret.SetString(str, 10) + if !success { + iter.ReportError("ReadBigInt", "invalid big int") + return nil + } + return ret +} + +//ReadFloat32 read float32 +func (iter *Iterator) ReadFloat32() (ret float32) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat32() + } + iter.unreadByte() + return iter.readPositiveFloat32() +} + +func (iter *Iterator) readPositiveFloat32() (ret float32) { + value := uint64(0) + c := byte(' ') + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c = iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.ReportError("readFloat32", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat32", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat32SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat32", "leading zero is invalid") + return + } + } + value = uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat32SlowPath() + case endOfNumber: + iter.head = i + return float32(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat32SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float32(float64(value) / float64(pow10[decimalPlaces])) + } + // too many decimal places + return iter.readFloat32SlowPath() + case invalidCharForNumber: + fallthrough + case dotInNumber: + return iter.readFloat32SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat32SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat32SlowPath() +} + +func (iter *Iterator) readNumberAsString() (ret string) { + strBuf := [16]byte{} + str := strBuf[0:0] +load_loop: + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '+', '-', '.', 'e', 'E', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + str = append(str, c) + continue + default: + iter.head = i + break load_loop + } + } + if !iter.loadMore() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + return + } + if len(str) == 0 { + iter.ReportError("readNumberAsString", "invalid number") + } + return *(*string)(unsafe.Pointer(&str)) +} + +func (iter *Iterator) readFloat32SlowPath() (ret float32) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat32SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 32) + if err != nil { + iter.Error = err + return + } + return float32(val) +} + +// ReadFloat64 read float64 +func (iter *Iterator) ReadFloat64() (ret float64) { + c := iter.nextToken() + if c == '-' { + return -iter.readPositiveFloat64() + } + iter.unreadByte() + return iter.readPositiveFloat64() +} + +func (iter *Iterator) readPositiveFloat64() (ret float64) { + value := uint64(0) + c := byte(' ') + i := iter.head + // first char + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c = iter.buf[i] + i++ + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.ReportError("readFloat64", "empty number") + return + case dotInNumber: + iter.ReportError("readFloat64", "leading dot is invalid") + return + case 0: + if i == iter.tail { + return iter.readFloat64SlowPath() + } + c = iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.ReportError("readFloat64", "leading zero is invalid") + return + } + } + value = uint64(ind) + // chars before dot +non_decimal_loop: + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case invalidCharForNumber: + return iter.readFloat64SlowPath() + case endOfNumber: + iter.head = i + return float64(value) + case dotInNumber: + break non_decimal_loop + } + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) // value = value * 10 + ind; + } + // chars after dot + if c == '.' { + i++ + decimalPlaces := 0 + if i == iter.tail { + return iter.readFloat64SlowPath() + } + for ; i < iter.tail; i++ { + c = iter.buf[i] + ind := floatDigits[c] + switch ind { + case endOfNumber: + if decimalPlaces > 0 && decimalPlaces < len(pow10) { + iter.head = i + return float64(value) / float64(pow10[decimalPlaces]) + } + // too many decimal places + return iter.readFloat64SlowPath() + case invalidCharForNumber: + fallthrough + case dotInNumber: + return iter.readFloat64SlowPath() + } + decimalPlaces++ + if value > uint64SafeToMultiple10 { + return iter.readFloat64SlowPath() + } + value = (value << 3) + (value << 1) + uint64(ind) + } + } + return iter.readFloat64SlowPath() +} + +func (iter *Iterator) readFloat64SlowPath() (ret float64) { + str := iter.readNumberAsString() + if iter.Error != nil && iter.Error != io.EOF { + return + } + errMsg := validateFloat(str) + if errMsg != "" { + iter.ReportError("readFloat64SlowPath", errMsg) + return + } + val, err := strconv.ParseFloat(str, 64) + if err != nil { + iter.Error = err + return + } + return val +} + +func validateFloat(str string) string { + // strconv.ParseFloat is not validating `1.` or `1.e1` + if len(str) == 0 { + return "empty number" + } + if str[0] == '-' { + return "-- is not valid" + } + dotPos := strings.IndexByte(str, '.') + if dotPos != -1 { + if dotPos == len(str)-1 { + return "dot can not be last character" + } + switch str[dotPos+1] { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + return "missing digit after dot" + } + } + return "" +} + +// ReadNumber read json.Number +func (iter *Iterator) ReadNumber() (ret json.Number) { + return json.Number(iter.readNumberAsString()) +} diff --git a/vendor/github.com/json-iterator/go/iter_int.go b/vendor/github.com/json-iterator/go/iter_int.go new file mode 100644 index 000000000..214232035 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_int.go @@ -0,0 +1,345 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var intDigits []int8 + +const uint32SafeToMultiply10 = uint32(0xffffffff)/10 - 1 +const uint64SafeToMultiple10 = uint64(0xffffffffffffffff)/10 - 1 + +func init() { + intDigits = make([]int8, 256) + for i := 0; i < len(intDigits); i++ { + intDigits[i] = invalidCharForNumber + } + for i := int8('0'); i <= int8('9'); i++ { + intDigits[i] = i - int8('0') + } +} + +// ReadUint read uint +func (iter *Iterator) ReadUint() uint { + if strconv.IntSize == 32 { + return uint(iter.ReadUint32()) + } + return uint(iter.ReadUint64()) +} + +// ReadInt read int +func (iter *Iterator) ReadInt() int { + if strconv.IntSize == 32 { + return int(iter.ReadInt32()) + } + return int(iter.ReadInt64()) +} + +// ReadInt8 read int8 +func (iter *Iterator) ReadInt8() (ret int8) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt8+1 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int8(val) + } + val := iter.readUint32(c) + if val > math.MaxInt8 { + iter.ReportError("ReadInt8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int8(val) +} + +// ReadUint8 read uint8 +func (iter *Iterator) ReadUint8() (ret uint8) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint8 { + iter.ReportError("ReadUint8", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint8(val) +} + +// ReadInt16 read int16 +func (iter *Iterator) ReadInt16() (ret int16) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt16+1 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int16(val) + } + val := iter.readUint32(c) + if val > math.MaxInt16 { + iter.ReportError("ReadInt16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int16(val) +} + +// ReadUint16 read uint16 +func (iter *Iterator) ReadUint16() (ret uint16) { + val := iter.readUint32(iter.nextToken()) + if val > math.MaxUint16 { + iter.ReportError("ReadUint16", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return uint16(val) +} + +// ReadInt32 read int32 +func (iter *Iterator) ReadInt32() (ret int32) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint32(iter.readByte()) + if val > math.MaxInt32+1 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return -int32(val) + } + val := iter.readUint32(c) + if val > math.MaxInt32 { + iter.ReportError("ReadInt32", "overflow: "+strconv.FormatInt(int64(val), 10)) + return + } + return int32(val) +} + +// ReadUint32 read uint32 +func (iter *Iterator) ReadUint32() (ret uint32) { + return iter.readUint32(iter.nextToken()) +} + +func (iter *Iterator) readUint32(c byte) (ret uint32) { + ind := intDigits[c] + if ind == 0 { + iter.assertInteger() + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint32", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint32(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint32(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint32(ind2)*10 + uint32(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + if value > uint32SafeToMultiply10 { + value2 := (value << 3) + (value << 1) + uint32(ind) + if value2 < value { + iter.ReportError("readUint32", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint32(ind) + } + if !iter.loadMore() { + iter.assertInteger() + return value + } + } +} + +// ReadInt64 read int64 +func (iter *Iterator) ReadInt64() (ret int64) { + c := iter.nextToken() + if c == '-' { + val := iter.readUint64(iter.readByte()) + if val > math.MaxInt64+1 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return -int64(val) + } + val := iter.readUint64(c) + if val > math.MaxInt64 { + iter.ReportError("ReadInt64", "overflow: "+strconv.FormatUint(uint64(val), 10)) + return + } + return int64(val) +} + +// ReadUint64 read uint64 +func (iter *Iterator) ReadUint64() uint64 { + return iter.readUint64(iter.nextToken()) +} + +func (iter *Iterator) readUint64(c byte) (ret uint64) { + ind := intDigits[c] + if ind == 0 { + iter.assertInteger() + return 0 // single zero + } + if ind == invalidCharForNumber { + iter.ReportError("readUint64", "unexpected character: "+string([]byte{byte(ind)})) + return + } + value := uint64(ind) + if iter.tail-iter.head > 10 { + i := iter.head + ind2 := intDigits[iter.buf[i]] + if ind2 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + i++ + ind3 := intDigits[iter.buf[i]] + if ind3 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10 + uint64(ind2) + } + //iter.head = i + 1 + //value = value * 100 + uint32(ind2) * 10 + uint32(ind3) + i++ + ind4 := intDigits[iter.buf[i]] + if ind4 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100 + uint64(ind2)*10 + uint64(ind3) + } + i++ + ind5 := intDigits[iter.buf[i]] + if ind5 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4) + } + i++ + ind6 := intDigits[iter.buf[i]] + if ind6 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5) + } + i++ + ind7 := intDigits[iter.buf[i]] + if ind7 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6) + } + i++ + ind8 := intDigits[iter.buf[i]] + if ind8 == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7) + } + i++ + ind9 := intDigits[iter.buf[i]] + value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8) + iter.head = i + if ind9 == invalidCharForNumber { + iter.assertInteger() + return value + } + } + for { + for i := iter.head; i < iter.tail; i++ { + ind = intDigits[iter.buf[i]] + if ind == invalidCharForNumber { + iter.head = i + iter.assertInteger() + return value + } + if value > uint64SafeToMultiple10 { + value2 := (value << 3) + (value << 1) + uint64(ind) + if value2 < value { + iter.ReportError("readUint64", "overflow") + return + } + value = value2 + continue + } + value = (value << 3) + (value << 1) + uint64(ind) + } + if !iter.loadMore() { + iter.assertInteger() + return value + } + } +} + +func (iter *Iterator) assertInteger() { + if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' { + iter.ReportError("assertInteger", "can not decode float as int") + } +} diff --git a/vendor/github.com/json-iterator/go/iter_object.go b/vendor/github.com/json-iterator/go/iter_object.go new file mode 100644 index 000000000..1c5757671 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_object.go @@ -0,0 +1,251 @@ +package jsoniter + +import ( + "fmt" + "strings" +) + +// ReadObject read one field from object. +// If object ended, returns empty string. +// Otherwise, returns the field name. +func (iter *Iterator) ReadObject() (ret string) { + c := iter.nextToken() + switch c { + case 'n': + iter.skipThreeBytes('u', 'l', 'l') + return "" // null + case '{': + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + } + if c == '}' { + return "" // end of object + } + iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c})) + return + case ',': + field := iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + return field + case '}': + return "" // end of object + default: + iter.ReportError("ReadObject", fmt.Sprintf(`expect { or , or } or n, but found %s`, string([]byte{c}))) + return + } +} + +// CaseInsensitive +func (iter *Iterator) readFieldHash() int64 { + hash := int64(0x811c9dc5) + c := iter.nextToken() + if c != '"' { + iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c})) + return 0 + } + for { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + b := iter.buf[i] + if b == '\\' { + iter.head = i + for _, b := range iter.readStringSlowPath() { + if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash + } + if b == '"' { + iter.head = i + 1 + c = iter.nextToken() + if c != ':' { + iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c})) + return 0 + } + return hash + } + if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive { + b += 'a' - 'A' + } + hash ^= int64(b) + hash *= 0x1000193 + } + if !iter.loadMore() { + iter.ReportError("readFieldHash", `incomplete field name`) + return 0 + } + } +} + +func calcHash(str string, caseSensitive bool) int64 { + if !caseSensitive { + str = strings.ToLower(str) + } + hash := int64(0x811c9dc5) + for _, b := range []byte(str) { + hash ^= int64(b) + hash *= 0x1000193 + } + return int64(hash) +} + +// ReadObjectCB read object with callback, the key is ascii only and field name not copied +func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + var field string + if c == '{' { + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadObjectCB", `object not ended with }`) + return false + } + return true + } + if c == '}' { + return true + } + iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c})) + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +// ReadMapCB read map with callback, the key can be any string +func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '"' { + iter.unreadByte() + field := iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return false + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + for c == ',' { + field = iter.ReadString() + if iter.nextToken() != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return false + } + if !callback(iter, field) { + return false + } + c = iter.nextToken() + } + if c != '}' { + iter.ReportError("ReadMapCB", `object not ended with }`) + return false + } + return true + } + if c == '}' { + return true + } + iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) + return false + } + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return true // null + } + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectStart() bool { + c := iter.nextToken() + if c == '{' { + c = iter.nextToken() + if c == '}' { + return false + } + iter.unreadByte() + return true + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return false + } + iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c})) + return false +} + +func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) { + str := iter.ReadStringAsSlice() + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if iter.buf[iter.head] != ':' { + iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]})) + return + } + iter.head++ + if iter.skipWhitespacesWithoutLoadMore() { + if ret == nil { + ret = make([]byte, len(str)) + copy(ret, str) + } + if !iter.loadMore() { + return + } + } + if ret == nil { + return str + } + return ret +} diff --git a/vendor/github.com/json-iterator/go/iter_skip.go b/vendor/github.com/json-iterator/go/iter_skip.go new file mode 100644 index 000000000..f58beb913 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip.go @@ -0,0 +1,129 @@ +package jsoniter + +import "fmt" + +// ReadNil reads a json object as nil and +// returns whether it's a nil or not +func (iter *Iterator) ReadNil() (ret bool) { + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') // null + return true + } + iter.unreadByte() + return false +} + +// ReadBool reads a json object as BoolValue +func (iter *Iterator) ReadBool() (ret bool) { + c := iter.nextToken() + if c == 't' { + iter.skipThreeBytes('r', 'u', 'e') + return true + } + if c == 'f' { + iter.skipFourBytes('a', 'l', 's', 'e') + return false + } + iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c})) + return +} + +// SkipAndReturnBytes skip next JSON element, and return its content as []byte. +// The []byte can be kept, it is a copy of data. +func (iter *Iterator) SkipAndReturnBytes() []byte { + iter.startCapture(iter.head) + iter.Skip() + return iter.stopCapture() +} + +type captureBuffer struct { + startedAt int + captured []byte +} + +func (iter *Iterator) startCapture(captureStartedAt int) { + if iter.captured != nil { + panic("already in capture mode") + } + iter.captureStartedAt = captureStartedAt + iter.captured = make([]byte, 0, 32) +} + +func (iter *Iterator) stopCapture() []byte { + if iter.captured == nil { + panic("not in capture mode") + } + captured := iter.captured + remaining := iter.buf[iter.captureStartedAt:iter.head] + iter.captureStartedAt = -1 + iter.captured = nil + if len(captured) == 0 { + copied := make([]byte, len(remaining)) + copy(copied, remaining) + return copied + } + captured = append(captured, remaining...) + return captured +} + +// Skip skips a json object and positions to relatively the next json object +func (iter *Iterator) Skip() { + c := iter.nextToken() + switch c { + case '"': + iter.skipString() + case 'n': + iter.skipThreeBytes('u', 'l', 'l') // null + case 't': + iter.skipThreeBytes('r', 'u', 'e') // true + case 'f': + iter.skipFourBytes('a', 'l', 's', 'e') // false + case '0': + iter.unreadByte() + iter.ReadFloat32() + case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': + iter.skipNumber() + case '[': + iter.skipArray() + case '{': + iter.skipObject() + default: + iter.ReportError("Skip", fmt.Sprintf("do not know how to skip: %v", c)) + return + } +} + +func (iter *Iterator) skipFourBytes(b1, b2, b3, b4 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } + if iter.readByte() != b4 { + iter.ReportError("skipFourBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3, b4}))) + return + } +} + +func (iter *Iterator) skipThreeBytes(b1, b2, b3 byte) { + if iter.readByte() != b1 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b2 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } + if iter.readByte() != b3 { + iter.ReportError("skipThreeBytes", fmt.Sprintf("expect %s", string([]byte{b1, b2, b3}))) + return + } +} diff --git a/vendor/github.com/json-iterator/go/iter_skip_sloppy.go b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go new file mode 100644 index 000000000..8fcdc3b69 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip_sloppy.go @@ -0,0 +1,144 @@ +//+build jsoniter_sloppy + +package jsoniter + +// sloppy but faster implementation, do not validate the input json + +func (iter *Iterator) skipNumber() { + for { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case ' ', '\n', '\r', '\t', ',', '}', ']': + iter.head = i + return + } + } + if !iter.loadMore() { + return + } + } +} + +func (iter *Iterator) skipArray() { + level := 1 + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '[': // If open symbol, increase level + level++ + case ']': // If close symbol, increase level + level-- + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete array") + return + } + } +} + +func (iter *Iterator) skipObject() { + level := 1 + for { + for i := iter.head; i < iter.tail; i++ { + switch iter.buf[i] { + case '"': // If inside string, skip it + iter.head = i + 1 + iter.skipString() + i = iter.head - 1 // it will be i++ soon + case '{': // If open symbol, increase level + level++ + case '}': // If close symbol, increase level + level-- + + // If we have returned to the original level, we're done + if level == 0 { + iter.head = i + 1 + return + } + } + } + if !iter.loadMore() { + iter.ReportError("skipObject", "incomplete object") + return + } + } +} + +func (iter *Iterator) skipString() { + for { + end, escaped := iter.findStringEnd() + if end == -1 { + if !iter.loadMore() { + iter.ReportError("skipString", "incomplete string") + return + } + if escaped { + iter.head = 1 // skip the first char as last char read is \ + } + } else { + iter.head = end + return + } + } +} + +// adapted from: https://github.com/buger/jsonparser/blob/master/parser.go +// Tries to find the end of string +// Support if string contains escaped quote symbols. +func (iter *Iterator) findStringEnd() (int, bool) { + escaped := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + if !escaped { + return i + 1, false + } + j := i - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return i + 1, true + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + } + } else if c == '\\' { + escaped = true + } + } + j := iter.tail - 1 + for { + if j < iter.head || iter.buf[j] != '\\' { + // even number of backslashes + // either end of buffer, or " found + return -1, false // do not end with \ + } + j-- + if j < iter.head || iter.buf[j] != '\\' { + // odd number of backslashes + // it is \" or \\\" + break + } + j-- + + } + return -1, true // end with \ +} diff --git a/vendor/github.com/json-iterator/go/iter_skip_strict.go b/vendor/github.com/json-iterator/go/iter_skip_strict.go new file mode 100644 index 000000000..f67bc2e83 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_skip_strict.go @@ -0,0 +1,89 @@ +//+build !jsoniter_sloppy + +package jsoniter + +import "fmt" + +func (iter *Iterator) skipNumber() { + if !iter.trySkipNumber() { + iter.unreadByte() + iter.ReadFloat32() + } +} + +func (iter *Iterator) trySkipNumber() bool { + dotFound := false + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + case '.': + if dotFound { + iter.ReportError("validateNumber", `more than one dot found in number`) + return true // already failed + } + if i+1 == iter.tail { + return false + } + c = iter.buf[i+1] + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + iter.ReportError("validateNumber", `missing digit after dot`) + return true // already failed + } + dotFound = true + default: + switch c { + case ',', ']', '}', ' ', '\t', '\n', '\r': + if iter.head == i { + return false // if - without following digits + } + iter.head = i + return true // must be valid + } + return false // may be invalid + } + } + return false +} + +func (iter *Iterator) skipString() { + if !iter.trySkipString() { + iter.unreadByte() + iter.ReadString() + } +} + +func (iter *Iterator) trySkipString() bool { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + iter.head = i + 1 + return true // valid + } else if c == '\\' { + return false + } else if c < ' ' { + iter.ReportError("trySkipString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return true // already failed + } + } + return false +} + +func (iter *Iterator) skipObject() { + iter.unreadByte() + iter.ReadObjectCB(func(iter *Iterator, field string) bool { + iter.Skip() + return true + }) +} + +func (iter *Iterator) skipArray() { + iter.unreadByte() + iter.ReadArrayCB(func(iter *Iterator) bool { + iter.Skip() + return true + }) +} diff --git a/vendor/github.com/json-iterator/go/iter_str.go b/vendor/github.com/json-iterator/go/iter_str.go new file mode 100644 index 000000000..adc487ea8 --- /dev/null +++ b/vendor/github.com/json-iterator/go/iter_str.go @@ -0,0 +1,215 @@ +package jsoniter + +import ( + "fmt" + "unicode/utf16" +) + +// ReadString read string from iterator +func (iter *Iterator) ReadString() (ret string) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + c := iter.buf[i] + if c == '"' { + ret = string(iter.buf[iter.head:i]) + iter.head = i + 1 + return ret + } else if c == '\\' { + break + } else if c < ' ' { + iter.ReportError("ReadString", + fmt.Sprintf(`invalid control character found: %d`, c)) + return + } + } + return iter.readStringSlowPath() + } else if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return "" + } + iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readStringSlowPath() (ret string) { + var str []byte + var c byte + for iter.Error == nil { + c = iter.readByte() + if c == '"' { + return string(str) + } + if c == '\\' { + c = iter.readByte() + str = iter.readEscapedChar(c, str) + } else { + str = append(str, c) + } + } + iter.ReportError("readStringSlowPath", "unexpected end of input") + return +} + +func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte { + switch c { + case 'u': + r := iter.readU4() + if utf16.IsSurrogate(r) { + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != '\\' { + iter.unreadByte() + str = appendRune(str, r) + return str + } + c = iter.readByte() + if iter.Error != nil { + return nil + } + if c != 'u' { + str = appendRune(str, r) + return iter.readEscapedChar(c, str) + } + r2 := iter.readU4() + if iter.Error != nil { + return nil + } + combined := utf16.DecodeRune(r, r2) + if combined == '\uFFFD' { + str = appendRune(str, r) + str = appendRune(str, r2) + } else { + str = appendRune(str, combined) + } + } else { + str = appendRune(str, r) + } + case '"': + str = append(str, '"') + case '\\': + str = append(str, '\\') + case '/': + str = append(str, '/') + case 'b': + str = append(str, '\b') + case 'f': + str = append(str, '\f') + case 'n': + str = append(str, '\n') + case 'r': + str = append(str, '\r') + case 't': + str = append(str, '\t') + default: + iter.ReportError("readEscapedChar", + `invalid escape char after \`) + return nil + } + return str +} + +// ReadStringAsSlice read string from iterator without copying into string form. +// The []byte can not be kept, as it will change after next iterator call. +func (iter *Iterator) ReadStringAsSlice() (ret []byte) { + c := iter.nextToken() + if c == '"' { + for i := iter.head; i < iter.tail; i++ { + // require ascii string and no escape + // for: field name, base64, number + if iter.buf[i] == '"' { + // fast path: reuse the underlying buffer + ret = iter.buf[iter.head:i] + iter.head = i + 1 + return ret + } + } + readLen := iter.tail - iter.head + copied := make([]byte, readLen, readLen*2) + copy(copied, iter.buf[iter.head:iter.tail]) + iter.head = iter.tail + for iter.Error == nil { + c := iter.readByte() + if c == '"' { + return copied + } + copied = append(copied, c) + } + return copied + } + iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c})) + return +} + +func (iter *Iterator) readU4() (ret rune) { + for i := 0; i < 4; i++ { + c := iter.readByte() + if iter.Error != nil { + return + } + if c >= '0' && c <= '9' { + ret = ret*16 + rune(c-'0') + } else if c >= 'a' && c <= 'f' { + ret = ret*16 + rune(c-'a'+10) + } else if c >= 'A' && c <= 'F' { + ret = ret*16 + rune(c-'A'+10) + } else { + iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c})) + return + } + } + return ret +} + +const ( + t1 = 0x00 // 0000 0000 + tx = 0x80 // 1000 0000 + t2 = 0xC0 // 1100 0000 + t3 = 0xE0 // 1110 0000 + t4 = 0xF0 // 1111 0000 + t5 = 0xF8 // 1111 1000 + + maskx = 0x3F // 0011 1111 + mask2 = 0x1F // 0001 1111 + mask3 = 0x0F // 0000 1111 + mask4 = 0x07 // 0000 0111 + + rune1Max = 1<<7 - 1 + rune2Max = 1<<11 - 1 + rune3Max = 1<<16 - 1 + + surrogateMin = 0xD800 + surrogateMax = 0xDFFF + + maxRune = '\U0010FFFF' // Maximum valid Unicode code point. + runeError = '\uFFFD' // the "error" Rune or "Unicode replacement character" +) + +func appendRune(p []byte, r rune) []byte { + // Negative values are erroneous. Making it unsigned addresses the problem. + switch i := uint32(r); { + case i <= rune1Max: + p = append(p, byte(r)) + return p + case i <= rune2Max: + p = append(p, t2|byte(r>>6)) + p = append(p, tx|byte(r)&maskx) + return p + case i > maxRune, surrogateMin <= i && i <= surrogateMax: + r = runeError + fallthrough + case i <= rune3Max: + p = append(p, t3|byte(r>>12)) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + default: + p = append(p, t4|byte(r>>18)) + p = append(p, tx|byte(r>>12)&maskx) + p = append(p, tx|byte(r>>6)&maskx) + p = append(p, tx|byte(r)&maskx) + return p + } +} diff --git a/vendor/github.com/json-iterator/go/jsoniter.go b/vendor/github.com/json-iterator/go/jsoniter.go new file mode 100644 index 000000000..c2934f916 --- /dev/null +++ b/vendor/github.com/json-iterator/go/jsoniter.go @@ -0,0 +1,18 @@ +// Package jsoniter implements encoding and decoding of JSON as defined in +// RFC 4627 and provides interfaces with identical syntax of standard lib encoding/json. +// Converting from encoding/json to jsoniter is no more than replacing the package with jsoniter +// and variable type declarations (if any). +// jsoniter interfaces gives 100% compatibility with code using standard lib. +// +// "JSON and Go" +// (https://golang.org/doc/articles/json_and_go.html) +// gives a description of how Marshal/Unmarshal operate +// between arbitrary or predefined json objects and bytes, +// and it applies to jsoniter.Marshal/Unmarshal as well. +// +// Besides, jsoniter.Iterator provides a different set of interfaces +// iterating given bytes/string/reader +// and yielding parsed elements one by one. +// This set of interfaces reads input as required and gives +// better performance. +package jsoniter diff --git a/vendor/github.com/json-iterator/go/pool.go b/vendor/github.com/json-iterator/go/pool.go new file mode 100644 index 000000000..e2389b56c --- /dev/null +++ b/vendor/github.com/json-iterator/go/pool.go @@ -0,0 +1,42 @@ +package jsoniter + +import ( + "io" +) + +// IteratorPool a thread safe pool of iterators with same configuration +type IteratorPool interface { + BorrowIterator(data []byte) *Iterator + ReturnIterator(iter *Iterator) +} + +// StreamPool a thread safe pool of streams with same configuration +type StreamPool interface { + BorrowStream(writer io.Writer) *Stream + ReturnStream(stream *Stream) +} + +func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream { + stream := cfg.streamPool.Get().(*Stream) + stream.Reset(writer) + return stream +} + +func (cfg *frozenConfig) ReturnStream(stream *Stream) { + stream.out = nil + stream.Error = nil + stream.Attachment = nil + cfg.streamPool.Put(stream) +} + +func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator { + iter := cfg.iteratorPool.Get().(*Iterator) + iter.ResetBytes(data) + return iter +} + +func (cfg *frozenConfig) ReturnIterator(iter *Iterator) { + iter.Error = nil + iter.Attachment = nil + cfg.iteratorPool.Put(iter) +} diff --git a/vendor/github.com/json-iterator/go/reflect.go b/vendor/github.com/json-iterator/go/reflect.go new file mode 100644 index 000000000..4459e203f --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect.go @@ -0,0 +1,332 @@ +package jsoniter + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/modern-go/reflect2" +) + +// ValDecoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValDecoder with json.Decoder. +// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link). +// +// Reflection on type to create decoders, which is then cached +// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions +// 1. create instance of new value, for example *int will need a int to be allocated +// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New +// 3. assignment to map, both key and value will be reflect.Value +// For a simple struct binding, it will be reflect.Value free and allocation free +type ValDecoder interface { + Decode(ptr unsafe.Pointer, iter *Iterator) +} + +// ValEncoder is an internal type registered to cache as needed. +// Don't confuse jsoniter.ValEncoder with json.Encoder. +// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link). +type ValEncoder interface { + IsEmpty(ptr unsafe.Pointer) bool + Encode(ptr unsafe.Pointer, stream *Stream) +} + +type checkIsEmpty interface { + IsEmpty(ptr unsafe.Pointer) bool +} + +type ctx struct { + *frozenConfig + prefix string + encoders map[reflect2.Type]ValEncoder + decoders map[reflect2.Type]ValDecoder +} + +func (b *ctx) caseSensitive() bool { + if b.frozenConfig == nil { + // default is case-insensitive + return false + } + return b.frozenConfig.caseSensitive +} + +func (b *ctx) append(prefix string) *ctx { + return &ctx{ + frozenConfig: b.frozenConfig, + prefix: b.prefix + " " + prefix, + encoders: b.encoders, + decoders: b.decoders, + } +} + +// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal +func (iter *Iterator) ReadVal(obj interface{}) { + cacheKey := reflect2.RTypeOf(obj) + decoder := iter.cfg.getDecoderFromCache(cacheKey) + if decoder == nil { + typ := reflect2.TypeOf(obj) + if typ.Kind() != reflect.Ptr { + iter.ReportError("ReadVal", "can only unmarshal into pointer") + return + } + decoder = iter.cfg.DecoderOf(typ) + } + ptr := reflect2.PtrOf(obj) + if ptr == nil { + iter.ReportError("ReadVal", "can not read into nil pointer") + return + } + decoder.Decode(ptr, iter) +} + +// WriteVal copy the go interface into underlying JSON, same as json.Marshal +func (stream *Stream) WriteVal(val interface{}) { + if nil == val { + stream.WriteNil() + return + } + cacheKey := reflect2.RTypeOf(val) + encoder := stream.cfg.getEncoderFromCache(cacheKey) + if encoder == nil { + typ := reflect2.TypeOf(val) + encoder = stream.cfg.EncoderOf(typ) + } + encoder.Encode(reflect2.PtrOf(val), stream) +} + +func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder { + cacheKey := typ.RType() + decoder := cfg.getDecoderFromCache(cacheKey) + if decoder != nil { + return decoder + } + ctx := &ctx{ + frozenConfig: cfg, + prefix: "", + decoders: map[reflect2.Type]ValDecoder{}, + encoders: map[reflect2.Type]ValEncoder{}, + } + ptrType := typ.(*reflect2.UnsafePtrType) + decoder = decoderOfType(ctx, ptrType.Elem()) + cfg.addDecoderToCache(cacheKey, decoder) + return decoder +} + +func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := getTypeDecoderFromExtension(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfType(ctx, typ) + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) + for _, extension := range ctx.extraExtensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + return decoder +} + +func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := ctx.decoders[typ] + if decoder != nil { + return decoder + } + placeholder := &placeholderDecoder{} + ctx.decoders[typ] = placeholder + decoder = _createDecoderOfType(ctx, typ) + placeholder.decoder = decoder + return decoder +} + +func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := createDecoderOfJsonRawMessage(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfJsonNumber(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfMarshaler(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfAny(ctx, typ) + if decoder != nil { + return decoder + } + decoder = createDecoderOfNative(ctx, typ) + if decoder != nil { + return decoder + } + switch typ.Kind() { + case reflect.Interface: + ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType) + if isIFace { + return &ifaceDecoder{valType: ifaceType} + } + return &efaceDecoder{} + case reflect.Struct: + return decoderOfStruct(ctx, typ) + case reflect.Array: + return decoderOfArray(ctx, typ) + case reflect.Slice: + return decoderOfSlice(ctx, typ) + case reflect.Map: + return decoderOfMap(ctx, typ) + case reflect.Ptr: + return decoderOfOptional(ctx, typ) + default: + return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} + } +} + +func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder { + cacheKey := typ.RType() + encoder := cfg.getEncoderFromCache(cacheKey) + if encoder != nil { + return encoder + } + ctx := &ctx{ + frozenConfig: cfg, + prefix: "", + decoders: map[reflect2.Type]ValDecoder{}, + encoders: map[reflect2.Type]ValEncoder{}, + } + encoder = encoderOfType(ctx, typ) + if typ.LikePtr() { + encoder = &onePtrEncoder{encoder} + } + cfg.addEncoderToCache(cacheKey, encoder) + return encoder +} + +type onePtrEncoder struct { + encoder ValEncoder +} + +func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +} + +func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := getTypeEncoderFromExtension(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfType(ctx, typ) + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) + for _, extension := range ctx.extraExtensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + return encoder +} + +func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := ctx.encoders[typ] + if encoder != nil { + return encoder + } + placeholder := &placeholderEncoder{} + ctx.encoders[typ] = placeholder + encoder = _createEncoderOfType(ctx, typ) + placeholder.encoder = encoder + return encoder +} +func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := createEncoderOfJsonRawMessage(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfJsonNumber(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfMarshaler(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfAny(ctx, typ) + if encoder != nil { + return encoder + } + encoder = createEncoderOfNative(ctx, typ) + if encoder != nil { + return encoder + } + kind := typ.Kind() + switch kind { + case reflect.Interface: + return &dynamicEncoder{typ} + case reflect.Struct: + return encoderOfStruct(ctx, typ) + case reflect.Array: + return encoderOfArray(ctx, typ) + case reflect.Slice: + return encoderOfSlice(ctx, typ) + case reflect.Map: + return encoderOfMap(ctx, typ) + case reflect.Ptr: + return encoderOfOptional(ctx, typ) + default: + return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())} + } +} + +type lazyErrorDecoder struct { + err error +} + +func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.WhatIsNext() != NilValue { + if iter.Error == nil { + iter.Error = decoder.err + } + } else { + iter.Skip() + } +} + +type lazyErrorEncoder struct { + err error +} + +func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if ptr == nil { + stream.WriteNil() + } else if stream.Error == nil { + stream.Error = encoder.err + } +} + +func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type placeholderDecoder struct { + decoder ValDecoder +} + +func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.decoder.Decode(ptr, iter) +} + +type placeholderEncoder struct { + encoder ValEncoder +} + +func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(ptr, stream) +} + +func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(ptr) +} diff --git a/vendor/github.com/json-iterator/go/reflect_array.go b/vendor/github.com/json-iterator/go/reflect_array.go new file mode 100644 index 000000000..13a0b7b08 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_array.go @@ -0,0 +1,104 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "unsafe" +) + +func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder { + arrayType := typ.(*reflect2.UnsafeArrayType) + decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) + return &arrayDecoder{arrayType, decoder} +} + +func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder { + arrayType := typ.(*reflect2.UnsafeArrayType) + if arrayType.Len() == 0 { + return emptyArrayEncoder{} + } + encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem()) + return &arrayEncoder{arrayType, encoder} +} + +type emptyArrayEncoder struct{} + +func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyArray() +} + +func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return true +} + +type arrayEncoder struct { + arrayType *reflect2.UnsafeArrayType + elemEncoder ValEncoder +} + +func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteArrayStart() + elemPtr := unsafe.Pointer(ptr) + encoder.elemEncoder.Encode(elemPtr, stream) + for i := 1; i < encoder.arrayType.Len(); i++ { + stream.WriteMore() + elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i) + encoder.elemEncoder.Encode(elemPtr, stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error()) + } +} + +func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type arrayDecoder struct { + arrayType *reflect2.UnsafeArrayType + elemDecoder ValDecoder +} + +func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error()) + } +} + +func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + arrayType := decoder.arrayType + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + return + } + if c != '[' { + iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c})) + return + } + c = iter.nextToken() + if c == ']' { + return + } + iter.unreadByte() + elemPtr := arrayType.UnsafeGetIndex(ptr, 0) + decoder.elemDecoder.Decode(elemPtr, iter) + length := 1 + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + if length >= arrayType.Len() { + iter.Skip() + continue + } + idx := length + length += 1 + elemPtr = arrayType.UnsafeGetIndex(ptr, idx) + decoder.elemDecoder.Decode(elemPtr, iter) + } + if c != ']' { + iter.ReportError("decode array", "expect ], but found "+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_dynamic.go b/vendor/github.com/json-iterator/go/reflect_dynamic.go new file mode 100644 index 000000000..8b6bc8b43 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_dynamic.go @@ -0,0 +1,70 @@ +package jsoniter + +import ( + "github.com/modern-go/reflect2" + "reflect" + "unsafe" +) + +type dynamicEncoder struct { + valType reflect2.Type +} + +func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + stream.WriteVal(obj) +} + +func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.valType.UnsafeIndirect(ptr) == nil +} + +type efaceDecoder struct { +} + +func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + pObj := (*interface{})(ptr) + obj := *pObj + if obj == nil { + *pObj = iter.Read() + return + } + typ := reflect2.TypeOf(obj) + if typ.Kind() != reflect.Ptr { + *pObj = iter.Read() + return + } + ptrType := typ.(*reflect2.UnsafePtrType) + ptrElemType := ptrType.Elem() + if iter.WhatIsNext() == NilValue { + if ptrElemType.Kind() != reflect.Ptr { + iter.skipFourBytes('n', 'u', 'l', 'l') + *pObj = nil + return + } + } + if reflect2.IsNil(obj) { + obj := ptrElemType.New() + iter.ReadVal(obj) + *pObj = obj + return + } + iter.ReadVal(obj) +} + +type ifaceDecoder struct { + valType *reflect2.UnsafeIFaceType +} + +func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew()) + return + } + obj := decoder.valType.UnsafeIndirect(ptr) + if reflect2.IsNil(obj) { + iter.ReportError("decode non empty interface", "can not unmarshal into nil") + return + } + iter.ReadVal(obj) +} diff --git a/vendor/github.com/json-iterator/go/reflect_extension.go b/vendor/github.com/json-iterator/go/reflect_extension.go new file mode 100644 index 000000000..04f68756b --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_extension.go @@ -0,0 +1,483 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "reflect" + "sort" + "strings" + "unicode" + "unsafe" +) + +var typeDecoders = map[string]ValDecoder{} +var fieldDecoders = map[string]ValDecoder{} +var typeEncoders = map[string]ValEncoder{} +var fieldEncoders = map[string]ValEncoder{} +var extensions = []Extension{} + +// StructDescriptor describe how should we encode/decode the struct +type StructDescriptor struct { + Type reflect2.Type + Fields []*Binding +} + +// GetField get one field from the descriptor by its name. +// Can not use map here to keep field orders. +func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding { + for _, binding := range structDescriptor.Fields { + if binding.Field.Name() == fieldName { + return binding + } + } + return nil +} + +// Binding describe how should we encode/decode the struct field +type Binding struct { + levels []int + Field reflect2.StructField + FromNames []string + ToNames []string + Encoder ValEncoder + Decoder ValDecoder +} + +// Extension the one for all SPI. Customize encoding/decoding by specifying alternate encoder/decoder. +// Can also rename fields by UpdateStructDescriptor. +type Extension interface { + UpdateStructDescriptor(structDescriptor *StructDescriptor) + CreateMapKeyDecoder(typ reflect2.Type) ValDecoder + CreateMapKeyEncoder(typ reflect2.Type) ValEncoder + CreateDecoder(typ reflect2.Type) ValDecoder + CreateEncoder(typ reflect2.Type) ValEncoder + DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder + DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder +} + +// DummyExtension embed this type get dummy implementation for all methods of Extension +type DummyExtension struct { +} + +// UpdateStructDescriptor No-op +func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateMapKeyDecoder No-op +func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// CreateDecoder No-op +func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateEncoder No-op +func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type EncoderExtension map[reflect2.Type]ValEncoder + +// UpdateStructDescriptor No-op +func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateDecoder No-op +func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateEncoder get encoder from map +func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return extension[typ] +} + +// CreateMapKeyDecoder No-op +func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type DecoderExtension map[reflect2.Type]ValDecoder + +// UpdateStructDescriptor No-op +func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) { +} + +// CreateMapKeyDecoder No-op +func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder { + return nil +} + +// CreateMapKeyEncoder No-op +func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// CreateDecoder get decoder from map +func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder { + return extension[typ] +} + +// CreateEncoder No-op +func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder { + return nil +} + +// DecorateDecoder No-op +func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder { + return decoder +} + +// DecorateEncoder No-op +func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder { + return encoder +} + +type funcDecoder struct { + fun DecoderFunc +} + +func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.fun(ptr, iter) +} + +type funcEncoder struct { + fun EncoderFunc + isEmptyFunc func(ptr unsafe.Pointer) bool +} + +func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.fun(ptr, stream) +} + +func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool { + if encoder.isEmptyFunc == nil { + return false + } + return encoder.isEmptyFunc(ptr) +} + +// DecoderFunc the function form of TypeDecoder +type DecoderFunc func(ptr unsafe.Pointer, iter *Iterator) + +// EncoderFunc the function form of TypeEncoder +type EncoderFunc func(ptr unsafe.Pointer, stream *Stream) + +// RegisterTypeDecoderFunc register TypeDecoder for a type with function +func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) { + typeDecoders[typ] = &funcDecoder{fun} +} + +// RegisterTypeDecoder register TypeDecoder for a typ +func RegisterTypeDecoder(typ string, decoder ValDecoder) { + typeDecoders[typ] = decoder +} + +// RegisterFieldDecoderFunc register TypeDecoder for a struct field with function +func RegisterFieldDecoderFunc(typ string, field string, fun DecoderFunc) { + RegisterFieldDecoder(typ, field, &funcDecoder{fun}) +} + +// RegisterFieldDecoder register TypeDecoder for a struct field +func RegisterFieldDecoder(typ string, field string, decoder ValDecoder) { + fieldDecoders[fmt.Sprintf("%s/%s", typ, field)] = decoder +} + +// RegisterTypeEncoderFunc register TypeEncoder for a type with encode/isEmpty function +func RegisterTypeEncoderFunc(typ string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + typeEncoders[typ] = &funcEncoder{fun, isEmptyFunc} +} + +// RegisterTypeEncoder register TypeEncoder for a type +func RegisterTypeEncoder(typ string, encoder ValEncoder) { + typeEncoders[typ] = encoder +} + +// RegisterFieldEncoderFunc register TypeEncoder for a struct field with encode/isEmpty function +func RegisterFieldEncoderFunc(typ string, field string, fun EncoderFunc, isEmptyFunc func(unsafe.Pointer) bool) { + RegisterFieldEncoder(typ, field, &funcEncoder{fun, isEmptyFunc}) +} + +// RegisterFieldEncoder register TypeEncoder for a struct field +func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) { + fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder +} + +// RegisterExtension register extension +func RegisterExtension(extension Extension) { + extensions = append(extensions, extension) +} + +func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := _getTypeDecoderFromExtension(ctx, typ) + if decoder != nil { + for _, extension := range extensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + decoder = ctx.decoderExtension.DecorateDecoder(typ, decoder) + for _, extension := range ctx.extraExtensions { + decoder = extension.DecorateDecoder(typ, decoder) + } + } + return decoder +} +func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder { + for _, extension := range extensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + decoder := ctx.decoderExtension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + for _, extension := range ctx.extraExtensions { + decoder := extension.CreateDecoder(typ) + if decoder != nil { + return decoder + } + } + typeName := typ.String() + decoder = typeDecoders[typeName] + if decoder != nil { + return decoder + } + if typ.Kind() == reflect.Ptr { + ptrType := typ.(*reflect2.UnsafePtrType) + decoder := typeDecoders[ptrType.Elem().String()] + if decoder != nil { + return &OptionalDecoder{ptrType.Elem(), decoder} + } + } + return nil +} + +func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := _getTypeEncoderFromExtension(ctx, typ) + if encoder != nil { + for _, extension := range extensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + encoder = ctx.encoderExtension.DecorateEncoder(typ, encoder) + for _, extension := range ctx.extraExtensions { + encoder = extension.DecorateEncoder(typ, encoder) + } + } + return encoder +} + +func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder { + for _, extension := range extensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + encoder := ctx.encoderExtension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + for _, extension := range ctx.extraExtensions { + encoder := extension.CreateEncoder(typ) + if encoder != nil { + return encoder + } + } + typeName := typ.String() + encoder = typeEncoders[typeName] + if encoder != nil { + return encoder + } + if typ.Kind() == reflect.Ptr { + typePtr := typ.(*reflect2.UnsafePtrType) + encoder := typeEncoders[typePtr.Elem().String()] + if encoder != nil { + return &OptionalEncoder{encoder} + } + } + return nil +} + +func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor { + structType := typ.(*reflect2.UnsafeStructType) + embeddedBindings := []*Binding{} + bindings := []*Binding{} + for i := 0; i < structType.NumField(); i++ { + field := structType.Field(i) + tag, hastag := field.Tag().Lookup(ctx.getTagKey()) + if ctx.onlyTaggedField && !hastag { + continue + } + tagParts := strings.Split(tag, ",") + if tag == "-" { + continue + } + if field.Anonymous() && (tag == "" || tagParts[0] == "") { + if field.Type().Kind() == reflect.Struct { + structDescriptor := describeStruct(ctx, field.Type()) + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} + binding.Decoder = &structFieldDecoder{field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } else if field.Type().Kind() == reflect.Ptr { + ptrType := field.Type().(*reflect2.UnsafePtrType) + if ptrType.Elem().Kind() == reflect.Struct { + structDescriptor := describeStruct(ctx, ptrType.Elem()) + for _, binding := range structDescriptor.Fields { + binding.levels = append([]int{i}, binding.levels...) + omitempty := binding.Encoder.(*structFieldEncoder).omitempty + binding.Encoder = &dereferenceEncoder{binding.Encoder} + binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty} + binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder} + binding.Decoder = &structFieldDecoder{field, binding.Decoder} + embeddedBindings = append(embeddedBindings, binding) + } + continue + } + } + } + fieldNames := calcFieldNames(field.Name(), tagParts[0], tag) + fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name()) + decoder := fieldDecoders[fieldCacheKey] + if decoder == nil { + decoder = decoderOfType(ctx.append(field.Name()), field.Type()) + } + encoder := fieldEncoders[fieldCacheKey] + if encoder == nil { + encoder = encoderOfType(ctx.append(field.Name()), field.Type()) + } + binding := &Binding{ + Field: field, + FromNames: fieldNames, + ToNames: fieldNames, + Decoder: decoder, + Encoder: encoder, + } + binding.levels = []int{i} + bindings = append(bindings, binding) + } + return createStructDescriptor(ctx, typ, bindings, embeddedBindings) +} +func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor { + structDescriptor := &StructDescriptor{ + Type: typ, + Fields: bindings, + } + for _, extension := range extensions { + extension.UpdateStructDescriptor(structDescriptor) + } + ctx.encoderExtension.UpdateStructDescriptor(structDescriptor) + ctx.decoderExtension.UpdateStructDescriptor(structDescriptor) + for _, extension := range ctx.extraExtensions { + extension.UpdateStructDescriptor(structDescriptor) + } + processTags(structDescriptor, ctx.frozenConfig) + // merge normal & embedded bindings & sort with original order + allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...)) + sort.Sort(allBindings) + structDescriptor.Fields = allBindings + return structDescriptor +} + +type sortableBindings []*Binding + +func (bindings sortableBindings) Len() int { + return len(bindings) +} + +func (bindings sortableBindings) Less(i, j int) bool { + left := bindings[i].levels + right := bindings[j].levels + k := 0 + for { + if left[k] < right[k] { + return true + } else if left[k] > right[k] { + return false + } + k++ + } +} + +func (bindings sortableBindings) Swap(i, j int) { + bindings[i], bindings[j] = bindings[j], bindings[i] +} + +func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) { + for _, binding := range structDescriptor.Fields { + shouldOmitEmpty := false + tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",") + for _, tagPart := range tagParts[1:] { + if tagPart == "omitempty" { + shouldOmitEmpty = true + } else if tagPart == "string" { + if binding.Field.Type().Kind() == reflect.String { + binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg} + binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg} + } else { + binding.Decoder = &stringModeNumberDecoder{binding.Decoder} + binding.Encoder = &stringModeNumberEncoder{binding.Encoder} + } + } + } + binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} + binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} + } +} + +func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string { + // ignore? + if wholeTag == "-" { + return []string{} + } + // rename? + var fieldNames []string + if tagProvidedFieldName == "" { + fieldNames = []string{originalFieldName} + } else { + fieldNames = []string{tagProvidedFieldName} + } + // private? + isNotExported := unicode.IsLower(rune(originalFieldName[0])) + if isNotExported { + fieldNames = []string{} + } + return fieldNames +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_number.go b/vendor/github.com/json-iterator/go/reflect_json_number.go new file mode 100644 index 000000000..98d45c1ec --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_json_number.go @@ -0,0 +1,112 @@ +package jsoniter + +import ( + "encoding/json" + "github.com/modern-go/reflect2" + "strconv" + "unsafe" +) + +type Number string + +// String returns the literal text of the number. +func (n Number) String() string { return string(n) } + +// Float64 returns the number as a float64. +func (n Number) Float64() (float64, error) { + return strconv.ParseFloat(string(n), 64) +} + +// Int64 returns the number as an int64. +func (n Number) Int64() (int64, error) { + return strconv.ParseInt(string(n), 10, 64) +} + +func CastJsonNumber(val interface{}) (string, bool) { + switch typedVal := val.(type) { + case json.Number: + return string(typedVal), true + case Number: + return string(typedVal), true + } + return "", false +} + +var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem() +var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem() + +func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{} + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{} + } + return nil +} + +func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ.AssignableTo(jsonNumberType) { + return &jsonNumberCodec{} + } + if typ.AssignableTo(jsoniterNumberType) { + return &jsoniterNumberCodec{} + } + return nil +} + +type jsonNumberCodec struct { +} + +func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*json.Number)(ptr)) = json.Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*json.Number)(ptr)) = "" + default: + *((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + number := *((*json.Number)(ptr)) + if len(number) == 0 { + stream.writeByte('0') + } else { + stream.WriteRaw(string(number)) + } +} + +func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.Number)(ptr))) == 0 +} + +type jsoniterNumberCodec struct { +} + +func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + switch iter.WhatIsNext() { + case StringValue: + *((*Number)(ptr)) = Number(iter.ReadString()) + case NilValue: + iter.skipFourBytes('n', 'u', 'l', 'l') + *((*Number)(ptr)) = "" + default: + *((*Number)(ptr)) = Number([]byte(iter.readNumberAsString())) + } +} + +func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + number := *((*Number)(ptr)) + if len(number) == 0 { + stream.writeByte('0') + } else { + stream.WriteRaw(string(number)) + } +} + +func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*Number)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_json_raw_message.go b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go new file mode 100644 index 000000000..f2619936c --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_json_raw_message.go @@ -0,0 +1,60 @@ +package jsoniter + +import ( + "encoding/json" + "github.com/modern-go/reflect2" + "unsafe" +) + +var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem() +var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem() + +func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{} + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{} + } + return nil +} + +func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ == jsonRawMessageType { + return &jsonRawMessageCodec{} + } + if typ == jsoniterRawMessageType { + return &jsoniterRawMessageCodec{} + } + return nil +} + +type jsonRawMessageCodec struct { +} + +func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*json.RawMessage)(ptr)))) +} + +func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*json.RawMessage)(ptr))) == 0 +} + +type jsoniterRawMessageCodec struct { +} + +func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes()) +} + +func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteRaw(string(*((*RawMessage)(ptr)))) +} + +func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*RawMessage)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_map.go b/vendor/github.com/json-iterator/go/reflect_map.go new file mode 100644 index 000000000..7f66a88b0 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_map.go @@ -0,0 +1,326 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "sort" + "unsafe" +) + +func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder { + mapType := typ.(*reflect2.UnsafeMapType) + keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()) + elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem()) + return &mapDecoder{ + mapType: mapType, + keyType: mapType.Key(), + elemType: mapType.Elem(), + keyDecoder: keyDecoder, + elemDecoder: elemDecoder, + } +} + +func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder { + mapType := typ.(*reflect2.UnsafeMapType) + if ctx.sortMapKeys { + return &sortKeysMapEncoder{ + mapType: mapType, + keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), + elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), + } + } + return &mapEncoder{ + mapType: mapType, + keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()), + elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()), + } +} + +func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder { + decoder := ctx.decoderExtension.CreateMapKeyDecoder(typ) + if decoder != nil { + return decoder + } + for _, extension := range ctx.extraExtensions { + decoder := extension.CreateMapKeyDecoder(typ) + if decoder != nil { + return decoder + } + } + switch typ.Kind() { + case reflect.String: + return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) + case reflect.Bool, + reflect.Uint8, reflect.Int8, + reflect.Uint16, reflect.Int16, + reflect.Uint32, reflect.Int32, + reflect.Uint64, reflect.Int64, + reflect.Uint, reflect.Int, + reflect.Float32, reflect.Float64, + reflect.Uintptr: + typ = reflect2.DefaultTypeOfKind(typ.Kind()) + return &numericMapKeyDecoder{decoderOfType(ctx, typ)} + default: + ptrType := reflect2.PtrTo(typ) + if ptrType.Implements(textMarshalerType) { + return &referenceDecoder{ + &textUnmarshalerDecoder{ + valType: ptrType, + }, + } + } + if typ.Implements(textMarshalerType) { + return &textUnmarshalerDecoder{ + valType: typ, + } + } + return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)} + } +} + +func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder { + encoder := ctx.encoderExtension.CreateMapKeyEncoder(typ) + if encoder != nil { + return encoder + } + for _, extension := range ctx.extraExtensions { + encoder := extension.CreateMapKeyEncoder(typ) + if encoder != nil { + return encoder + } + } + switch typ.Kind() { + case reflect.String: + return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String)) + case reflect.Bool, + reflect.Uint8, reflect.Int8, + reflect.Uint16, reflect.Int16, + reflect.Uint32, reflect.Int32, + reflect.Uint64, reflect.Int64, + reflect.Uint, reflect.Int, + reflect.Float32, reflect.Float64, + reflect.Uintptr: + typ = reflect2.DefaultTypeOfKind(typ.Kind()) + return &numericMapKeyEncoder{encoderOfType(ctx, typ)} + default: + if typ == textMarshalerType { + return &directTextMarshalerEncoder{ + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + } + if typ.Implements(textMarshalerType) { + return &textMarshalerEncoder{ + valType: typ, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + } + if typ.Kind() == reflect.Interface { + return &dynamicMapKeyEncoder{ctx, typ} + } + return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)} + } +} + +type mapDecoder struct { + mapType *reflect2.UnsafeMapType + keyType reflect2.Type + elemType reflect2.Type + keyDecoder ValDecoder + elemDecoder ValDecoder +} + +func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + mapType := decoder.mapType + c := iter.nextToken() + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + *(*unsafe.Pointer)(ptr) = nil + mapType.UnsafeSet(ptr, mapType.UnsafeNew()) + return + } + if mapType.UnsafeIsNil(ptr) { + mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0)) + } + if c != '{' { + iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c})) + return + } + c = iter.nextToken() + if c == '}' { + return + } + if c != '"' { + iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c})) + return + } + iter.unreadByte() + key := decoder.keyType.UnsafeNew() + decoder.keyDecoder.Decode(key, iter) + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return + } + elem := decoder.elemType.UnsafeNew() + decoder.elemDecoder.Decode(elem, iter) + decoder.mapType.UnsafeSetIndex(ptr, key, elem) + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + key := decoder.keyType.UnsafeNew() + decoder.keyDecoder.Decode(key, iter) + c = iter.nextToken() + if c != ':' { + iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c})) + return + } + elem := decoder.elemType.UnsafeNew() + decoder.elemDecoder.Decode(elem, iter) + decoder.mapType.UnsafeSetIndex(ptr, key, elem) + } + if c != '}' { + iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c})) + } +} + +type numericMapKeyDecoder struct { + decoder ValDecoder +} + +func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) + return + } + decoder.decoder.Decode(ptr, iter) + c = iter.nextToken() + if c != '"' { + iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c})) + return + } +} + +type numericMapKeyEncoder struct { + encoder ValEncoder +} + +func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.encoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type dynamicMapKeyEncoder struct { + ctx *ctx + valType reflect2.Type +} + +func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream) +} + +func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool { + obj := encoder.valType.UnsafeIndirect(ptr) + return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj)) +} + +type mapEncoder struct { + mapType *reflect2.UnsafeMapType + keyEncoder ValEncoder + elemEncoder ValEncoder +} + +func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteObjectStart() + iter := encoder.mapType.UnsafeIterate(ptr) + for i := 0; iter.HasNext(); i++ { + if i != 0 { + stream.WriteMore() + } + key, elem := iter.UnsafeNext() + encoder.keyEncoder.Encode(key, stream) + if stream.indention > 0 { + stream.writeTwoBytes(byte(':'), byte(' ')) + } else { + stream.writeByte(':') + } + encoder.elemEncoder.Encode(elem, stream) + } + stream.WriteObjectEnd() +} + +func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + iter := encoder.mapType.UnsafeIterate(ptr) + return !iter.HasNext() +} + +type sortKeysMapEncoder struct { + mapType *reflect2.UnsafeMapType + keyEncoder ValEncoder + elemEncoder ValEncoder +} + +func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *(*unsafe.Pointer)(ptr) == nil { + stream.WriteNil() + return + } + stream.WriteObjectStart() + mapIter := encoder.mapType.UnsafeIterate(ptr) + subStream := stream.cfg.BorrowStream(nil) + subIter := stream.cfg.BorrowIterator(nil) + keyValues := encodedKeyValues{} + for mapIter.HasNext() { + subStream.buf = make([]byte, 0, 64) + key, elem := mapIter.UnsafeNext() + encoder.keyEncoder.Encode(key, subStream) + if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil { + stream.Error = subStream.Error + } + encodedKey := subStream.Buffer() + subIter.ResetBytes(encodedKey) + decodedKey := subIter.ReadString() + if stream.indention > 0 { + subStream.writeTwoBytes(byte(':'), byte(' ')) + } else { + subStream.writeByte(':') + } + encoder.elemEncoder.Encode(elem, subStream) + keyValues = append(keyValues, encodedKV{ + key: decodedKey, + keyValue: subStream.Buffer(), + }) + } + sort.Sort(keyValues) + for i, keyValue := range keyValues { + if i != 0 { + stream.WriteMore() + } + stream.Write(keyValue.keyValue) + } + stream.WriteObjectEnd() + stream.cfg.ReturnStream(subStream) + stream.cfg.ReturnIterator(subIter) +} + +func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool { + iter := encoder.mapType.UnsafeIterate(ptr) + return !iter.HasNext() +} + +type encodedKeyValues []encodedKV + +type encodedKV struct { + key string + keyValue []byte +} + +func (sv encodedKeyValues) Len() int { return len(sv) } +func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key } diff --git a/vendor/github.com/json-iterator/go/reflect_marshaler.go b/vendor/github.com/json-iterator/go/reflect_marshaler.go new file mode 100644 index 000000000..58ac959ad --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_marshaler.go @@ -0,0 +1,218 @@ +package jsoniter + +import ( + "encoding" + "encoding/json" + "github.com/modern-go/reflect2" + "unsafe" +) + +var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem() +var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem() +var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem() +var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem() + +func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder { + ptrType := reflect2.PtrTo(typ) + if ptrType.Implements(unmarshalerType) { + return &referenceDecoder{ + &unmarshalerDecoder{ptrType}, + } + } + if ptrType.Implements(textUnmarshalerType) { + return &referenceDecoder{ + &textUnmarshalerDecoder{ptrType}, + } + } + return nil +} + +func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ == marshalerType { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &directMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + } + return encoder + } + if typ.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &marshalerEncoder{ + valType: typ, + checkIsEmpty: checkIsEmpty, + } + return encoder + } + ptrType := reflect2.PtrTo(typ) + if ctx.prefix != "" && ptrType.Implements(marshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, ptrType) + var encoder ValEncoder = &marshalerEncoder{ + valType: ptrType, + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + if typ == textMarshalerType { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &directTextMarshalerEncoder{ + checkIsEmpty: checkIsEmpty, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + } + return encoder + } + if typ.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, typ) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: typ, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return encoder + } + // if prefix is empty, the type is the root type + if ctx.prefix != "" && ptrType.Implements(textMarshalerType) { + checkIsEmpty := createCheckIsEmpty(ctx, ptrType) + var encoder ValEncoder = &textMarshalerEncoder{ + valType: ptrType, + stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")), + checkIsEmpty: checkIsEmpty, + } + return &referenceEncoder{encoder} + } + return nil +} + +type marshalerEncoder struct { + checkIsEmpty checkIsEmpty + valType reflect2.Type +} + +func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + if encoder.valType.IsNullable() && reflect2.IsNil(obj) { + stream.WriteNil() + return + } + marshaler := obj.(json.Marshaler) + bytes, err := marshaler.MarshalJSON() + if err != nil { + stream.Error = err + } else { + stream.Write(bytes) + } +} + +func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type directMarshalerEncoder struct { + checkIsEmpty checkIsEmpty +} + +func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + marshaler := *(*json.Marshaler)(ptr) + if marshaler == nil { + stream.WriteNil() + return + } + bytes, err := marshaler.MarshalJSON() + if err != nil { + stream.Error = err + } else { + stream.Write(bytes) + } +} + +func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type textMarshalerEncoder struct { + valType reflect2.Type + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty +} + +func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + obj := encoder.valType.UnsafeIndirect(ptr) + if encoder.valType.IsNullable() && reflect2.IsNil(obj) { + stream.WriteNil() + return + } + marshaler := (obj).(encoding.TextMarshaler) + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + str := string(bytes) + encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) + } +} + +func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type directTextMarshalerEncoder struct { + stringEncoder ValEncoder + checkIsEmpty checkIsEmpty +} + +func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + marshaler := *(*encoding.TextMarshaler)(ptr) + if marshaler == nil { + stream.WriteNil() + return + } + bytes, err := marshaler.MarshalText() + if err != nil { + stream.Error = err + } else { + str := string(bytes) + encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream) + } +} + +func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.checkIsEmpty.IsEmpty(ptr) +} + +type unmarshalerDecoder struct { + valType reflect2.Type +} + +func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valType := decoder.valType + obj := valType.UnsafeIndirect(ptr) + unmarshaler := obj.(json.Unmarshaler) + iter.nextToken() + iter.unreadByte() // skip spaces + bytes := iter.SkipAndReturnBytes() + err := unmarshaler.UnmarshalJSON(bytes) + if err != nil { + iter.ReportError("unmarshalerDecoder", err.Error()) + } +} + +type textUnmarshalerDecoder struct { + valType reflect2.Type +} + +func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valType := decoder.valType + obj := valType.UnsafeIndirect(ptr) + if reflect2.IsNil(obj) { + ptrType := valType.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + elem := elemType.UnsafeNew() + ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem)) + obj = valType.UnsafeIndirect(ptr) + } + unmarshaler := (obj).(encoding.TextUnmarshaler) + str := iter.ReadString() + err := unmarshaler.UnmarshalText([]byte(str)) + if err != nil { + iter.ReportError("textUnmarshalerDecoder", err.Error()) + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_native.go b/vendor/github.com/json-iterator/go/reflect_native.go new file mode 100644 index 000000000..9042eb0cb --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_native.go @@ -0,0 +1,451 @@ +package jsoniter + +import ( + "encoding/base64" + "reflect" + "strconv" + "unsafe" + + "github.com/modern-go/reflect2" +) + +const ptrSize = 32 << uintptr(^uintptr(0)>>63) + +func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder { + if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { + sliceDecoder := decoderOfSlice(ctx, typ) + return &base64Codec{sliceDecoder: sliceDecoder} + } + typeName := typ.String() + kind := typ.Kind() + switch kind { + case reflect.String: + if typeName != "string" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) + } + return &stringCodec{} + case reflect.Int: + if typeName != "int" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &int32Codec{} + } + return &int64Codec{} + case reflect.Int8: + if typeName != "int8" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) + } + return &int8Codec{} + case reflect.Int16: + if typeName != "int16" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) + } + return &int16Codec{} + case reflect.Int32: + if typeName != "int32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) + } + return &int32Codec{} + case reflect.Int64: + if typeName != "int64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) + } + return &int64Codec{} + case reflect.Uint: + if typeName != "uint" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint8: + if typeName != "uint8" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) + } + return &uint8Codec{} + case reflect.Uint16: + if typeName != "uint16" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) + } + return &uint16Codec{} + case reflect.Uint32: + if typeName != "uint32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) + } + return &uint32Codec{} + case reflect.Uintptr: + if typeName != "uintptr" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) + } + if ptrSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint64: + if typeName != "uint64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) + } + return &uint64Codec{} + case reflect.Float32: + if typeName != "float32" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) + } + return &float32Codec{} + case reflect.Float64: + if typeName != "float64" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) + } + return &float64Codec{} + case reflect.Bool: + if typeName != "bool" { + return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) + } + return &boolCodec{} + } + return nil +} + +func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder { + if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 { + sliceDecoder := decoderOfSlice(ctx, typ) + return &base64Codec{sliceDecoder: sliceDecoder} + } + typeName := typ.String() + switch typ.Kind() { + case reflect.String: + if typeName != "string" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem()) + } + return &stringCodec{} + case reflect.Int: + if typeName != "int" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &int32Codec{} + } + return &int64Codec{} + case reflect.Int8: + if typeName != "int8" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem()) + } + return &int8Codec{} + case reflect.Int16: + if typeName != "int16" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem()) + } + return &int16Codec{} + case reflect.Int32: + if typeName != "int32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem()) + } + return &int32Codec{} + case reflect.Int64: + if typeName != "int64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem()) + } + return &int64Codec{} + case reflect.Uint: + if typeName != "uint" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem()) + } + if strconv.IntSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint8: + if typeName != "uint8" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem()) + } + return &uint8Codec{} + case reflect.Uint16: + if typeName != "uint16" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem()) + } + return &uint16Codec{} + case reflect.Uint32: + if typeName != "uint32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem()) + } + return &uint32Codec{} + case reflect.Uintptr: + if typeName != "uintptr" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem()) + } + if ptrSize == 32 { + return &uint32Codec{} + } + return &uint64Codec{} + case reflect.Uint64: + if typeName != "uint64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem()) + } + return &uint64Codec{} + case reflect.Float32: + if typeName != "float32" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem()) + } + return &float32Codec{} + case reflect.Float64: + if typeName != "float64" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem()) + } + return &float64Codec{} + case reflect.Bool: + if typeName != "bool" { + return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem()) + } + return &boolCodec{} + } + return nil +} + +type stringCodec struct { +} + +func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + *((*string)(ptr)) = iter.ReadString() +} + +func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + str := *((*string)(ptr)) + stream.WriteString(str) +} + +func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*string)(ptr)) == "" +} + +type int8Codec struct { +} + +func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int8)(ptr)) = iter.ReadInt8() + } +} + +func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt8(*((*int8)(ptr))) +} + +func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int8)(ptr)) == 0 +} + +type int16Codec struct { +} + +func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int16)(ptr)) = iter.ReadInt16() + } +} + +func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt16(*((*int16)(ptr))) +} + +func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int16)(ptr)) == 0 +} + +type int32Codec struct { +} + +func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int32)(ptr)) = iter.ReadInt32() + } +} + +func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt32(*((*int32)(ptr))) +} + +func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int32)(ptr)) == 0 +} + +type int64Codec struct { +} + +func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*int64)(ptr)) = iter.ReadInt64() + } +} + +func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteInt64(*((*int64)(ptr))) +} + +func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*int64)(ptr)) == 0 +} + +type uint8Codec struct { +} + +func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint8)(ptr)) = iter.ReadUint8() + } +} + +func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint8(*((*uint8)(ptr))) +} + +func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint8)(ptr)) == 0 +} + +type uint16Codec struct { +} + +func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint16)(ptr)) = iter.ReadUint16() + } +} + +func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint16(*((*uint16)(ptr))) +} + +func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint16)(ptr)) == 0 +} + +type uint32Codec struct { +} + +func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint32)(ptr)) = iter.ReadUint32() + } +} + +func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint32(*((*uint32)(ptr))) +} + +func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint32)(ptr)) == 0 +} + +type uint64Codec struct { +} + +func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*uint64)(ptr)) = iter.ReadUint64() + } +} + +func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteUint64(*((*uint64)(ptr))) +} + +func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*uint64)(ptr)) == 0 +} + +type float32Codec struct { +} + +func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float32)(ptr)) = iter.ReadFloat32() + } +} + +func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat32(*((*float32)(ptr))) +} + +func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float32)(ptr)) == 0 +} + +type float64Codec struct { +} + +func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*float64)(ptr)) = iter.ReadFloat64() + } +} + +func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteFloat64(*((*float64)(ptr))) +} + +func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return *((*float64)(ptr)) == 0 +} + +type boolCodec struct { +} + +func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.ReadNil() { + *((*bool)(ptr)) = iter.ReadBool() + } +} + +func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteBool(*((*bool)(ptr))) +} + +func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool { + return !(*((*bool)(ptr))) +} + +type base64Codec struct { + sliceType *reflect2.UnsafeSliceType + sliceDecoder ValDecoder +} + +func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + codec.sliceType.UnsafeSetNil(ptr) + return + } + switch iter.WhatIsNext() { + case StringValue: + src := iter.ReadString() + dst, err := base64.StdEncoding.DecodeString(src) + if err != nil { + iter.ReportError("decode base64", err.Error()) + } else { + codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst)) + } + case ArrayValue: + codec.sliceDecoder.Decode(ptr, iter) + default: + iter.ReportError("base64Codec", "invalid input") + } +} + +func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) { + src := *((*[]byte)(ptr)) + if len(src) == 0 { + stream.WriteNil() + return + } + encoding := base64.StdEncoding + stream.writeByte('"') + size := encoding.EncodedLen(len(src)) + buf := make([]byte, size) + encoding.Encode(buf, src) + stream.buf = append(stream.buf, buf...) + stream.writeByte('"') +} + +func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool { + return len(*((*[]byte)(ptr))) == 0 +} diff --git a/vendor/github.com/json-iterator/go/reflect_optional.go b/vendor/github.com/json-iterator/go/reflect_optional.go new file mode 100644 index 000000000..43ec71d6d --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_optional.go @@ -0,0 +1,133 @@ +package jsoniter + +import ( + "github.com/modern-go/reflect2" + "reflect" + "unsafe" +) + +func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + decoder := decoderOfType(ctx, elemType) + if ctx.prefix == "" && elemType.Kind() == reflect.Ptr { + return &dereferenceDecoder{elemType, decoder} + } + return &OptionalDecoder{elemType, decoder} +} + +func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + elemEncoder := encoderOfType(ctx, elemType) + encoder := &OptionalEncoder{elemEncoder} + return encoder +} + +type OptionalDecoder struct { + ValueType reflect2.Type + ValueDecoder ValDecoder +} + +func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if iter.ReadNil() { + *((*unsafe.Pointer)(ptr)) = nil + } else { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + newPtr := decoder.ValueType.UnsafeNew() + decoder.ValueDecoder.Decode(newPtr, iter) + *((*unsafe.Pointer)(ptr)) = newPtr + } else { + //reuse existing instance + decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } + } +} + +type dereferenceDecoder struct { + // only to deference a pointer + valueType reflect2.Type + valueDecoder ValDecoder +} + +func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if *((*unsafe.Pointer)(ptr)) == nil { + //pointer to null, we have to allocate memory to hold the value + newPtr := decoder.valueType.UnsafeNew() + decoder.valueDecoder.Decode(newPtr, iter) + *((*unsafe.Pointer)(ptr)) = newPtr + } else { + //reuse existing instance + decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter) + } +} + +type OptionalEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return *((*unsafe.Pointer)(ptr)) == nil +} + +type dereferenceEncoder struct { + ValueEncoder ValEncoder +} + +func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if *((*unsafe.Pointer)(ptr)) == nil { + stream.WriteNil() + } else { + encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream) + } +} + +func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + dePtr := *((*unsafe.Pointer)(ptr)) + if dePtr == nil { + return true + } + return encoder.ValueEncoder.IsEmpty(dePtr) +} + +func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { + deReferenced := *((*unsafe.Pointer)(ptr)) + if deReferenced == nil { + return true + } + isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil) + if !converted { + return false + } + fieldPtr := unsafe.Pointer(deReferenced) + return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) +} + +type referenceEncoder struct { + encoder ValEncoder +} + +func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + encoder.encoder.Encode(unsafe.Pointer(&ptr), stream) +} + +func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr)) +} + +type referenceDecoder struct { + decoder ValDecoder +} + +func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.decoder.Decode(unsafe.Pointer(&ptr), iter) +} diff --git a/vendor/github.com/json-iterator/go/reflect_slice.go b/vendor/github.com/json-iterator/go/reflect_slice.go new file mode 100644 index 000000000..9441d79df --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_slice.go @@ -0,0 +1,99 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "unsafe" +) + +func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder { + sliceType := typ.(*reflect2.UnsafeSliceType) + decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) + return &sliceDecoder{sliceType, decoder} +} + +func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder { + sliceType := typ.(*reflect2.UnsafeSliceType) + encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem()) + return &sliceEncoder{sliceType, encoder} +} + +type sliceEncoder struct { + sliceType *reflect2.UnsafeSliceType + elemEncoder ValEncoder +} + +func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + if encoder.sliceType.UnsafeIsNil(ptr) { + stream.WriteNil() + return + } + length := encoder.sliceType.UnsafeLengthOf(ptr) + if length == 0 { + stream.WriteEmptyArray() + return + } + stream.WriteArrayStart() + encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream) + for i := 1; i < length; i++ { + stream.WriteMore() + elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i) + encoder.elemEncoder.Encode(elemPtr, stream) + } + stream.WriteArrayEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error()) + } +} + +func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.sliceType.UnsafeLengthOf(ptr) == 0 +} + +type sliceDecoder struct { + sliceType *reflect2.UnsafeSliceType + elemDecoder ValDecoder +} + +func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.doDecode(ptr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error()) + } +} + +func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + sliceType := decoder.sliceType + if c == 'n' { + iter.skipThreeBytes('u', 'l', 'l') + sliceType.UnsafeSetNil(ptr) + return + } + if c != '[' { + iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c})) + return + } + c = iter.nextToken() + if c == ']' { + sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0)) + return + } + iter.unreadByte() + sliceType.UnsafeGrow(ptr, 1) + elemPtr := sliceType.UnsafeGetIndex(ptr, 0) + decoder.elemDecoder.Decode(elemPtr, iter) + length := 1 + for c = iter.nextToken(); c == ','; c = iter.nextToken() { + idx := length + length += 1 + sliceType.UnsafeGrow(ptr, length) + elemPtr = sliceType.UnsafeGetIndex(ptr, idx) + decoder.elemDecoder.Decode(elemPtr, iter) + } + if c != ']' { + iter.ReportError("decode slice", "expect ], but found "+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_decoder.go b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go new file mode 100644 index 000000000..355d2d116 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_struct_decoder.go @@ -0,0 +1,1048 @@ +package jsoniter + +import ( + "fmt" + "io" + "strings" + "unsafe" + + "github.com/modern-go/reflect2" +) + +func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder { + bindings := map[string]*Binding{} + structDescriptor := describeStruct(ctx, typ) + for _, binding := range structDescriptor.Fields { + for _, fromName := range binding.FromNames { + old := bindings[fromName] + if old == nil { + bindings[fromName] = binding + continue + } + ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding) + if ignoreOld { + delete(bindings, fromName) + } + if !ignoreNew { + bindings[fromName] = binding + } + } + } + fields := map[string]*structFieldDecoder{} + for k, binding := range bindings { + fields[k] = binding.Decoder.(*structFieldDecoder) + } + + if !ctx.caseSensitive() { + for k, binding := range bindings { + if _, found := fields[strings.ToLower(k)]; !found { + fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder) + } + } + } + + return createStructDecoder(ctx, typ, fields) +} + +func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder { + if ctx.disallowUnknownFields { + return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true} + } + knownHash := map[int64]struct{}{ + 0: {}, + } + + switch len(fields) { + case 0: + return &skipObjectDecoder{typ} + case 1: + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder} + } + case 2: + var fieldHash1 int64 + var fieldHash2 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldHash1 == 0 { + fieldHash1 = fieldHash + fieldDecoder1 = fieldDecoder + } else { + fieldHash2 = fieldHash + fieldDecoder2 = fieldDecoder + } + } + return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2} + case 3: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } + } + return &threeFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3} + case 4: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } + } + return &fourFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4} + case 5: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } + } + return &fiveFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5} + case 6: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } + } + return &sixFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6} + case 7: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } + } + return &sevenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7} + case 8: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } + } + return &eightFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8} + case 9: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } + } + return &nineFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9} + case 10: + var fieldName1 int64 + var fieldName2 int64 + var fieldName3 int64 + var fieldName4 int64 + var fieldName5 int64 + var fieldName6 int64 + var fieldName7 int64 + var fieldName8 int64 + var fieldName9 int64 + var fieldName10 int64 + var fieldDecoder1 *structFieldDecoder + var fieldDecoder2 *structFieldDecoder + var fieldDecoder3 *structFieldDecoder + var fieldDecoder4 *structFieldDecoder + var fieldDecoder5 *structFieldDecoder + var fieldDecoder6 *structFieldDecoder + var fieldDecoder7 *structFieldDecoder + var fieldDecoder8 *structFieldDecoder + var fieldDecoder9 *structFieldDecoder + var fieldDecoder10 *structFieldDecoder + for fieldName, fieldDecoder := range fields { + fieldHash := calcHash(fieldName, ctx.caseSensitive()) + _, known := knownHash[fieldHash] + if known { + return &generalStructDecoder{typ, fields, false} + } + knownHash[fieldHash] = struct{}{} + if fieldName1 == 0 { + fieldName1 = fieldHash + fieldDecoder1 = fieldDecoder + } else if fieldName2 == 0 { + fieldName2 = fieldHash + fieldDecoder2 = fieldDecoder + } else if fieldName3 == 0 { + fieldName3 = fieldHash + fieldDecoder3 = fieldDecoder + } else if fieldName4 == 0 { + fieldName4 = fieldHash + fieldDecoder4 = fieldDecoder + } else if fieldName5 == 0 { + fieldName5 = fieldHash + fieldDecoder5 = fieldDecoder + } else if fieldName6 == 0 { + fieldName6 = fieldHash + fieldDecoder6 = fieldDecoder + } else if fieldName7 == 0 { + fieldName7 = fieldHash + fieldDecoder7 = fieldDecoder + } else if fieldName8 == 0 { + fieldName8 = fieldHash + fieldDecoder8 = fieldDecoder + } else if fieldName9 == 0 { + fieldName9 = fieldHash + fieldDecoder9 = fieldDecoder + } else { + fieldName10 = fieldHash + fieldDecoder10 = fieldDecoder + } + } + return &tenFieldsStructDecoder{typ, + fieldName1, fieldDecoder1, + fieldName2, fieldDecoder2, + fieldName3, fieldDecoder3, + fieldName4, fieldDecoder4, + fieldName5, fieldDecoder5, + fieldName6, fieldDecoder6, + fieldName7, fieldDecoder7, + fieldName8, fieldDecoder8, + fieldName9, fieldDecoder9, + fieldName10, fieldDecoder10} + } + return &generalStructDecoder{typ, fields, false} +} + +type generalStructDecoder struct { + typ reflect2.Type + fields map[string]*structFieldDecoder + disallowUnknownFields bool +} + +func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + var c byte + for c = ','; c == ','; c = iter.nextToken() { + decoder.decodeOneField(ptr, iter) + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } + if c != '}' { + iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c})) + } +} + +func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) { + var field string + var fieldDecoder *structFieldDecoder + if iter.cfg.objectFieldMustBeSimpleString { + fieldBytes := iter.ReadStringAsSlice() + field = *(*string)(unsafe.Pointer(&fieldBytes)) + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil && !iter.cfg.caseSensitive { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } else { + field = iter.ReadString() + fieldDecoder = decoder.fields[field] + if fieldDecoder == nil && !iter.cfg.caseSensitive { + fieldDecoder = decoder.fields[strings.ToLower(field)] + } + } + if fieldDecoder == nil { + msg := "found unknown field: " + field + if decoder.disallowUnknownFields { + iter.ReportError("ReadObject", msg) + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + iter.Skip() + return + } + c := iter.nextToken() + if c != ':' { + iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c})) + } + fieldDecoder.Decode(ptr, iter) +} + +type skipObjectDecoder struct { + typ reflect2.Type +} + +func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + valueType := iter.WhatIsNext() + if valueType != ObjectValue && valueType != NilValue { + iter.ReportError("skipObjectDecoder", "expect object or null") + return + } + iter.Skip() +} + +type oneFieldStructDecoder struct { + typ reflect2.Type + fieldHash int64 + fieldDecoder *structFieldDecoder +} + +func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + if iter.readFieldHash() == decoder.fieldHash { + decoder.fieldDecoder.Decode(ptr, iter) + } else { + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type twoFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder +} + +func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type threeFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder +} + +func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type fourFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder +} + +func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type fiveFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder +} + +func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type sixFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder +} + +func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type sevenFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder +} + +func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type eightFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder +} + +func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type nineFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder + fieldHash9 int64 + fieldDecoder9 *structFieldDecoder +} + +func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type tenFieldsStructDecoder struct { + typ reflect2.Type + fieldHash1 int64 + fieldDecoder1 *structFieldDecoder + fieldHash2 int64 + fieldDecoder2 *structFieldDecoder + fieldHash3 int64 + fieldDecoder3 *structFieldDecoder + fieldHash4 int64 + fieldDecoder4 *structFieldDecoder + fieldHash5 int64 + fieldDecoder5 *structFieldDecoder + fieldHash6 int64 + fieldDecoder6 *structFieldDecoder + fieldHash7 int64 + fieldDecoder7 *structFieldDecoder + fieldHash8 int64 + fieldDecoder8 *structFieldDecoder + fieldHash9 int64 + fieldDecoder9 *structFieldDecoder + fieldHash10 int64 + fieldDecoder10 *structFieldDecoder +} + +func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + if !iter.readObjectStart() { + return + } + for { + switch iter.readFieldHash() { + case decoder.fieldHash1: + decoder.fieldDecoder1.Decode(ptr, iter) + case decoder.fieldHash2: + decoder.fieldDecoder2.Decode(ptr, iter) + case decoder.fieldHash3: + decoder.fieldDecoder3.Decode(ptr, iter) + case decoder.fieldHash4: + decoder.fieldDecoder4.Decode(ptr, iter) + case decoder.fieldHash5: + decoder.fieldDecoder5.Decode(ptr, iter) + case decoder.fieldHash6: + decoder.fieldDecoder6.Decode(ptr, iter) + case decoder.fieldHash7: + decoder.fieldDecoder7.Decode(ptr, iter) + case decoder.fieldHash8: + decoder.fieldDecoder8.Decode(ptr, iter) + case decoder.fieldHash9: + decoder.fieldDecoder9.Decode(ptr, iter) + case decoder.fieldHash10: + decoder.fieldDecoder10.Decode(ptr, iter) + default: + iter.Skip() + } + if iter.isObjectEnd() { + break + } + } + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error()) + } +} + +type structFieldDecoder struct { + field reflect2.StructField + fieldDecoder ValDecoder +} + +func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + fieldPtr := decoder.field.UnsafeGet(ptr) + decoder.fieldDecoder.Decode(fieldPtr, iter) + if iter.Error != nil && iter.Error != io.EOF { + iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error()) + } +} + +type stringModeStringDecoder struct { + elemDecoder ValDecoder + cfg *frozenConfig +} + +func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + decoder.elemDecoder.Decode(ptr, iter) + str := *((*string)(ptr)) + tempIter := decoder.cfg.BorrowIterator([]byte(str)) + defer decoder.cfg.ReturnIterator(tempIter) + *((*string)(ptr)) = tempIter.ReadString() +} + +type stringModeNumberDecoder struct { + elemDecoder ValDecoder +} + +func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) { + c := iter.nextToken() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } + decoder.elemDecoder.Decode(ptr, iter) + if iter.Error != nil { + return + } + c = iter.readByte() + if c != '"' { + iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c})) + return + } +} diff --git a/vendor/github.com/json-iterator/go/reflect_struct_encoder.go b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go new file mode 100644 index 000000000..d0759cf64 --- /dev/null +++ b/vendor/github.com/json-iterator/go/reflect_struct_encoder.go @@ -0,0 +1,210 @@ +package jsoniter + +import ( + "fmt" + "github.com/modern-go/reflect2" + "io" + "reflect" + "unsafe" +) + +func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder { + type bindingTo struct { + binding *Binding + toName string + ignored bool + } + orderedBindings := []*bindingTo{} + structDescriptor := describeStruct(ctx, typ) + for _, binding := range structDescriptor.Fields { + for _, toName := range binding.ToNames { + new := &bindingTo{ + binding: binding, + toName: toName, + } + for _, old := range orderedBindings { + if old.toName != toName { + continue + } + old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding) + } + orderedBindings = append(orderedBindings, new) + } + } + if len(orderedBindings) == 0 { + return &emptyStructEncoder{} + } + finalOrderedFields := []structFieldTo{} + for _, bindingTo := range orderedBindings { + if !bindingTo.ignored { + finalOrderedFields = append(finalOrderedFields, structFieldTo{ + encoder: bindingTo.binding.Encoder.(*structFieldEncoder), + toName: bindingTo.toName, + }) + } + } + return &structEncoder{typ, finalOrderedFields} +} + +func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty { + encoder := createEncoderOfNative(ctx, typ) + if encoder != nil { + return encoder + } + kind := typ.Kind() + switch kind { + case reflect.Interface: + return &dynamicEncoder{typ} + case reflect.Struct: + return &structEncoder{typ: typ} + case reflect.Array: + return &arrayEncoder{} + case reflect.Slice: + return &sliceEncoder{} + case reflect.Map: + return encoderOfMap(ctx, typ) + case reflect.Ptr: + return &OptionalEncoder{} + default: + return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)} + } +} + +func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) { + newTagged := new.Field.Tag().Get(cfg.getTagKey()) != "" + oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != "" + if newTagged { + if oldTagged { + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } else { + return true, false + } + } else { + if oldTagged { + return true, false + } + if len(old.levels) > len(new.levels) { + return true, false + } else if len(new.levels) > len(old.levels) { + return false, true + } else { + return true, true + } + } +} + +type structFieldEncoder struct { + field reflect2.StructField + fieldEncoder ValEncoder + omitempty bool +} + +func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + fieldPtr := encoder.field.UnsafeGet(ptr) + encoder.fieldEncoder.Encode(fieldPtr, stream) + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error()) + } +} + +func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool { + fieldPtr := encoder.field.UnsafeGet(ptr) + return encoder.fieldEncoder.IsEmpty(fieldPtr) +} + +func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool { + isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil) + if !converted { + return false + } + fieldPtr := encoder.field.UnsafeGet(ptr) + return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr) +} + +type IsEmbeddedPtrNil interface { + IsEmbeddedPtrNil(ptr unsafe.Pointer) bool +} + +type structEncoder struct { + typ reflect2.Type + fields []structFieldTo +} + +type structFieldTo struct { + encoder *structFieldEncoder + toName string +} + +func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteObjectStart() + isNotFirst := false + for _, field := range encoder.fields { + if field.encoder.omitempty && field.encoder.IsEmpty(ptr) { + continue + } + if field.encoder.IsEmbeddedPtrNil(ptr) { + continue + } + if isNotFirst { + stream.WriteMore() + } + stream.WriteObjectField(field.toName) + field.encoder.Encode(ptr, stream) + isNotFirst = true + } + stream.WriteObjectEnd() + if stream.Error != nil && stream.Error != io.EOF { + stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error()) + } +} + +func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type emptyStructEncoder struct { +} + +func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.WriteEmptyObject() +} + +func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return false +} + +type stringModeNumberEncoder struct { + elemEncoder ValEncoder +} + +func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + stream.writeByte('"') + encoder.elemEncoder.Encode(ptr, stream) + stream.writeByte('"') +} + +func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} + +type stringModeStringEncoder struct { + elemEncoder ValEncoder + cfg *frozenConfig +} + +func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) { + tempStream := encoder.cfg.BorrowStream(nil) + defer encoder.cfg.ReturnStream(tempStream) + encoder.elemEncoder.Encode(ptr, tempStream) + stream.WriteString(string(tempStream.Buffer())) +} + +func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool { + return encoder.elemEncoder.IsEmpty(ptr) +} diff --git a/vendor/github.com/json-iterator/go/stream.go b/vendor/github.com/json-iterator/go/stream.go new file mode 100644 index 000000000..17662fded --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream.go @@ -0,0 +1,211 @@ +package jsoniter + +import ( + "io" +) + +// stream is a io.Writer like object, with JSON specific write functions. +// Error is not returned as return value, but stored as Error member on this stream instance. +type Stream struct { + cfg *frozenConfig + out io.Writer + buf []byte + Error error + indention int + Attachment interface{} // open for customized encoder +} + +// NewStream create new stream instance. +// cfg can be jsoniter.ConfigDefault. +// out can be nil if write to internal buffer. +// bufSize is the initial size for the internal buffer in bytes. +func NewStream(cfg API, out io.Writer, bufSize int) *Stream { + return &Stream{ + cfg: cfg.(*frozenConfig), + out: out, + buf: make([]byte, 0, bufSize), + Error: nil, + indention: 0, + } +} + +// Pool returns a pool can provide more stream with same configuration +func (stream *Stream) Pool() StreamPool { + return stream.cfg +} + +// Reset reuse this stream instance by assign a new writer +func (stream *Stream) Reset(out io.Writer) { + stream.out = out + stream.buf = stream.buf[:0] +} + +// Available returns how many bytes are unused in the buffer. +func (stream *Stream) Available() int { + return cap(stream.buf) - len(stream.buf) +} + +// Buffered returns the number of bytes that have been written into the current buffer. +func (stream *Stream) Buffered() int { + return len(stream.buf) +} + +// Buffer if writer is nil, use this method to take the result +func (stream *Stream) Buffer() []byte { + return stream.buf +} + +// SetBuffer allows to append to the internal buffer directly +func (stream *Stream) SetBuffer(buf []byte) { + stream.buf = buf +} + +// Write writes the contents of p into the buffer. +// It returns the number of bytes written. +// If nn < len(p), it also returns an error explaining +// why the write is short. +func (stream *Stream) Write(p []byte) (nn int, err error) { + stream.buf = append(stream.buf, p...) + if stream.out != nil { + nn, err = stream.out.Write(stream.buf) + stream.buf = stream.buf[nn:] + return + } + return len(p), nil +} + +// WriteByte writes a single byte. +func (stream *Stream) writeByte(c byte) { + stream.buf = append(stream.buf, c) +} + +func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) { + stream.buf = append(stream.buf, c1, c2) +} + +func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) { + stream.buf = append(stream.buf, c1, c2, c3) +} + +func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) { + stream.buf = append(stream.buf, c1, c2, c3, c4) +} + +func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) { + stream.buf = append(stream.buf, c1, c2, c3, c4, c5) +} + +// Flush writes any buffered data to the underlying io.Writer. +func (stream *Stream) Flush() error { + if stream.out == nil { + return nil + } + if stream.Error != nil { + return stream.Error + } + n, err := stream.out.Write(stream.buf) + if err != nil { + if stream.Error == nil { + stream.Error = err + } + return err + } + stream.buf = stream.buf[n:] + return nil +} + +// WriteRaw write string out without quotes, just like []byte +func (stream *Stream) WriteRaw(s string) { + stream.buf = append(stream.buf, s...) +} + +// WriteNil write null to stream +func (stream *Stream) WriteNil() { + stream.writeFourBytes('n', 'u', 'l', 'l') +} + +// WriteTrue write true to stream +func (stream *Stream) WriteTrue() { + stream.writeFourBytes('t', 'r', 'u', 'e') +} + +// WriteFalse write false to stream +func (stream *Stream) WriteFalse() { + stream.writeFiveBytes('f', 'a', 'l', 's', 'e') +} + +// WriteBool write true or false into stream +func (stream *Stream) WriteBool(val bool) { + if val { + stream.WriteTrue() + } else { + stream.WriteFalse() + } +} + +// WriteObjectStart write { with possible indention +func (stream *Stream) WriteObjectStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('{') + stream.writeIndention(0) +} + +// WriteObjectField write "field": with possible indention +func (stream *Stream) WriteObjectField(field string) { + stream.WriteString(field) + if stream.indention > 0 { + stream.writeTwoBytes(':', ' ') + } else { + stream.writeByte(':') + } +} + +// WriteObjectEnd write } with possible indention +func (stream *Stream) WriteObjectEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte('}') +} + +// WriteEmptyObject write {} +func (stream *Stream) WriteEmptyObject() { + stream.writeByte('{') + stream.writeByte('}') +} + +// WriteMore write , with possible indention +func (stream *Stream) WriteMore() { + stream.writeByte(',') + stream.writeIndention(0) + stream.Flush() +} + +// WriteArrayStart write [ with possible indention +func (stream *Stream) WriteArrayStart() { + stream.indention += stream.cfg.indentionStep + stream.writeByte('[') + stream.writeIndention(0) +} + +// WriteEmptyArray write [] +func (stream *Stream) WriteEmptyArray() { + stream.writeTwoBytes('[', ']') +} + +// WriteArrayEnd write ] with possible indention +func (stream *Stream) WriteArrayEnd() { + stream.writeIndention(stream.cfg.indentionStep) + stream.indention -= stream.cfg.indentionStep + stream.writeByte(']') +} + +func (stream *Stream) writeIndention(delta int) { + if stream.indention == 0 { + return + } + stream.writeByte('\n') + toWrite := stream.indention - delta + for i := 0; i < toWrite; i++ { + stream.buf = append(stream.buf, ' ') + } +} diff --git a/vendor/github.com/json-iterator/go/stream_float.go b/vendor/github.com/json-iterator/go/stream_float.go new file mode 100644 index 000000000..f318d2c59 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_float.go @@ -0,0 +1,94 @@ +package jsoniter + +import ( + "math" + "strconv" +) + +var pow10 []uint64 + +func init() { + pow10 = []uint64{1, 10, 100, 1000, 10000, 100000, 1000000} +} + +// WriteFloat32 write float32 to stream +func (stream *Stream) WriteFloat32(val float32) { + abs := math.Abs(float64(val)) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if float32(abs) < 1e-6 || float32(abs) >= 1e21 { + fmt = 'e' + } + } + stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32) +} + +// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat32Lossy(val float32) { + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat32(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(float64(val)*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] + } +} + +// WriteFloat64 write float64 to stream +func (stream *Stream) WriteFloat64(val float64) { + abs := math.Abs(val) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if abs < 1e-6 || abs >= 1e21 { + fmt = 'e' + } + } + stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64) +} + +// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster +func (stream *Stream) WriteFloat64Lossy(val float64) { + if val < 0 { + stream.writeByte('-') + val = -val + } + if val > 0x4ffffff { + stream.WriteFloat64(val) + return + } + precision := 6 + exp := uint64(1000000) // 6 + lval := uint64(val*float64(exp) + 0.5) + stream.WriteUint64(lval / exp) + fval := lval % exp + if fval == 0 { + return + } + stream.writeByte('.') + for p := precision - 1; p > 0 && fval < pow10[p]; p-- { + stream.writeByte('0') + } + stream.WriteUint64(fval) + for stream.buf[len(stream.buf)-1] == '0' { + stream.buf = stream.buf[:len(stream.buf)-1] + } +} diff --git a/vendor/github.com/json-iterator/go/stream_int.go b/vendor/github.com/json-iterator/go/stream_int.go new file mode 100644 index 000000000..d1059ee4c --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_int.go @@ -0,0 +1,190 @@ +package jsoniter + +var digits []uint32 + +func init() { + digits = make([]uint32, 1000) + for i := uint32(0); i < 1000; i++ { + digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0' + if i < 10 { + digits[i] += 2 << 24 + } else if i < 100 { + digits[i] += 1 << 24 + } + } +} + +func writeFirstBuf(space []byte, v uint32) []byte { + start := v >> 24 + if start == 0 { + space = append(space, byte(v>>16), byte(v>>8)) + } else if start == 1 { + space = append(space, byte(v>>8)) + } + space = append(space, byte(v)) + return space +} + +func writeBuf(buf []byte, v uint32) []byte { + return append(buf, byte(v>>16), byte(v>>8), byte(v)) +} + +// WriteUint8 write uint8 to stream +func (stream *Stream) WriteUint8(val uint8) { + stream.buf = writeFirstBuf(stream.buf, digits[val]) +} + +// WriteInt8 write int8 to stream +func (stream *Stream) WriteInt8(nval int8) { + var val uint8 + if nval < 0 { + val = uint8(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint8(nval) + } + stream.buf = writeFirstBuf(stream.buf, digits[val]) +} + +// WriteUint16 write uint16 to stream +func (stream *Stream) WriteUint16(val uint16) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return +} + +// WriteInt16 write int16 to stream +func (stream *Stream) WriteInt16(nval int16) { + var val uint16 + if nval < 0 { + val = uint16(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint16(nval) + } + stream.WriteUint16(val) +} + +// WriteUint32 write uint32 to stream +func (stream *Stream) WriteUint32(val uint32) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q2]) + } else { + r3 := q2 - q3*1000 + stream.buf = append(stream.buf, byte(q3+'0')) + stream.buf = writeBuf(stream.buf, digits[r3]) + } + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) +} + +// WriteInt32 write int32 to stream +func (stream *Stream) WriteInt32(nval int32) { + var val uint32 + if nval < 0 { + val = uint32(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint32(nval) + } + stream.WriteUint32(val) +} + +// WriteUint64 write uint64 to stream +func (stream *Stream) WriteUint64(val uint64) { + q1 := val / 1000 + if q1 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[val]) + return + } + r1 := val - q1*1000 + q2 := q1 / 1000 + if q2 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q1]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r2 := q1 - q2*1000 + q3 := q2 / 1000 + if q3 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q2]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r3 := q2 - q3*1000 + q4 := q3 / 1000 + if q4 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q3]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r4 := q3 - q4*1000 + q5 := q4 / 1000 + if q5 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q4]) + stream.buf = writeBuf(stream.buf, digits[r4]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) + return + } + r5 := q4 - q5*1000 + q6 := q5 / 1000 + if q6 == 0 { + stream.buf = writeFirstBuf(stream.buf, digits[q5]) + } else { + stream.buf = writeFirstBuf(stream.buf, digits[q6]) + r6 := q5 - q6*1000 + stream.buf = writeBuf(stream.buf, digits[r6]) + } + stream.buf = writeBuf(stream.buf, digits[r5]) + stream.buf = writeBuf(stream.buf, digits[r4]) + stream.buf = writeBuf(stream.buf, digits[r3]) + stream.buf = writeBuf(stream.buf, digits[r2]) + stream.buf = writeBuf(stream.buf, digits[r1]) +} + +// WriteInt64 write int64 to stream +func (stream *Stream) WriteInt64(nval int64) { + var val uint64 + if nval < 0 { + val = uint64(-nval) + stream.buf = append(stream.buf, '-') + } else { + val = uint64(nval) + } + stream.WriteUint64(val) +} + +// WriteInt write int to stream +func (stream *Stream) WriteInt(val int) { + stream.WriteInt64(int64(val)) +} + +// WriteUint write uint to stream +func (stream *Stream) WriteUint(val uint) { + stream.WriteUint64(uint64(val)) +} diff --git a/vendor/github.com/json-iterator/go/stream_str.go b/vendor/github.com/json-iterator/go/stream_str.go new file mode 100644 index 000000000..54c2ba0b3 --- /dev/null +++ b/vendor/github.com/json-iterator/go/stream_str.go @@ -0,0 +1,372 @@ +package jsoniter + +import ( + "unicode/utf8" +) + +// htmlSafeSet holds the value true if the ASCII character with the given +// array position can be safely represented inside a JSON string, embedded +// inside of HTML