Fix: Add TTL and custom Timeout in DigitalOcean DNS provider
This commit is contained in:
parent
66485e81b4
commit
0ef1b7b683
120 changed files with 23764 additions and 9782 deletions
201
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/LICENSE
generated
vendored
Normal file
201
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/LICENSE
generated
vendored
Normal file
|
@ -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.
|
36
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/api.go
generated
vendored
Normal file
36
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/api.go
generated
vendored
Normal file
|
@ -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{}
|
111
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/client.go
generated
vendored
Normal file
111
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/client.go
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Package client is a simple library for http.Client to sign Akamai OPEN Edgegrid API requests
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
|
||||
"github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1"
|
||||
)
|
||||
|
||||
var (
|
||||
libraryVersion = "0.6.0"
|
||||
// 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)
|
||||
|
||||
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) {
|
||||
jsonBody, err := jsonhooks.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := bytes.NewReader(jsonBody)
|
||||
req, err := NewRequest(config, method, path, buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Accept", "application/json,*/*")
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
88
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/errors.go
generated
vendored
Normal file
88
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
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"`
|
||||
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:"-"`
|
||||
}
|
||||
|
||||
func (error APIError) Error() string {
|
||||
return strings.TrimSpace(fmt.Sprintf("API Error: %d %s %s More Info %s", error.Status, error.Title, error.Detail, error.Type))
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
125
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/errors.go
generated
vendored
Normal file
125
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/errors.go
generated
vendored
Normal file
|
@ -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 "<nil>"
|
||||
}
|
||||
|
||||
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 "<nil>"
|
||||
}
|
1738
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/record.go
generated
vendored
Normal file
1738
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/record.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
16
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/service.go
generated
vendored
Normal file
16
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/service.go
generated
vendored
Normal file
|
@ -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
|
||||
}
|
1557
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/zone.go
generated
vendored
Normal file
1557
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v1/zone.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
181
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/config.go
generated
vendored
Normal file
181
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/config.go
generated
vendored
Normal file
|
@ -0,0 +1,181 @@
|
|||
package edgegrid
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-ini/ini"
|
||||
"gopkg.in/mattes/go-expand-tilde.v1"
|
||||
)
|
||||
|
||||
// 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"`
|
||||
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 := tilde.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
|
||||
}
|
22
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/errors.go
generated
vendored
Normal file
22
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/errors.go
generated
vendored
Normal file
|
@ -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",
|
||||
}
|
||||
)
|
195
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/signer.go
generated
vendored
Normal file
195
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid/signer.go
generated
vendored
Normal file
|
@ -0,0 +1,195 @@
|
|||
// 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"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tuvistavie/securerandom"
|
||||
)
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
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 := securerandom.Uuid()
|
||||
if err != nil {
|
||||
log.Errorf(errorMap[ErrUUIDGenerateFailed], err)
|
||||
return ""
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
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
|
||||
}
|
1
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/errors.go
generated
vendored
Normal file
1
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/errors.go
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package jsonhooks
|
69
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/jsonhooks.go
generated
vendored
Normal file
69
vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1/jsonhooks.go
generated
vendored
Normal file
|
@ -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.Kind() == reflect.Ptr && value.IsNil() {
|
||||
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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue