mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-10-25 05:27:26 +08:00
NEW PROVIDER: AkamaiEdgeDNS (#1174)
* downcase TLSA * Akamai provider * Akamai provider * EdgeDNS provider * AkamaiEdgeDNS provider * AkamaiEdgeDNS provider * AkamaiEdgeDNS provider Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
This commit is contained in:
parent
12ff5cff97
commit
be1f03fb75
24 changed files with 857 additions and 63 deletions
1
OWNERS
1
OWNERS
|
|
@ -1,4 +1,5 @@
|
|||
# providers/activedir
|
||||
providers/akamaiedgedns @svernick
|
||||
providers/axfrddns @hnrgrgr
|
||||
providers/azuredns @vatsalyagoel
|
||||
providers/bind @tlimoncelli
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ Currently supported DNS providers:
|
|||
- AWS Route 53
|
||||
- AXFR+DDNS
|
||||
- Active Directory (Deprecated, see Microsoft DNS)
|
||||
- Akamai Edge DNS
|
||||
- Azure DNS
|
||||
- BIND
|
||||
- ClouDNS
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ func generateFeatureMatrix() error {
|
|||
{"R53_ALIAS", "Provider supports Route 53 limited ALIAS"},
|
||||
{"AZURE_ALIAS", "Provider supports Azure DNS limited ALIAS"},
|
||||
{"DS", "Provider supports adding DS records"},
|
||||
{ "AKAMAICDN", "Provider supports adding AKAMAICDN records"},
|
||||
|
||||
{"dual host", "This provider is recommended for use in 'dual hosting' scenarios. Usually this means the provider allows full control over the apex NS records"},
|
||||
{"create-domains", "This means the provider can automatically create domains that do not currently exist on your account. The 'dnscontrol create-domains' command will initialize any missing domains"},
|
||||
|
|
@ -88,6 +89,7 @@ func generateFeatureMatrix() error {
|
|||
setCap("SRV", providers.CanUseSRV)
|
||||
setCap("SSHFP", providers.CanUseSSHFP)
|
||||
setCap("TLSA", providers.CanUseTLSA)
|
||||
setCap("AKAMAICDN", providers.CanUseAKAMAICDN)
|
||||
setCap("get-zones", providers.CanGetZones)
|
||||
setCap("DS", providers.CanUseDS)
|
||||
setDoc("dual host", providers.DocDualHost, false)
|
||||
|
|
|
|||
10
docs/_functions/domain/AKAMAICDN.md
Normal file
10
docs/_functions/domain/AKAMAICDN.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
name: AKAMAICDN
|
||||
parameters:
|
||||
- name
|
||||
- target
|
||||
- modifiers...
|
||||
---
|
||||
|
||||
AKAMAICDN is a proprietary record type that is used to configure [Zone Apex Mapping](https://blogs.akamai.com/2019/08/fast-dns-zone-apex-mapping-dnssec.html).
|
||||
The AKAMAICDN target must be preconfigured in the Akamai network.
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
<tr>
|
||||
<th></th>
|
||||
<th class="rotate"><div><span>ACTIVEDIRECTORY_PS</span></div></th>
|
||||
<th class="rotate"><div><span>AKAMAIEDGEDNS</span></div></th>
|
||||
<th class="rotate"><div><span>AXFRDDNS</span></div></th>
|
||||
<th class="rotate"><div><span>AZURE_DNS</span></div></th>
|
||||
<th class="rotate"><div><span>BIND</span></div></th>
|
||||
|
|
@ -52,6 +53,9 @@
|
|||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -172,6 +176,9 @@
|
|||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -280,6 +287,9 @@
|
|||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -373,6 +383,9 @@
|
|||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="Azure DNS does not provide a generic ALIAS functionality. Use AZURE_ALIAS instead.">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
|
|
@ -455,6 +468,9 @@
|
|||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider can automatically manage DNSSEC">AUTODNSSEC</th>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success" data-toggle="tooltip" data-container="body" data-placement="top" title="Just warn when DNSSEC is requested but no RRSIG is found in the AXFR or warn when DNSSEC is not requested but RRSIG are found in the AXFR.">
|
||||
<i class="fa has-tooltip fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -526,6 +542,9 @@
|
|||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
|
|
@ -612,6 +631,9 @@
|
|||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -698,6 +720,9 @@
|
|||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -753,6 +778,9 @@
|
|||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider can manage SOA records">SOA</th>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
|
|
@ -810,6 +838,9 @@
|
|||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
|
|
@ -894,6 +925,9 @@
|
|||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -968,6 +1002,9 @@
|
|||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -1081,6 +1118,7 @@
|
|||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider supports Route 53 limited ALIAS">R53_ALIAS</th>
|
||||
|
|
@ -1101,6 +1139,7 @@
|
|||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="Using ALIAS is possible through our extended DNS (X-DNS) service. Feel free to get in touch with us.">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -1130,6 +1169,7 @@
|
|||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider supports Azure DNS limited ALIAS">AZURE_ALIAS</th>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -1173,6 +1213,9 @@
|
|||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider supports adding DS records">DS</th>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
|
|
@ -1230,11 +1273,55 @@
|
|||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="Provider supports adding AKAMAICDN records">AKAMAICDN</th>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
<td><i class="fa fa-minus dim"></i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="row-header" style="text-decoration: underline;" data-toggle="tooltip" data-container="body" data-placement="top" title="This provider is recommended for use in 'dual hosting' scenarios. Usually this means the provider allows full control over the apex NS records">dual host</th>
|
||||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="This driver does not manage NS records, so should not be used for dual-host scenarios">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -1327,6 +1414,9 @@
|
|||
<td class="danger" data-toggle="tooltip" data-container="body" data-placement="top" title="AD depends on the zone already existing on the dns server">
|
||||
<i class="fa has-tooltip fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -1438,6 +1528,9 @@
|
|||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
@ -1543,6 +1636,9 @@
|
|||
<td class="info">
|
||||
<i class="fa fa-circle-o text-info" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="success">
|
||||
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||
</td>
|
||||
<td class="danger">
|
||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
||||
</td>
|
||||
|
|
|
|||
76
docs/_providers/akamaiedgedns.md
Normal file
76
docs/_providers/akamaiedgedns.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
---
|
||||
name: AkamaiEdgeDns
|
||||
title: Akamai Edge DNS Provider
|
||||
layout: default
|
||||
jsId: AKAMAIEDGEDNS
|
||||
---
|
||||
|
||||
# Akamai Edge DNS Provider
|
||||
|
||||
"Akamai Edge DNS Provider" configures Akamai's
|
||||
[Edge DNS](https://www.akamai.com/us/en/products/security/edge-dns.jsp) service.
|
||||
|
||||
This provider interacts with Edge DNS via the
|
||||
[Edge DNS Zone Management API](https://developer.akamai.com/api/cloud_security/edge_dns_zone_management/v2.html).
|
||||
|
||||
Before you can use this provider, you need to create an "API Client" with authorization to use the
|
||||
[Edge DNS Zone Management API](https://developer.akamai.com/api/cloud_security/edge_dns_zone_management/v2.html).
|
||||
|
||||
See the "Get Started" section of [Edge DNS Zone Management API](https://developer.akamai.com/api/cloud_security/edge_dns_zone_management/v2.html),
|
||||
which says, "To enable this API, choose the API service named DNS—Zone Record Management, and set the access level to READ-WRITE."
|
||||
|
||||
Follow directions at [Authenticate With EdgeGrid](https://developer.akamai.com/getting-started/edgegrid) to generate
|
||||
the required credentials.
|
||||
|
||||
## Configuration
|
||||
|
||||
In the credentials file (creds.json), you must provide the following:
|
||||
{% highlight json %}
|
||||
"akamaiedgedns": {
|
||||
"client_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"host": "akaa-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxx.akamaiapis.net",
|
||||
"access_token": "akaa-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"client_token": "akaa-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"contract_id": "X-XXXX",
|
||||
"group_id": "NNNNNN"
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
## Usage
|
||||
|
||||
A new zone created by DNSControl:
|
||||
|
||||
```
|
||||
dnscontrol create-domains
|
||||
```
|
||||
|
||||
automatically creates SOA and authoritative NS records.
|
||||
|
||||
Akamai assigns a unique set of authoritative nameservers for each contract. These authorities should be
|
||||
used as the NS records on all zones belonging to this contract.
|
||||
|
||||
The NS records for these authorities have a TTL of 86400.
|
||||
|
||||
Add:
|
||||
|
||||
```
|
||||
NAMESERVER_TTL(86400)
|
||||
```
|
||||
|
||||
modifier to the dnscontrol.js D() function so that DNSControl does not change the TTL of the authoritative NS records.
|
||||
|
||||
Example 'dnsconfig.js':
|
||||
{% highlight js %}
|
||||
var REG_NONE = NewRegistrar('none', 'NONE');
|
||||
var DNS_AKAMAIEDGEDNS = NewDnsProvider('akamaiedgedns', 'AKAMAIEDGEDNS');
|
||||
|
||||
D('example.com', REG_NONE, DnsProvider(DNS_AKAMAIEDGEDNS),
|
||||
NAMESERVER_TTL(86400),
|
||||
AUTODNSSEC_ON,
|
||||
AKAMAICDN("@", "www.preconfigured.edgesuite.net", TTL(20)),
|
||||
A('foo','1.2.3.4')
|
||||
);
|
||||
{% endhighlight %}
|
||||
|
||||
AKAMAICDN is a proprietary record type that is used to configure [Zone Apex Mapping](https://blogs.akamai.com/2019/08/fast-dns-zone-apex-mapping-dnssec.html).
|
||||
The AKAMAICDN target must be preconfigured in the Akamai network.
|
||||
|
|
@ -72,6 +72,7 @@ provided to help community members support their code independently.
|
|||
Maintainers of contributed providers:
|
||||
|
||||
* `AXFRDDNS` @hnrgrgr
|
||||
* `AKAMAIEDGEDNS` @svernick
|
||||
* `CLOUDNS` @pragmaton
|
||||
* `CSCGLOBAL` @Air-New-Zealand
|
||||
* `DESEC` @D3luxee
|
||||
|
|
|
|||
31
go.mod
31
go.mod
|
|
@ -3,36 +3,35 @@ module github.com/StackExchange/dnscontrol/v3
|
|||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go v55.1.0+incompatible
|
||||
github.com/Azure/azure-sdk-for-go v55.2.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.7
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0
|
||||
github.com/DisposaBoy/JsonConfigReader v0.0.0-20201129172854-99cf318d67e7
|
||||
github.com/PuerkitoBio/goquery v1.6.1
|
||||
github.com/TomOnTime/utfutil v0.0.0-20200626160131-0b0178852c8f
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.1
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
|
||||
github.com/andybalholm/cascadia v1.2.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.38.53
|
||||
github.com/aws/aws-sdk-go v1.38.58
|
||||
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6
|
||||
github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e
|
||||
github.com/billputer/go-namecheap v0.0.0-20170915210158-0c7adb0710f8
|
||||
github.com/billputer/go-namecheap v0.0.0-20210108011502-994a912fb7f9
|
||||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/daaku/go.zipexe v1.0.1 // indirect
|
||||
github.com/digitalocean/godo v1.61.0
|
||||
github.com/digitalocean/godo v1.62.0
|
||||
github.com/ditashi/jsbeautifier-go v0.0.0-20141206144643-2520a8026a9c
|
||||
github.com/dnsimple/dnsimple-go v0.62.0
|
||||
github.com/exoscale/egoscale v0.23.0
|
||||
github.com/dnsimple/dnsimple-go v0.70.1
|
||||
github.com/exoscale/egoscale v1.19.0
|
||||
github.com/fatih/color v1.10.0 // indirect
|
||||
github.com/frankban/quicktest v1.11.3 // indirect
|
||||
github.com/go-acme/lego v2.7.2+incompatible
|
||||
github.com/go-gandi/go-gandi v0.0.0-20200921091836-0d8a64b9cc09
|
||||
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe
|
||||
github.com/gofrs/uuid v4.0.0+incompatible // indirect
|
||||
github.com/golang/snappy v0.0.3 // indirect
|
||||
github.com/google/go-github/v35 v35.2.0
|
||||
github.com/google/go-querystring v1.0.1-0.20190318165438-c8c88dbee036 // indirect
|
||||
github.com/google/go-github/v35 v35.3.0
|
||||
github.com/gopherjs/jquery v0.0.0-20191017083323-73f4c7416038
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
|
|
@ -49,32 +48,30 @@ require (
|
|||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
||||
github.com/nrdcg/goinwx v0.8.1
|
||||
github.com/oracle/oci-go-sdk/v32 v32.0.0
|
||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
||||
github.com/ovh/go-ovh v1.1.0
|
||||
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d
|
||||
github.com/pierrec/lz4 v2.6.0+incompatible // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pquerna/otp v1.3.0
|
||||
github.com/qdm12/reprint v0.0.0-20200326205758-722754a53494
|
||||
github.com/renier/xmlrpc v0.0.0-20191022213033-ce560eccbd00 // indirect
|
||||
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/smartystreets/assertions v1.0.0 // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/softlayer/softlayer-go v0.0.0-20170804160555-5e1c8cccc730
|
||||
github.com/softlayer/softlayer-go v1.0.3
|
||||
github.com/stretchr/objx v0.3.0 // indirect
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/tdewolff/minify/v2 v2.9.17
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
github.com/vultr/govultr v1.0.0
|
||||
github.com/vultr/govultr v1.1.1
|
||||
github.com/xddxdd/ottoext v0.0.0-20210101073831-439879ee6281
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
google.golang.org/api v0.47.0
|
||||
google.golang.org/api v0.48.0
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
gopkg.in/ns1/ns1-go.v2 v2.4.4
|
||||
gopkg.in/ns1/ns1-go.v2 v2.5.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
|
|
|||
102
go.sum
102
go.sum
|
|
@ -17,8 +17,9 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP
|
|||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go v0.83.0 h1:bAMqZidYkmIsUqe6PtkEPT7Q+vfizScn+jfNA6jwK9c=
|
||||
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
|
|
@ -37,8 +38,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
|||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v55.1.0+incompatible h1:B+zsJuu6v/LyVPO59e6/7T/JoU6+eLLE574wLJ1NT6A=
|
||||
github.com/Azure/azure-sdk-for-go v55.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v55.2.0+incompatible h1:TL2/vJWJEPOrmv97nHcbvjXES0Ntlb9P95hqGA1J2dU=
|
||||
github.com/Azure/azure-sdk-for-go v55.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
|
|
@ -75,6 +76,8 @@ github.com/PuerkitoBio/goquery v1.6.1 h1:FgjbQZKl5HTmcn4sKBgvx8vv63nhyhIpv7lJpFG
|
|||
github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/TomOnTime/utfutil v0.0.0-20200626160131-0b0178852c8f h1:MXp+2PP1RxWWoE3qmOecVblerzKCryXkFXq9er+EDr8=
|
||||
github.com/TomOnTime/utfutil v0.0.0-20200626160131-0b0178852c8f/go.mod h1:FiuynIwe98RFhWI8nZ0dnsldPVsBy9rHH1hn2WYwme4=
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.1 h1:bLzehmpyCwQiqCE1Qe9Ny6fbFqs7hPlmo9vKv2orUxs=
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.1.1/go.mod h1:kX6YddBkXqqywAe8c9LyvgTCyFuZCTMF4cRPQhc3Fy8=
|
||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/alecthomas/kong v0.2.2/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
|
|
@ -85,16 +88,16 @@ github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxB
|
|||
github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.38.53 h1:Qj5OvKPrDGTiCnWj+kwQXAlBO6OaFBH/WaRzJPZPg3w=
|
||||
github.com/aws/aws-sdk-go v1.38.53/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go v1.38.58 h1:s4BKYcepKuX73xRTSRI3dQCfAM3zwmKgTLvjG/wtBEM=
|
||||
github.com/aws/aws-sdk-go v1.38.58/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 h1:4NNbNM2Iq/k57qEu7WfL67UrbPq1uFWxW4qODCohi+0=
|
||||
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6/go.mod h1:J29hk+f9lJrblVIfiJOtTFk+OblBawmib4uz/VdKzlg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e h1:KCjb01YiNoRaJ5c+SbnPLWjVzU9vqRYHg3e5JcN50nM=
|
||||
github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e/go.mod h1:f7vw6ObmmNcyFQLhZX9eUGBJGpnwTJFDvVjqZxIxHWY=
|
||||
github.com/billputer/go-namecheap v0.0.0-20170915210158-0c7adb0710f8 h1:sIv3xbwhhAG94a62Q/rrSBtrWcXiYgldNOeqifyKSgo=
|
||||
github.com/billputer/go-namecheap v0.0.0-20170915210158-0c7adb0710f8/go.mod h1:bqqNsI2akL+lLWyApkYY0cxquWPKwEBU0Wd3chi3TEg=
|
||||
github.com/billputer/go-namecheap v0.0.0-20210108011502-994a912fb7f9 h1:2vQTbEJvFsyd1VefzZ34GUkUD6TkJleYYJh9/25WBE4=
|
||||
github.com/billputer/go-namecheap v0.0.0-20210108011502-994a912fb7f9/go.mod h1:bqqNsI2akL+lLWyApkYY0cxquWPKwEBU0Wd3chi3TEg=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
|
|
@ -121,15 +124,15 @@ github.com/daaku/go.zipexe v1.0.1/go.mod h1:5xWogtqlYnfBXkSB1o9xysukNP9GTvaNkqzU
|
|||
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/digitalocean/godo v1.61.0 h1:PChvUn5+Ajwvl7caOJoFbcM9r+y91ssQbM0W0k3pnZU=
|
||||
github.com/digitalocean/godo v1.61.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
|
||||
github.com/digitalocean/godo v1.62.0 h1:7Gw2KFsWkxl36qJa0s50tgXaE0Cgm51JdRP+MFQvNnM=
|
||||
github.com/digitalocean/godo v1.62.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
||||
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
|
||||
github.com/ditashi/jsbeautifier-go v0.0.0-20141206144643-2520a8026a9c h1:+Zo5Ca9GH0RoeVZQKzFJcTLoAixx5s5Gq3pTIS+n354=
|
||||
github.com/ditashi/jsbeautifier-go v0.0.0-20141206144643-2520a8026a9c/go.mod h1:HJGU9ULdREjOcVGZVPB5s6zYmHi1RxzT71l2wQyLmnE=
|
||||
github.com/dnsimple/dnsimple-go v0.62.0 h1:Lr4U8F08FBL90rMEtQMR547RebifgwTPGCRC/+6ZW4g=
|
||||
github.com/dnsimple/dnsimple-go v0.62.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
|
||||
github.com/dnsimple/dnsimple-go v0.70.1 h1:cSZndVjttLpgplDuesY4LFIvfKf/zRA1J7mCATBbzSM=
|
||||
github.com/dnsimple/dnsimple-go v0.70.1/go.mod h1:F9WHww9cC76hrnwGFfAfrqdW99j3MOYasQcIwTS/aUk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
|
|
@ -138,8 +141,8 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
|
|||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/exoscale/egoscale v0.23.0 h1:hoUDzrO8yNoobNdnrRvlRFjfg3Ng0vQTrv6bXRJu6z0=
|
||||
github.com/exoscale/egoscale v0.23.0/go.mod h1:hRo78jkjkCDKpivQdRBEpNYF5+cVpCJCPDg2/r45KaY=
|
||||
github.com/exoscale/egoscale v1.19.0 h1:DbSyyzaPyxDBgGOuduCU26rQ4PJb/GP+8srXRabRf5U=
|
||||
github.com/exoscale/egoscale v1.19.0/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
|
|
@ -213,16 +216,18 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v35 v35.2.0 h1:s/soW8jauhjUC3rh8JI0FePuocj0DEI9DNBg/bVplE8=
|
||||
github.com/google/go-github/v35 v35.2.0/go.mod h1:s0515YVTI+IMrDoy9Y4pHt9ShGpzHvHO8rZ7L7acgvs=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v35 v35.3.0 h1:fU+WBzuukn0VssbayTT+Zo3/ESKX9JYWjbZTLOTEyho=
|
||||
github.com/google/go-github/v35 v35.3.0/go.mod h1:yWB7uCcVWaUbUP74Aq3whuMySRMatyRmq5U9FTNlbio=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.0.1-0.20190318165438-c8c88dbee036 h1:Avad62mreCc9la5buHvHZXbvsY+GPYUVjd8xsi48FYY=
|
||||
github.com/google/go-querystring v1.0.1-0.20190318165438-c8c88dbee036/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
|
|
@ -234,7 +239,10 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
|
|||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/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=
|
||||
|
|
@ -287,6 +295,7 @@ github.com/hexonet/go-sdk/v3 v3.5.2 h1:zNY5NjlKdamBHy9NKmX4WSAL9wvKJ+KoWLrrQAbmC
|
|||
github.com/hexonet/go-sdk/v3 v3.5.2/go.mod h1:X/TQ5RQ7MMNsTajP4/lr3/eBkOoz8qUiha2lydNBGZE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
|
||||
github.com/jarcoal/httpmock v1.0.8 h1:8kI16SoO6LQKgPE7PvQuV+YuD/inwHd7fOOe2zMbo4k=
|
||||
github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
|
|
@ -333,6 +342,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
|||
github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ=
|
||||
github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b h1:iNjcivnc6lhbvJA3LD622NPrUponluJrBWPIwGG/3Bg=
|
||||
github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
|
|
@ -385,9 +396,11 @@ github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH
|
|||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oracle/oci-go-sdk/v32 v32.0.0 h1:SSbzrQO3WRcPJEZ8+b3SFPYsPtkFM96clqrp03lrwbU=
|
||||
github.com/oracle/oci-go-sdk/v32 v32.0.0/go.mod h1:aZc4jC59IuNP3cr5y1nj555QvwojMX2nMJaBiozuuEs=
|
||||
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/ovh/go-ovh v1.1.0 h1:bHXZmw8nTgZin4Nv7JuaLs0KG5x54EQR7migYTd1zrk=
|
||||
github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d h1:nf4+lHs8TQeIGFYZMcNg4iQOnZndLfYxnQaKEdqHVA4=
|
||||
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d/go.mod h1:VDIGNBy0tHXMDAu4gxHFQJDq3NuwqUxw2Kok7wi+6ck=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
|
|
@ -408,8 +421,6 @@ github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7q
|
|||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/qdm12/reprint v0.0.0-20200326205758-722754a53494 h1:wSmWgpuccqS2IOfmYrbRiUgv+g37W5suLLLxwwniTSc=
|
||||
github.com/qdm12/reprint v0.0.0-20200326205758-722754a53494/go.mod h1:yipyliwI08eQ6XwDm1fEwKPdF/xdbkiHtrU+1Hg+vc4=
|
||||
github.com/renier/xmlrpc v0.0.0-20191022213033-ce560eccbd00 h1:mKU5SDtoxNCBexJlsba8dNKN8SoDNMibWxVEowW1fig=
|
||||
github.com/renier/xmlrpc v0.0.0-20191022213033-ce560eccbd00/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU=
|
||||
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac h1:kYPjbEN6YPYWWHI6ky1J813KzIq/8+Wg4TO4xU7A/KU=
|
||||
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
|
|
@ -422,15 +433,20 @@ github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIH
|
|||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/softlayer/softlayer-go v0.0.0-20170804160555-5e1c8cccc730 h1:NFtcXPhyIM81jGPrxh5OvdRM1esrM2lIYlO0SFm3KOg=
|
||||
github.com/softlayer/softlayer-go v0.0.0-20170804160555-5e1c8cccc730/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw=
|
||||
github.com/softlayer/softlayer-go v1.0.3 h1:9FONm5xzQ9belQtbdryR6gBg4EF6hX6lrjNKi0IvZkU=
|
||||
github.com/softlayer/softlayer-go v1.0.3/go.mod h1:6HepcfAXROz0Rf63krk5hPZyHT6qyx2MNvYyHof7ik4=
|
||||
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e h1:3OgWYFw7jxCZPcvAg+4R8A50GZ+CCkARF10lxu2qDsQ=
|
||||
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e/go.mod h1:fKZCUVdirrxrBpwd9wb+lSoVixvpwAu8eHzbQB2tums=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
|
||||
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
|
|
@ -449,10 +465,13 @@ github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
|||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/vultr/govultr v1.0.0 h1:yeJrYp9wyA4xXaQZ7eOL2u1wKn2JU79HjRevwvpxbJ4=
|
||||
github.com/vultr/govultr v1.0.0/go.mod h1:wZZXZbYbqyY1n3AldoeYNZK4Wnmmoq6dNFkvd5TV3ss=
|
||||
github.com/vultr/govultr v1.1.1 h1:ntltxMYyJstjKz1v2CLNxFZiqjlt/8HqD1GZeJ/fAMc=
|
||||
github.com/vultr/govultr v1.1.1/go.mod h1:QXCNTRg0nwu95ayiMC3feYvrAFTLnj94s2FiibIpoC4=
|
||||
github.com/xddxdd/ottoext v0.0.0-20210101073831-439879ee6281 h1:QruJ/b9zaFRxtNYvekIXlqWh/BoJJrSJg+FdmMNp8cw=
|
||||
github.com/xddxdd/ottoext v0.0.0-20210101073831-439879ee6281/go.mod h1:8Hr+gV9GtucFQOptKfzuYxqg++CyIjg4E7QCR7F3Dxw=
|
||||
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.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
|
@ -553,8 +572,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b h1:k+E048sYJHyVnsr1GDrRZWQ32D2C7lWs9JRc0bel53A=
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
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/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
|
@ -588,6 +607,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
@ -627,8 +647,9 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I=
|
||||
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
@ -680,6 +701,7 @@ golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapK
|
|||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
|
|
@ -694,6 +716,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
@ -720,8 +743,9 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q
|
|||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.47.0 h1:sQLWZQvP6jPGIP4JGPkJu4zHswrv81iobiyszr3b/0I=
|
||||
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
|
||||
google.golang.org/api v0.48.0 h1:RDAPWfNFY06dffEXfn7hZF5Fr1ZbnChzfQZAPyBd1+I=
|
||||
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
|
||||
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/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
|
@ -769,8 +793,10 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D
|
|||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384 h1:z+j74wi4yV+P7EtK9gPLGukOk7mFOy9wMQaC0wNb7eY=
|
||||
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08 h1:pc16UedxnxXXtGxHCSUhafAoVHQZ0yXl8ZelMH4EETc=
|
||||
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
|
|
@ -791,8 +817,11 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
|
|||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.1 h1:ARnQJNWxGyYJpdf/JXscNlQr/uv607ZPU9Z7ogHi+iI=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
|
@ -814,15 +843,18 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
|
|||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v1 v1.0.0-20161222125816-442357a80af5/go.mod h1:u0ALmqvLRxLI95fkdCEWrE6mhWYZW1aMOJHp5YXLHTg=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/h2non/gock.v1 v1.0.14 h1:fTeu9fcUvSnLNacYvYI54h+1/XEteDyHvrVCZEEEYNM=
|
||||
gopkg.in/h2non/gock.v1 v1.0.14/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
|
||||
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/httprequest.v1 v1.1.1/go.mod h1:/CkavNL+g3qLOrpFHVrEx4NKepeqR4XTZWNj4sGGjz0=
|
||||
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20160818015218-f2b6f6c918c4/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/ns1/ns1-go.v2 v2.4.4 h1:xV/rJE2m8p3IncnwMEFrv36K4NDnRXu4CoIkgq+AZek=
|
||||
gopkg.in/ns1/ns1-go.v2 v2.4.4/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk=
|
||||
gopkg.in/ns1/ns1-go.v2 v2.5.1 h1:yDCffh6bVBQuOUHuikJ2CC3cnMmsu8biEEwtLkpxVSI=
|
||||
gopkg.in/ns1/ns1-go.v2 v2.5.1/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk=
|
||||
gopkg.in/readline.v1 v1.0.0-20160726135117-62c6fe619375/go.mod h1:lNEQeAhU009zbRxng+XOj5ITVgY24WcbNnQopyfKoYQ=
|
||||
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||
|
|
|
|||
|
|
@ -986,8 +986,9 @@ func makeTests(t *testing.T) []*TestGroup {
|
|||
|
||||
testgroup("pager1201",
|
||||
only(
|
||||
//"MSDNS", // No paging done. No need to test.
|
||||
//"AZURE_DNS", // Currently failing. See https://github.com/StackExchange/dnscontrol/issues/770
|
||||
//"MSDNS", // No paging done. No need to test.
|
||||
//"AKAMAIEDGEDNS", // No paging done. No need to test.
|
||||
//"AZURE_DNS", // Currently failing. See https://github.com/StackExchange/dnscontrol/issues/770
|
||||
"HEXONET",
|
||||
"HOSTINGDE",
|
||||
//"ROUTE53", // Currently failing. See https://github.com/StackExchange/dnscontrol/issues/908
|
||||
|
|
|
|||
|
|
@ -58,6 +58,15 @@
|
|||
"api_key": "$DNSMADEEASY_API_KEY",
|
||||
"secret_key": "$DNSMADEEASY_SECRET_KEY"
|
||||
},
|
||||
"AKAMAIEDGEDNS": {
|
||||
"client_secret": "$AED_CLIENT_SECRET",
|
||||
"host": "$AED_HOST",
|
||||
"access_token": "$AED_ACCESS_TOKEN",
|
||||
"client_token": "$AED_CLIENT_TOKEN",
|
||||
"contract_id": "$AED_CONTRACT_ID",
|
||||
"group_id": "$AED_GROUP_ID",
|
||||
"domain": "$AED_DOMAIN"
|
||||
},
|
||||
"EXOSCALE": {
|
||||
"apikey": "$EXOSCALE_API_KEY",
|
||||
"dns-endpoint": "https://api.exoscale.ch/dns",
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ func (dc *DomainConfig) Punycode() error {
|
|||
|
||||
// Set the target:
|
||||
switch rec.Type { // #rtype_variations
|
||||
case "ALIAS", "MX", "NS", "CNAME", "PTR", "SRV", "URL", "URL301", "FRAME", "R53_ALIAS", "NS1_URLFWD":
|
||||
case "ALIAS", "MX", "NS", "CNAME", "PTR", "SRV", "URL", "URL301", "FRAME", "R53_ALIAS", "NS1_URLFWD", "AKAMAICDN":
|
||||
// These rtypes are hostnames, therefore need to be converted (unlike, for example, an AAAA record)
|
||||
t, err := idna.ToASCII(rec.GetTargetField())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -499,10 +499,10 @@ func downcase(recs []*RecordConfig) {
|
|||
r.Name = strings.ToLower(r.Name)
|
||||
r.NameFQDN = strings.ToLower(r.NameFQDN)
|
||||
switch r.Type { // #rtype_variations
|
||||
case "ANAME", "CNAME", "DS", "MX", "NS", "PTR", "NAPTR", "SRV":
|
||||
case "ANAME", "CNAME", "DS", "MX", "NS", "PTR", "NAPTR", "SRV", "TLSA", "AKAMAICDN":
|
||||
// These record types have a target that is case insensitive, so we downcase it.
|
||||
r.target = strings.ToLower(r.target)
|
||||
case "A", "AAAA", "ALIAS", "CAA", "IMPORT_TRANSFORM", "TLSA", "TXT", "SSHFP", "CF_REDIRECT", "CF_TEMP_REDIRECT":
|
||||
case "A", "AAAA", "ALIAS", "CAA", "IMPORT_TRANSFORM", "TXT", "SSHFP", "CF_REDIRECT", "CF_TEMP_REDIRECT":
|
||||
// These record types have a target that is case sensitive, or is an IP address. We leave them alone.
|
||||
// Do nothing.
|
||||
case "SOA":
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func (r *RecordConfig) PopulateFromString(rtype, contents, origin string) error
|
|||
return fmt.Errorf("invalid IP in AAAA record: %s", contents)
|
||||
}
|
||||
return r.SetTargetIP(ip) // Reformat to canonical form.
|
||||
case "ALIAS", "ANAME", "CNAME", "NS", "PTR":
|
||||
case "AKAMAICDN", "ALIAS", "ANAME", "CNAME", "NS", "PTR":
|
||||
return r.SetTarget(contents)
|
||||
case "CAA":
|
||||
return r.SetTargetCAAString(contents)
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ func (rc *RecordConfig) GetTargetSortable() string {
|
|||
func (rc *RecordConfig) GetTargetDebug() string {
|
||||
content := fmt.Sprintf("%s %s %s %d", rc.Type, rc.NameFQDN, rc.target, rc.TTL)
|
||||
switch rc.Type { // #rtype_variations
|
||||
case "A", "AAAA", "CNAME", "NS", "PTR", "TXT":
|
||||
case "A", "AAAA", "CNAME", "NS", "PTR", "TXT", "AKAMAICDN":
|
||||
// Nothing special.
|
||||
case "DS":
|
||||
content += fmt.Sprintf(" ds_algorithm=%d ds_keytag=%d ds_digesttype=%d ds_digest=%s", rc.DsAlgorithm, rc.DsKeyTag, rc.DsDigestType, rc.DsDigest)
|
||||
|
|
|
|||
|
|
@ -215,6 +215,9 @@ var A = recordBuilder('A');
|
|||
// AAAA(name,ip, recordModifiers...)
|
||||
var AAAA = recordBuilder('AAAA');
|
||||
|
||||
// AKAMAICDN(name, target, recordModifiers...)
|
||||
var AKAMAICDN = recordBuilder('AKAMAICDN');
|
||||
|
||||
// ALIAS(name,target, recordModifiers...)
|
||||
var ALIAS = recordBuilder('ALIAS');
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
$TTL 300
|
||||
_443._tcp IN TLSA 3 1 1 MDFiYTQ3MTljODBiNmZlOTExYjA5MWE3YzA1MTI0YjY0ZWVlY2U5NjRlMDljMDU4ZWY4Zjk4MDVkYWNhNTQ2YiAgLQo=
|
||||
_443._tcp IN TLSA 3 1 1 mdfiytq3mtljodbinmzlotexyja5mwe3yza1mti0yjy0zwvly2u5njrlmdljmdu4zwy4zjk4mdvkywnhntq2yiaglqo=
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []tra
|
|||
r := newRec()
|
||||
r.SetTarget(transformCNAME(r.GetTargetField(), srcDomain.Name, dstDomain.Name))
|
||||
dstDomain.Records = append(dstDomain.Records, r)
|
||||
case "MX", "NAPTR", "NS", "SOA", "SRV", "TXT", "CAA", "TLSA":
|
||||
case "AKAMAICDN", "MX", "NAPTR", "NS", "SOA", "SRV", "TXT", "CAA", "TLSA":
|
||||
// Not imported.
|
||||
continue
|
||||
default:
|
||||
|
|
@ -555,6 +555,7 @@ var providerCapabilityChecks = []pairTypeCapability{
|
|||
capabilityCheck("SRV", providers.CanUseSRV),
|
||||
capabilityCheck("TLSA", providers.CanUseTLSA),
|
||||
capabilityCheck("AZURE_ALIAS", providers.CanUseAzureAlias),
|
||||
capabilityCheck("AKAMAICDN", providers.CanUseAKAMAICDN),
|
||||
|
||||
// DS needs special record-level checks
|
||||
{
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ func (c ConsolePrinter) StartDNSProvider(provider string, skip bool) {
|
|||
if skip {
|
||||
lbl = " (skipping)\n"
|
||||
}
|
||||
fmt.Fprintf(c.Writer, "----- DNS Provider: %s...%s", provider, lbl)
|
||||
fmt.Fprintf(c.Writer, "----- DNS Provider: %s...%s\n", provider, lbl)
|
||||
}
|
||||
|
||||
// StartRegistrar is called at the start of each new registrar.
|
||||
|
|
@ -114,7 +114,7 @@ func (c ConsolePrinter) StartRegistrar(provider string, skip bool) {
|
|||
if skip {
|
||||
lbl = " (skipping)\n"
|
||||
}
|
||||
fmt.Fprintf(c.Writer, "----- Registrar: %s...%s", provider, lbl)
|
||||
fmt.Fprintf(c.Writer, "----- Registrar: %s...%s\n", provider, lbl)
|
||||
}
|
||||
|
||||
// EndProvider is called at the end of each provider.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package all
|
|||
import (
|
||||
// Define all known providers here. They should each register themselves with the providers package via init function.
|
||||
_ "github.com/StackExchange/dnscontrol/v3/providers/activedir"
|
||||
_ "github.com/StackExchange/dnscontrol/v3/providers/akamaiedgedns"
|
||||
_ "github.com/StackExchange/dnscontrol/v3/providers/axfrddns"
|
||||
_ "github.com/StackExchange/dnscontrol/v3/providers/azuredns"
|
||||
_ "github.com/StackExchange/dnscontrol/v3/providers/bind"
|
||||
|
|
|
|||
247
providers/akamaiedgedns/akamaiEdgeDnsProvider.go
Normal file
247
providers/akamaiedgedns/akamaiEdgeDnsProvider.go
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
package akamaiedgedns
|
||||
|
||||
/*
|
||||
Akamai Edge DNS provider
|
||||
|
||||
For information about Akamai Edge DNS, see:
|
||||
https://www.akamai.com/us/en/products/security/edge-dns.jsp
|
||||
https://learn.akamai.com/en-us/products/cloud_security/edge_dns.html
|
||||
https://www.akamai.com/us/en/multimedia/documents/product-brief/edge-dns-product-brief.pdf
|
||||
*/
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/StackExchange/dnscontrol/v3/models"
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/diff"
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/txtutil"
|
||||
"github.com/StackExchange/dnscontrol/v3/providers"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var features = providers.DocumentationNotes{
|
||||
// The default for unlisted capabilities is 'Cannot'.
|
||||
// See providers/capabilities.go for the entire list of capabilties.
|
||||
providers.CanUseAlias: providers.Cannot(),
|
||||
providers.CanUseCAA: providers.Can(),
|
||||
providers.CanUseDS: providers.Cannot(),
|
||||
providers.CanUseDSForChildren: providers.Can(),
|
||||
providers.CanUsePTR: providers.Can(),
|
||||
providers.CanUseNAPTR: providers.Can(),
|
||||
providers.CanUseSRV: providers.Can(),
|
||||
providers.CanUseSSHFP: providers.Can(),
|
||||
providers.CanUseTLSA: providers.Can(),
|
||||
providers.CanAutoDNSSEC: providers.Can(),
|
||||
providers.CantUseNOPURGE: providers.Cannot(),
|
||||
providers.DocOfficiallySupported: providers.Cannot(),
|
||||
providers.DocDualHost: providers.Can(),
|
||||
providers.CanUseSOA: providers.Cannot(),
|
||||
providers.DocCreateDomains: providers.Can(),
|
||||
providers.CanGetZones: providers.Can(),
|
||||
providers.CanUseAKAMAICDN: providers.Can(),
|
||||
}
|
||||
|
||||
type edgeDNSProvider struct {
|
||||
contractID string
|
||||
groupID string
|
||||
}
|
||||
|
||||
func init() {
|
||||
fns := providers.DspFuncs{
|
||||
Initializer: newEdgeDNSDSP,
|
||||
RecordAuditor: AuditRecords,
|
||||
}
|
||||
providers.RegisterDomainServiceProviderType("AKAMAIEDGEDNS", fns, features)
|
||||
providers.RegisterCustomRecordType("AKAMAICDN", "AKAMAIEDGEDNS", "")
|
||||
}
|
||||
|
||||
// DnsServiceProvider
|
||||
func newEdgeDNSDSP(config map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||
clientSecret := config["client_secret"]
|
||||
host := config["host"]
|
||||
accessToken := config["access_token"]
|
||||
clientToken := config["client_token"]
|
||||
contractID := config["contract_id"]
|
||||
groupID := config["group_id"]
|
||||
|
||||
if clientSecret == "" {
|
||||
return nil, fmt.Errorf("creds.json: client_secret must not be empty")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, fmt.Errorf("creds.json: host must not be empty")
|
||||
}
|
||||
if accessToken == "" {
|
||||
return nil, fmt.Errorf("creds.json: accessToken must not be empty")
|
||||
}
|
||||
if clientToken == "" {
|
||||
return nil, fmt.Errorf("creds.json: clientToken must not be empty")
|
||||
}
|
||||
if contractID == "" {
|
||||
return nil, fmt.Errorf("creds.json: contractID must not be empty")
|
||||
}
|
||||
if groupID == "" {
|
||||
return nil, fmt.Errorf("creds.json: groupID must not be empty")
|
||||
}
|
||||
|
||||
initialize(clientSecret, host, accessToken, clientToken)
|
||||
|
||||
api := &edgeDNSProvider{
|
||||
contractID: contractID,
|
||||
groupID: groupID,
|
||||
}
|
||||
return api, nil
|
||||
}
|
||||
|
||||
// EnsureDomainExists configures a new zone if the zone does not already exist.
|
||||
func (a *edgeDNSProvider) EnsureDomainExists(domain string) error {
|
||||
if zoneDoesExist(domain) {
|
||||
printer.Debugf("Zone %s already exists\n", domain)
|
||||
return nil
|
||||
}
|
||||
return createZone(domain, a.contractID, a.groupID)
|
||||
}
|
||||
|
||||
// GetDomainCorrections return a list of corrections. Each correction is a text string describing the change
|
||||
// and a function that, if called, will make the change.
|
||||
// “dnscontrol preview” simply prints the text strings.
|
||||
// "dnscontrol push" prints the strings and calls the functions.
|
||||
func (a *edgeDNSProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
|
||||
err := dc.Punycode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingRecords, err := getRecords(dc.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
models.PostProcessRecords(existingRecords)
|
||||
txtutil.SplitSingleLongTxt(dc.Records)
|
||||
|
||||
keysToUpdate, err := (diff.New(dc)).ChangedGroups(existingRecords)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingRecordsMap := make(map[models.RecordKey][]*models.RecordConfig)
|
||||
for _, r := range existingRecords {
|
||||
key := models.RecordKey{NameFQDN: r.NameFQDN, Type: r.Type}
|
||||
existingRecordsMap[key] = append(existingRecordsMap[key], r)
|
||||
}
|
||||
|
||||
desiredRecordsMap := dc.Records.GroupedByKey()
|
||||
|
||||
// Deletes must occur first. For example, if replacing a existing CNAME with an A of the same name:
|
||||
// DELETE CNAME foo.example.net
|
||||
// must occur before
|
||||
// CREATE A foo.example.net
|
||||
// because both an A and a CNAME for the same name is not allowed.
|
||||
|
||||
corrections := []*models.Correction{} // deletes first
|
||||
lastCorrections := []*models.Correction{} // creates and replaces last
|
||||
|
||||
for key, msg := range keysToUpdate {
|
||||
existing, okExisting := existingRecordsMap[key]
|
||||
desired, okDesired := desiredRecordsMap[key]
|
||||
|
||||
if okExisting && !okDesired {
|
||||
// In the existing map but not in the desired map: Delete
|
||||
corrections = append(corrections, &models.Correction{
|
||||
Msg: strings.Join(msg, "\n "),
|
||||
F: func() error {
|
||||
return deleteRecordset(existing, dc.Name)
|
||||
},
|
||||
})
|
||||
printer.Debugf("deleteRecordset: %s %s\n", key.NameFQDN, key.Type)
|
||||
for _, rdata := range existing {
|
||||
printer.Debugf(" Rdata: %s\n", rdata.GetTargetCombined())
|
||||
}
|
||||
} else if !okExisting && okDesired {
|
||||
// Not in the existing map but in the desired map: Create
|
||||
lastCorrections = append(lastCorrections, &models.Correction{
|
||||
Msg: strings.Join(msg, "\n "),
|
||||
F: func() error {
|
||||
return createRecordset(desired, dc.Name)
|
||||
},
|
||||
})
|
||||
printer.Debugf("createRecordset: %s %s\n", key.NameFQDN, key.Type)
|
||||
for _, rdata := range desired {
|
||||
printer.Debugf(" Rdata: %s\n", rdata.GetTargetCombined())
|
||||
}
|
||||
} else if okExisting && okDesired {
|
||||
// In the existing map and in the desired map: Replace
|
||||
lastCorrections = append(lastCorrections, &models.Correction{
|
||||
Msg: strings.Join(msg, "\n "),
|
||||
F: func() error {
|
||||
return replaceRecordset(desired, dc.Name)
|
||||
},
|
||||
})
|
||||
printer.Debugf("replaceRecordset: %s %s\n", key.NameFQDN, key.Type)
|
||||
for _, rdata := range desired {
|
||||
printer.Debugf(" Rdata: %s\n", rdata.GetTargetCombined())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deletes first, then creates and replaces
|
||||
corrections = append(corrections, lastCorrections...)
|
||||
|
||||
// AutoDnsSec correction
|
||||
existingAutoDNSSecEnabled, err := isAutoDNSSecEnabled(dc.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
desiredAutoDNSSecEnabled := dc.AutoDNSSEC == "on"
|
||||
|
||||
if !existingAutoDNSSecEnabled && desiredAutoDNSSecEnabled {
|
||||
// Existing false (disabled), Desired true (enabled)
|
||||
corrections = append(corrections, &models.Correction{
|
||||
Msg: "Enable AutoDnsSec\n",
|
||||
F: func() error {
|
||||
return autoDNSSecEnable(true, dc.Name)
|
||||
},
|
||||
})
|
||||
printer.Debugf("autoDNSSecEnable: Enable AutoDnsSec for zone %s\n", dc.Name)
|
||||
} else if existingAutoDNSSecEnabled && !desiredAutoDNSSecEnabled {
|
||||
// Existing true (enabled), Desired false (disabled)
|
||||
corrections = append(corrections, &models.Correction{
|
||||
Msg: "Disable AutoDnsSec\n",
|
||||
F: func() error {
|
||||
return autoDNSSecEnable(false, dc.Name)
|
||||
},
|
||||
})
|
||||
printer.Debugf("autoDNSSecEnable: Disable AutoDnsSec for zone %s\n", dc.Name)
|
||||
}
|
||||
|
||||
return corrections, nil
|
||||
}
|
||||
|
||||
// GetNameservers returns the nameservers for a domain.
|
||||
func (a *edgeDNSProvider) GetNameservers(domain string) ([]*models.Nameserver, error) {
|
||||
authorities, err := getAuthorities(a.contractID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return models.ToNameserversStripTD(authorities)
|
||||
}
|
||||
|
||||
// GetZoneRecords returns an array of RecordConfig structs for a zone.
|
||||
func (a *edgeDNSProvider) GetZoneRecords(domain string) (models.Records, error) {
|
||||
records, err := getRecords(domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return records, nil
|
||||
}
|
||||
|
||||
// ListZones returns all DNS zones managed by this provider.
|
||||
func (a *edgeDNSProvider) ListZones() ([]string, error) {
|
||||
zones, err := listZones(a.contractID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return zones, nil
|
||||
}
|
||||
305
providers/akamaiedgedns/akamaiEdgeDnsService.go
Normal file
305
providers/akamaiedgedns/akamaiEdgeDnsService.go
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
package akamaiedgedns
|
||||
|
||||
/*
|
||||
For information about Akamai's "Edge DNS Zone Management API", see:
|
||||
https://developer.akamai.com/api/cloud_security/edge_dns_zone_management/v2.html
|
||||
|
||||
For information about "AkamaiOPEN-edgegrid-golang" library, see:
|
||||
https://github.com/akamai/AkamaiOPEN-edgegrid-golang
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/StackExchange/dnscontrol/v3/models"
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
|
||||
dnsv2 "github.com/akamai/AkamaiOPEN-edgegrid-golang/configdns-v2"
|
||||
"github.com/akamai/AkamaiOPEN-edgegrid-golang/edgegrid"
|
||||
)
|
||||
|
||||
// initialize initializes the "Akamai OPEN EdgeGrid" library
|
||||
func initialize(clientSecret string, host string, accessToken string, clientToken string) {
|
||||
|
||||
eg := edgegrid.Config{
|
||||
ClientSecret: clientSecret,
|
||||
Host: host,
|
||||
AccessToken: accessToken,
|
||||
ClientToken: clientToken,
|
||||
MaxBody: 131072,
|
||||
Debug: false,
|
||||
}
|
||||
dnsv2.Init(eg)
|
||||
}
|
||||
|
||||
// zoneDoesExist returns true if the zone exists, false otherwise.
|
||||
func zoneDoesExist(zonename string) bool {
|
||||
_, err := dnsv2.GetZone(zonename)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// createZone create a new zone and creates SOA and NS records for the zone.
|
||||
// Akamai assigns a unique set of authoritative nameservers for each contract. These authorities should be
|
||||
// used as the NS records on all zones belonging to this contract.
|
||||
func createZone(zonename string, contractID string, groupID string) error {
|
||||
zone := &dnsv2.ZoneCreate{
|
||||
Zone: zonename,
|
||||
Type: "PRIMARY",
|
||||
Comment: "This zone created by DNSControl (http://dnscontrol.org)",
|
||||
SignAndServe: false,
|
||||
SignAndServeAlgorithm: "RSA_SHA512",
|
||||
ContractId: contractID,
|
||||
}
|
||||
|
||||
queryArgs := &dnsv2.ZoneQueryString{
|
||||
Contract: contractID,
|
||||
Group: groupID,
|
||||
}
|
||||
|
||||
err := dnsv2.ValidateZone(zone)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Invalid value provided for zone. Error: %s", err.Error())
|
||||
}
|
||||
|
||||
err = zone.Save(*queryArgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Zone create failed. Error: %s", err.Error())
|
||||
}
|
||||
|
||||
// Indirectly create NS and SOA records
|
||||
err = zone.SaveChangelist()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Zone initialization failed. SOA and NS records need to be created")
|
||||
}
|
||||
err = zone.SubmitChangelist()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Zone create failed. Error: %s", err.Error())
|
||||
}
|
||||
|
||||
printer.Printf("Created zone: %s\n", zone.Zone)
|
||||
printer.Printf(" Type: %s\n", zone.Type)
|
||||
printer.Printf(" Comment: %s\n", zone.Comment)
|
||||
printer.Printf(" SignAndServe: %v\n", zone.SignAndServe)
|
||||
printer.Printf(" SignAndServeAlgorithm: %s\n", zone.SignAndServeAlgorithm)
|
||||
printer.Printf(" ContractId: %s\n", zone.ContractId)
|
||||
printer.Printf(" GroupId: %s\n", queryArgs.Group)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// listZones lists all zones associated with this contract.
|
||||
func listZones(contractID string) ([]string, error) {
|
||||
queryArgs := dnsv2.ZoneListQueryArgs{
|
||||
ContractIds: contractID,
|
||||
ShowAll: true,
|
||||
}
|
||||
|
||||
zoneListResp, err := dnsv2.ListZones(queryArgs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Zone List retrieval failed. Error: %s", err.Error())
|
||||
}
|
||||
|
||||
edgeDNSZones := zoneListResp.Zones // what we have
|
||||
var zones []string // what we return
|
||||
|
||||
for _, edgeDNSZone := range edgeDNSZones {
|
||||
zones = append(zones, edgeDNSZone.Zone)
|
||||
}
|
||||
|
||||
return zones, nil
|
||||
}
|
||||
|
||||
// isAutoDNSSecEnabled returns true if AutoDNSSEC (SignAndServe) is enabled, false otherwise.
|
||||
func isAutoDNSSecEnabled(zonename string) (bool, error) {
|
||||
zone, err := dnsv2.GetZone(zonename)
|
||||
if err != nil {
|
||||
if dnsv2.IsConfigDNSError(err) && err.(dnsv2.ConfigDNSError).NotFound() {
|
||||
return false, fmt.Errorf("Zone %s does not exist. Error: %s",
|
||||
zonename, err.Error())
|
||||
}
|
||||
return false, fmt.Errorf("Error retrieving information for zone %s. Error: %s",
|
||||
zonename, err.Error())
|
||||
}
|
||||
return zone.SignAndServe, nil
|
||||
}
|
||||
|
||||
// autoDNSSecEnable enables or disables AutoDNSSEC (SignAndServe) for the zone.
|
||||
func autoDNSSecEnable(enable bool, zonename string) error {
|
||||
zone, err := dnsv2.GetZone(zonename)
|
||||
if err != nil {
|
||||
if dnsv2.IsConfigDNSError(err) && err.(dnsv2.ConfigDNSError).NotFound() {
|
||||
return fmt.Errorf("Zone %s does not exist. Error: %s",
|
||||
zonename, err.Error())
|
||||
}
|
||||
return fmt.Errorf("Error retrieving information for zone %s. Error: %s",
|
||||
zonename, err.Error())
|
||||
}
|
||||
|
||||
algorithm := "RSA_SHA512"
|
||||
if zone.SignAndServeAlgorithm != "" {
|
||||
algorithm = zone.SignAndServeAlgorithm
|
||||
}
|
||||
|
||||
modifiedzone := &dnsv2.ZoneCreate{
|
||||
Zone: zone.Zone,
|
||||
Type: zone.Type,
|
||||
Masters: zone.Masters,
|
||||
Comment: zone.Comment,
|
||||
SignAndServe: enable, // AutoDNSSEC
|
||||
SignAndServeAlgorithm: algorithm,
|
||||
TsigKey: zone.TsigKey,
|
||||
EndCustomerId: zone.EndCustomerId,
|
||||
ContractId: zone.ContractId,
|
||||
}
|
||||
|
||||
queryArgs := dnsv2.ZoneQueryString{}
|
||||
|
||||
err = modifiedzone.Update(queryArgs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error updating zone %s. Error: %s",
|
||||
zonename, err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getAuthorities returns the list of authoritative nameservers for the contract.
|
||||
// Akamai assigns a unique set of authoritative nameservers for each contract. These authorities should be
|
||||
// used as the NS records on all zones belonging to this contract.
|
||||
func getAuthorities(contractID string) ([]string, error) {
|
||||
authorityResponse, err := dnsv2.GetAuthorities(contractID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getAuthorities - ContractID %s: Authorities retrieval failed. Error: %s",
|
||||
contractID, err.Error())
|
||||
}
|
||||
contracts := authorityResponse.Contracts
|
||||
if len(contracts) != 1 {
|
||||
return nil, fmt.Errorf("getAuthorities - ContractID %s: Expected 1 element in array but got %d",
|
||||
contractID, len(contracts))
|
||||
}
|
||||
cid := contracts[0].ContractID
|
||||
if cid != contractID {
|
||||
return nil, fmt.Errorf("getAuthorities - ContractID %s: Got authorities for wrong contractID (%s)",
|
||||
contractID, cid)
|
||||
}
|
||||
authorities := contracts[0].Authorities
|
||||
return authorities, nil
|
||||
}
|
||||
|
||||
// rcToRs converts DNSControl RecordConfig records to an AkamaiEdgeDNS recordset.
|
||||
func rcToRs(records []*models.RecordConfig, zonename string) (*dnsv2.RecordBody, error) {
|
||||
if len(records) == 0 {
|
||||
return nil, fmt.Errorf("No records to replace")
|
||||
}
|
||||
|
||||
akaRecord := &dnsv2.RecordBody{
|
||||
Name: records[0].NameFQDN,
|
||||
RecordType: records[0].Type,
|
||||
TTL: int(records[0].TTL),
|
||||
}
|
||||
|
||||
for _, r := range records {
|
||||
akaRecord.Target = append(akaRecord.Target, r.GetTargetCombined())
|
||||
}
|
||||
|
||||
return akaRecord, nil
|
||||
}
|
||||
|
||||
// createRecordset creates a new AkamaiEdgeDNS recordset in the zone.
|
||||
func createRecordset(records []*models.RecordConfig, zonename string) error {
|
||||
akaRecord, err := rcToRs(records, zonename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = akaRecord.Save(zonename, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Recordset creation failed. Error: %s", err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// replaceRecordset replaces an existing AkamaiEdgeDNS recordset in the zone.
|
||||
func replaceRecordset(records []*models.RecordConfig, zonename string) error {
|
||||
akaRecord, err := rcToRs(records, zonename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = akaRecord.Update(zonename, true)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Recordset update failed. Error: %s", err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteRecordset deletes an existing AkamaiEdgeDNS recordset in the zone.
|
||||
func deleteRecordset(records []*models.RecordConfig, zonename string) error {
|
||||
akaRecord, err := rcToRs(records, zonename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = akaRecord.Delete(zonename, true)
|
||||
if err != nil {
|
||||
if dnsv2.IsConfigDNSError(err) && err.(dnsv2.ConfigDNSError).NotFound() {
|
||||
return fmt.Errorf("Recordset not found")
|
||||
}
|
||||
return fmt.Errorf("Failed to delete recordset. Error: %s", err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
Example AkamaiEdgeDNS Recordset (as JSON):
|
||||
{
|
||||
"name": "test.com",
|
||||
"rdata": [
|
||||
"a7.akafp.net.",
|
||||
"a4.akafp.net.",
|
||||
"a0.akafp.net."
|
||||
],
|
||||
"ttl": 10000,
|
||||
"type": "NS"
|
||||
}
|
||||
*/
|
||||
|
||||
// getRecords returns all RecordConfig records in the zone.
|
||||
func getRecords(zonename string) ([]*models.RecordConfig, error) {
|
||||
queryArgs := dnsv2.RecordsetQueryArgs{ShowAll: true}
|
||||
|
||||
rsetResp, err := dnsv2.GetRecordsets(zonename, queryArgs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Recordset list retrieval failed. Error: %s", err.Error())
|
||||
}
|
||||
|
||||
akaRecordsets := rsetResp.Recordsets // what we have
|
||||
var recordConfigs []*models.RecordConfig // what we return
|
||||
|
||||
// For each AkamaiEdgeDNS recordset...
|
||||
for _, akarecset := range akaRecordsets {
|
||||
akaname := akarecset.Name
|
||||
akatype := akarecset.Type
|
||||
akattl := akarecset.TTL
|
||||
|
||||
// Don't report the existence of an SOA record (because DnsControl will try to delete the SOA record).
|
||||
if akatype == "SOA" {
|
||||
continue
|
||||
}
|
||||
|
||||
// ... convert the recordset into 1 or more RecordConfig structs
|
||||
for _, r := range akarecset.Rdata {
|
||||
rc := &models.RecordConfig{
|
||||
Type: akatype,
|
||||
TTL: uint32(akattl),
|
||||
}
|
||||
rc.SetLabelFromFQDN(akaname, zonename)
|
||||
err = rc.PopulateFromString(akatype, r, zonename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
recordConfigs = append(recordConfigs, rc)
|
||||
}
|
||||
}
|
||||
|
||||
return recordConfigs, nil
|
||||
}
|
||||
8
providers/akamaiedgedns/auditrecords.go
Normal file
8
providers/akamaiedgedns/auditrecords.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package akamaiedgedns
|
||||
|
||||
import "github.com/StackExchange/dnscontrol/v3/models"
|
||||
|
||||
// AuditRecords returns an error if any records are not supportable by this provider.
|
||||
func AuditRecords(records []*models.RecordConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -69,6 +69,9 @@ const (
|
|||
|
||||
// CanUseSOA indicates the provider supports full management of a zone's SOA record
|
||||
CanUseSOA
|
||||
|
||||
// CanUseAKAMAICDN indicates the provider support the specific AKAMAICDN records that only the Akamai EdgeDns provider supports
|
||||
CanUseAKAMAICDN
|
||||
)
|
||||
|
||||
var providerCapabilities = map[string]map[Capability]bool{}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue