mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
Ns1 provider (#63)
* add ns1 libs to vendor * Create shim and wire into tests * ns1 provider more working. * vendor correct files * comment diff functions * ns1 docs * making mx work with ns1 * ? * refactor tests to make capability blocks easier. fix up ns1
This commit is contained in:
37
docs/_providers/ns1.md
Normal file
37
docs/_providers/ns1.md
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
name: NS1
|
||||
layout: default
|
||||
jsId: NS1
|
||||
---
|
||||
# NS1 Provider
|
||||
|
||||
NS1 provides a dns provider implementation for ns1 dns.
|
||||
|
||||
## Configuration
|
||||
|
||||
In your providers config json file you must provide your ns1 api key:
|
||||
|
||||
{% highlight json %}
|
||||
{
|
||||
"ns1":{
|
||||
"api_token": "your-ns1-token"
|
||||
}
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
## Metadata
|
||||
|
||||
This provider does not recognize any special metadata fields unique to ns1.
|
||||
|
||||
## Usage
|
||||
|
||||
Example javascript:
|
||||
|
||||
{% highlight js %}
|
||||
var NS1 = NewDnsProvider("ns1", "NS1");
|
||||
|
||||
D("example.tld", MY_REGISTRAR, DnsProvider(NS1),
|
||||
A("test","1.2.3.4")
|
||||
);
|
||||
{% endhighlight %}
|
||||
|
@ -88,6 +88,7 @@ func runTests(t *testing.T, prv providers.DNSServiceProvider, domainName string,
|
||||
dc := getDomainConfigWithNameservers(t, prv, domainName)
|
||||
// run tests one at a time
|
||||
end := *endIdx
|
||||
tests := makeTests(t)
|
||||
if end == 0 || end >= len(tests) {
|
||||
end = len(tests) - 1
|
||||
}
|
||||
@ -97,10 +98,6 @@ func runTests(t *testing.T, prv providers.DNSServiceProvider, domainName string,
|
||||
break
|
||||
}
|
||||
t.Run(fmt.Sprintf("%d: %s", i, tst.Desc), func(t *testing.T) {
|
||||
if tst.SkipUnless != 0 && !providers.ProviderHasCabability(*providerToRun, tst.SkipUnless) {
|
||||
t.Log("Skipping because provider does not support test features")
|
||||
return
|
||||
}
|
||||
skipVal := false
|
||||
if knownFailures[i] {
|
||||
t.Log("SKIPPING VALIDATION FOR KNOWN FAILURE CASE")
|
||||
@ -198,9 +195,8 @@ func TestDualProviders(t *testing.T) {
|
||||
}
|
||||
|
||||
type TestCase struct {
|
||||
Desc string
|
||||
Records []*rec
|
||||
SkipUnless providers.Capability
|
||||
Desc string
|
||||
Records []*rec
|
||||
}
|
||||
|
||||
type rec models.RecordConfig
|
||||
@ -275,95 +271,119 @@ func manyA(namePattern, target string, n int) []*rec {
|
||||
return recs
|
||||
}
|
||||
|
||||
func (tc *TestCase) IfHasCapability(c providers.Capability) *TestCase {
|
||||
tc.SkipUnless = c
|
||||
return tc
|
||||
}
|
||||
func makeTests(t *testing.T) []*TestCase {
|
||||
//ALWAYS ADD TO BOTTOM OF LIST. Order and indexes matter.
|
||||
tests := []*TestCase{
|
||||
// A
|
||||
tc("Empty"),
|
||||
tc("Create an A record", a("@", "1.1.1.1")),
|
||||
tc("Change it", a("@", "1.2.3.4")),
|
||||
tc("Add another", a("@", "1.2.3.4"), a("www", "1.2.3.4")),
|
||||
tc("Add another(same name)", a("@", "1.2.3.4"), a("www", "1.2.3.4"), a("www", "5.6.7.8")),
|
||||
tc("Change a ttl", a("@", "1.2.3.4").ttl(1000), a("www", "1.2.3.4"), a("www", "5.6.7.8")),
|
||||
tc("Change single target from set", a("@", "1.2.3.4").ttl(1000), a("www", "2.2.2.2"), a("www", "5.6.7.8")),
|
||||
tc("Change all ttls", a("@", "1.2.3.4").ttl(500), a("www", "2.2.2.2").ttl(400), a("www", "5.6.7.8").ttl(400)),
|
||||
tc("Delete one", a("@", "1.2.3.4").ttl(500), a("www", "5.6.7.8").ttl(400)),
|
||||
tc("Add back and change ttl", a("www", "5.6.7.8").ttl(700), a("www", "1.2.3.4").ttl(700)),
|
||||
tc("Change targets and ttls", a("www", "1.1.1.1"), a("www", "2.2.2.2")),
|
||||
|
||||
//ALWAYS ADD TO BOTTOM OF LIST. Order and indexes matter.
|
||||
var tests = []*TestCase{
|
||||
// A
|
||||
tc("Empty"),
|
||||
tc("Create an A record", a("@", "1.1.1.1")),
|
||||
tc("Change it", a("@", "1.2.3.4")),
|
||||
tc("Add another", a("@", "1.2.3.4"), a("www", "1.2.3.4")),
|
||||
tc("Add another(same name)", a("@", "1.2.3.4"), a("www", "1.2.3.4"), a("www", "5.6.7.8")),
|
||||
tc("Change a ttl", a("@", "1.2.3.4").ttl(1000), a("www", "1.2.3.4"), a("www", "5.6.7.8")),
|
||||
tc("Change single target from set", a("@", "1.2.3.4").ttl(1000), a("www", "2.2.2.2"), a("www", "5.6.7.8")),
|
||||
tc("Change all ttls", a("@", "1.2.3.4").ttl(500), a("www", "2.2.2.2").ttl(400), a("www", "5.6.7.8").ttl(400)),
|
||||
tc("Delete one", a("@", "1.2.3.4").ttl(500), a("www", "5.6.7.8").ttl(400)),
|
||||
tc("Add back and change ttl", a("www", "5.6.7.8").ttl(700), a("www", "1.2.3.4").ttl(700)),
|
||||
tc("Change targets and ttls", a("www", "1.1.1.1"), a("www", "2.2.2.2")),
|
||||
// CNAMES
|
||||
tc("Empty"),
|
||||
tc("Create a CNAME", cname("foo", "google.com.")),
|
||||
tc("Change it", cname("foo", "google2.com.")),
|
||||
tc("Change to A record", a("foo", "1.2.3.4")),
|
||||
tc("Change back to CNAME", cname("foo", "google.com.")),
|
||||
tc("Record pointing to @", cname("foo", "**current-domain**")),
|
||||
|
||||
// CNAMES
|
||||
tc("Empty"),
|
||||
tc("Create a CNAME", cname("foo", "google.com.")),
|
||||
tc("Change it", cname("foo", "google2.com.")),
|
||||
tc("Change to A record", a("foo", "1.2.3.4")),
|
||||
tc("Change back to CNAME", cname("foo", "google.com.")),
|
||||
tc("Record pointing to @", cname("foo", "**current-domain**")),
|
||||
//NS
|
||||
tc("Empty"),
|
||||
tc("NS for subdomain", ns("xyz", "ns2.foo.com.")),
|
||||
tc("Dual NS for subdomain", ns("xyz", "ns2.foo.com."), ns("xyz", "ns1.foo.com.")),
|
||||
tc("Record pointing to @", ns("foo", "**current-domain**")),
|
||||
|
||||
//NS
|
||||
tc("Empty"),
|
||||
tc("NS for subdomain", ns("xyz", "ns2.foo.com.")),
|
||||
tc("Dual NS for subdomain", ns("xyz", "ns2.foo.com."), ns("xyz", "ns1.foo.com.")),
|
||||
tc("Record pointing to @", ns("foo", "**current-domain**")),
|
||||
//IDNAs
|
||||
tc("Empty"),
|
||||
tc("Internationalized name", a("ööö", "1.2.3.4")),
|
||||
tc("Change IDN", a("ööö", "2.2.2.2")),
|
||||
tc("Internationalized CNAME Target", cname("a", "ööö.com.")),
|
||||
tc("IDN CNAME AND Target", cname("öoö", "ööö.企业.")),
|
||||
|
||||
//IDNAs
|
||||
tc("Empty"),
|
||||
tc("Internationalized name", a("ööö", "1.2.3.4")),
|
||||
tc("Change IDN", a("ööö", "2.2.2.2")),
|
||||
tc("Internationalized CNAME Target", cname("a", "ööö.com.")),
|
||||
tc("IDN CNAME AND Target", cname("öoö", "ööö.企业.")),
|
||||
//MX
|
||||
tc("Empty"),
|
||||
tc("MX record", mx("@", 5, "foo.com.")),
|
||||
tc("Second MX record, same prio", mx("@", 5, "foo.com."), mx("@", 5, "foo2.com.")),
|
||||
tc("3 MX", mx("@", 5, "foo.com."), mx("@", 5, "foo2.com."), mx("@", 15, "foo3.com.")),
|
||||
tc("Delete one", mx("@", 5, "foo2.com."), mx("@", 15, "foo3.com.")),
|
||||
tc("Change to other name", mx("@", 5, "foo2.com."), mx("mail", 15, "foo3.com.")),
|
||||
tc("Change Preference", mx("@", 7, "foo2.com."), mx("mail", 15, "foo3.com.")),
|
||||
tc("Record pointing to @", mx("foo", 8, "**current-domain**")),
|
||||
}
|
||||
|
||||
//MX
|
||||
tc("Empty"),
|
||||
tc("MX record", mx("@", 5, "foo.com.")),
|
||||
tc("Second MX record, same prio", mx("@", 5, "foo.com."), mx("@", 5, "foo2.com.")),
|
||||
tc("3 MX", mx("@", 5, "foo.com."), mx("@", 5, "foo2.com."), mx("@", 15, "foo3.com.")),
|
||||
tc("Delete one", mx("@", 5, "foo2.com."), mx("@", 15, "foo3.com.")),
|
||||
tc("Change to other name", mx("@", 5, "foo2.com."), mx("mail", 15, "foo3.com.")),
|
||||
tc("Change Preference", mx("@", 7, "foo2.com."), mx("mail", 15, "foo3.com.")),
|
||||
tc("Record pointing to @", mx("foo", 8, "**current-domain**")),
|
||||
// PTR
|
||||
if !providers.ProviderHasCabability(*providerToRun, providers.CanUsePTR) {
|
||||
t.Log("Skipping PTR Tests because provider does not support them")
|
||||
} else {
|
||||
tests = append(tests, tc("Empty"),
|
||||
tc("Create PTR record", ptr("4", "foo.com.")),
|
||||
tc("Modify PTR record", ptr("4", "bar.com.")),
|
||||
)
|
||||
}
|
||||
|
||||
//PTR
|
||||
tc("Empty").IfHasCapability(providers.CanUsePTR),
|
||||
tc("Create PTR record", ptr("4", "foo.com.")).IfHasCapability(providers.CanUsePTR),
|
||||
tc("Modify PTR record", ptr("4", "bar.com.")).IfHasCapability(providers.CanUsePTR),
|
||||
// ALIAS
|
||||
if !providers.ProviderHasCabability(*providerToRun, providers.CanUseAlias) {
|
||||
t.Log("Skipping ALIAS Tests because provider does not support them")
|
||||
} else {
|
||||
tests = append(tests, tc("Empty"),
|
||||
tc("ALIAS at root", alias("@", "foo.com.")),
|
||||
tc("change it", alias("@", "foo2.com.")),
|
||||
tc("ALIAS at subdomain", alias("test", "foo.com.")),
|
||||
)
|
||||
}
|
||||
|
||||
//ALIAS
|
||||
tc("Empty").IfHasCapability(providers.CanUseAlias),
|
||||
tc("ALIAS at root", alias("@", "foo.com.")).IfHasCapability(providers.CanUseAlias),
|
||||
tc("change it", alias("@", "foo2.com.")).IfHasCapability(providers.CanUseAlias),
|
||||
tc("ALIAS at subdomain", alias("test", "foo.com.")).IfHasCapability(providers.CanUseAlias),
|
||||
// SRV
|
||||
if !providers.ProviderHasCabability(*providerToRun, providers.CanUseSRV) {
|
||||
t.Log("Skipping SRV Tests because provider does not support them")
|
||||
} else {
|
||||
tests = append(tests, tc("Empty"),
|
||||
tc("SRV record", srv("_sip._tcp", 5, 6, 7, "foo.com.")),
|
||||
tc("Second SRV record, same prio", srv("_sip._tcp", 5, 6, 7, "foo.com."), srv("_sip._tcp", 5, 60, 70, "foo2.com.")),
|
||||
tc("3 SRV", srv("_sip._tcp", 5, 6, 7, "foo.com."), srv("_sip._tcp", 5, 60, 70, "foo2.com."), srv("_sip._tcp", 15, 65, 75, "foo3.com.")),
|
||||
tc("Delete one", srv("_sip._tcp", 5, 6, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo3.com.")),
|
||||
tc("Change Target", srv("_sip._tcp", 5, 6, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")),
|
||||
tc("Change Priority", srv("_sip._tcp", 52, 6, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")),
|
||||
tc("Change Weight", srv("_sip._tcp", 52, 62, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")),
|
||||
tc("Change Port", srv("_sip._tcp", 52, 62, 72, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")),
|
||||
)
|
||||
}
|
||||
|
||||
//SRV
|
||||
tc("Empty").IfHasCapability(providers.CanUseSRV),
|
||||
tc("SRV record", srv("_sip._tcp", 5, 6, 7, "foo.com.")).IfHasCapability(providers.CanUseSRV),
|
||||
tc("Second SRV record, same prio", srv("_sip._tcp", 5, 6, 7, "foo.com."), srv("_sip._tcp", 5, 60, 70, "foo2.com.")).IfHasCapability(providers.CanUseSRV),
|
||||
tc("3 SRV", srv("_sip._tcp", 5, 6, 7, "foo.com."), srv("_sip._tcp", 5, 60, 70, "foo2.com."), srv("_sip._tcp", 15, 65, 75, "foo3.com.")).IfHasCapability(providers.CanUseSRV),
|
||||
tc("Delete one", srv("_sip._tcp", 5, 6, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo3.com.")).IfHasCapability(providers.CanUseSRV),
|
||||
tc("Change Target", srv("_sip._tcp", 5, 6, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")).IfHasCapability(providers.CanUseSRV),
|
||||
tc("Change Priority", srv("_sip._tcp", 52, 6, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")).IfHasCapability(providers.CanUseSRV),
|
||||
tc("Change Weight", srv("_sip._tcp", 52, 62, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")).IfHasCapability(providers.CanUseSRV),
|
||||
tc("Change Port", srv("_sip._tcp", 52, 62, 72, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")).IfHasCapability(providers.CanUseSRV),
|
||||
|
||||
//CAA
|
||||
tc("Empty").IfHasCapability(providers.CanUseCAA),
|
||||
tc("CAA record", caa("@", "issue", 0, "letsencrypt.org")).IfHasCapability(providers.CanUseCAA),
|
||||
tc("CAA change tag", caa("@", "issuewild", 0, "letsencrypt.org")).IfHasCapability(providers.CanUseCAA),
|
||||
tc("CAA change target", caa("@", "issuewild", 0, "example.com")).IfHasCapability(providers.CanUseCAA),
|
||||
tc("CAA change flag", caa("@", "issuewild", 128, "example.com")).IfHasCapability(providers.CanUseCAA),
|
||||
tc("CAA many records", caa("@", "issue", 0, "letsencrypt.org"), caa("@", "issuewild", 0, ";"), caa("@", "iodef", 128, "mailto:test@example.com")).IfHasCapability(providers.CanUseCAA),
|
||||
tc("CAA delete", caa("@", "issue", 0, "letsencrypt.org")).IfHasCapability(providers.CanUseCAA),
|
||||
// CAA
|
||||
if !providers.ProviderHasCabability(*providerToRun, providers.CanUseCAA) {
|
||||
t.Log("Skipping CAA Tests because provider does not support them")
|
||||
} else {
|
||||
tests = append(tests, tc("Empty"),
|
||||
tc("CAA record", caa("@", "issue", 0, "letsencrypt.org")),
|
||||
tc("CAA change tag", caa("@", "issuewild", 0, "letsencrypt.org")),
|
||||
tc("CAA change target", caa("@", "issuewild", 0, "example.com")),
|
||||
tc("CAA change flag", caa("@", "issuewild", 128, "example.com")),
|
||||
tc("CAA many records", caa("@", "issue", 0, "letsencrypt.org"), caa("@", "issuewild", 0, ";"), caa("@", "iodef", 128, "mailto:test@example.com")),
|
||||
tc("CAA delete", caa("@", "issue", 0, "letsencrypt.org")),
|
||||
)
|
||||
}
|
||||
|
||||
// Test large zonefiles.
|
||||
// Gandi pages 100 items at a time.
|
||||
tc("Empty"),
|
||||
tc("99 records", manyA("rec%04d", "1.2.3.4", 99)...),
|
||||
tc("100 records", manyA("rec%04d", "1.2.3.4", 100)...),
|
||||
tc("101 records", manyA("rec%04d", "1.2.3.4", 101)...),
|
||||
// Mostly to test paging. Many providers page at 100
|
||||
skip := map[string]bool{
|
||||
"NS1": true, //ns1 free acct only allows 50 records
|
||||
}
|
||||
if skip[*providerToRun] {
|
||||
t.Log("Skipping Large record count Tests because provider does not support them")
|
||||
} else {
|
||||
tests = append(tests, tc("Empty"),
|
||||
tc("99 records", manyA("rec%04d", "1.2.3.4", 99)...),
|
||||
tc("100 records", manyA("rec%04d", "1.2.3.4", 100)...),
|
||||
tc("101 records", manyA("rec%04d", "1.2.3.4", 101)...),
|
||||
)
|
||||
}
|
||||
|
||||
//TODO: in validation, check that everything is given in unicode. This case hurts too much.
|
||||
//tc("IDN pre-punycoded", cname("xn--o-0gab", "xn--o-0gab.xn--o-0gab.")),
|
||||
return tests
|
||||
}
|
||||
|
@ -35,6 +35,10 @@
|
||||
"private_key": "$GCLOUD_PRIVATEKEY",
|
||||
"project_id": "$GCLOUD_PROJECT"
|
||||
},
|
||||
"NS1": {
|
||||
"domain": "$NS1_DOMAIN",
|
||||
"api_token": "$NS1_TOKEN"
|
||||
},
|
||||
"NAMEDOTCOM": {
|
||||
"apikey": "$NAMEDOTCOM_KEY",
|
||||
"apiurl": "$NAMEDOTCOM_URL",
|
||||
@ -46,4 +50,4 @@
|
||||
"SecretKey": "$R53_KEY",
|
||||
"domain": "$R53_DOMAIN"
|
||||
}
|
||||
}
|
||||
}
|
@ -225,6 +225,25 @@ func atou32(s string) uint32 {
|
||||
return uint32(i64)
|
||||
}
|
||||
|
||||
type Records []*RecordConfig
|
||||
|
||||
func (r Records) Grouped() map[RecordKey]Records {
|
||||
groups := map[RecordKey]Records{}
|
||||
for _, rec := range r {
|
||||
groups[rec.Key()] = append(groups[rec.Key()], rec)
|
||||
}
|
||||
return groups
|
||||
}
|
||||
|
||||
type RecordKey struct {
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
func (r *RecordConfig) Key() RecordKey {
|
||||
return RecordKey{r.Name, r.Type}
|
||||
}
|
||||
|
||||
type Nameserver struct {
|
||||
Name string `json:"name"` // Normalized to a FQDN with NO trailing "."
|
||||
Target string `json:"target"`
|
||||
@ -243,7 +262,7 @@ type DomainConfig struct {
|
||||
Registrar string `json:"registrar"`
|
||||
DNSProviders map[string]int `json:"dnsProviders"`
|
||||
Metadata map[string]string `json:"meta,omitempty"`
|
||||
Records []*RecordConfig `json:"records"`
|
||||
Records Records `json:"records"`
|
||||
Nameservers []*Nameserver `json:"nameservers,omitempty"`
|
||||
KeepUnknown bool `json:"keepunknown,omitempty"`
|
||||
}
|
||||
|
@ -12,5 +12,6 @@ import (
|
||||
_ "github.com/StackExchange/dnscontrol/providers/google"
|
||||
_ "github.com/StackExchange/dnscontrol/providers/namecheap"
|
||||
_ "github.com/StackExchange/dnscontrol/providers/namedotcom"
|
||||
_ "github.com/StackExchange/dnscontrol/providers/ns1"
|
||||
_ "github.com/StackExchange/dnscontrol/providers/route53"
|
||||
)
|
||||
|
@ -16,7 +16,11 @@ type Correlation struct {
|
||||
type Changeset []Correlation
|
||||
|
||||
type Differ interface {
|
||||
//IncrementalDiff performs a diff on a record-by-record basis, and returns a sets for which records need to be created, deleted, or modified.
|
||||
IncrementalDiff(existing []*models.RecordConfig) (unchanged, create, toDelete, modify Changeset)
|
||||
// ChangedGroups performs a diff more appropriate for providers with a "RecordSet" model, where all records with the same name and type are grouped.
|
||||
// Individual record changes are often not useful in such scenarios. Instead we return a map of record keys to a list of change descriptions within that group.
|
||||
ChangedGroups(existing []*models.RecordConfig) map[models.RecordKey][]string
|
||||
}
|
||||
|
||||
func New(dc *models.DomainConfig, extraValues ...func(*models.RecordConfig) map[string]string) Differ {
|
||||
@ -154,6 +158,21 @@ func (d *differ) IncrementalDiff(existing []*models.RecordConfig) (unchanged, cr
|
||||
return
|
||||
}
|
||||
|
||||
func (d *differ) ChangedGroups(existing []*models.RecordConfig) map[models.RecordKey][]string {
|
||||
changedKeys := map[models.RecordKey][]string{}
|
||||
_, create, delete, modify := d.IncrementalDiff(existing)
|
||||
for _, c := range create {
|
||||
changedKeys[c.Desired.Key()] = append(changedKeys[c.Desired.Key()], c.String())
|
||||
}
|
||||
for _, d := range delete {
|
||||
changedKeys[d.Existing.Key()] = append(changedKeys[d.Existing.Key()], d.String())
|
||||
}
|
||||
for _, m := range modify {
|
||||
changedKeys[m.Desired.Key()] = append(changedKeys[m.Desired.Key()], m.String())
|
||||
}
|
||||
return changedKeys
|
||||
}
|
||||
|
||||
func (c Correlation) String() string {
|
||||
if c.Existing == nil {
|
||||
return fmt.Sprintf("CREATE %s %s %s", c.Desired.Type, c.Desired.NameFQDN, c.d.content(c.Desired))
|
||||
|
145
providers/ns1/ns1provider.go
Normal file
145
providers/ns1/ns1provider.go
Normal file
@ -0,0 +1,145 @@
|
||||
package ns1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/models"
|
||||
"github.com/StackExchange/dnscontrol/providers"
|
||||
|
||||
"net/http"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/providers/diff"
|
||||
"github.com/miekg/dns/dnsutil"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/dns"
|
||||
)
|
||||
|
||||
func init() {
|
||||
providers.RegisterDomainServiceProviderType("NS1", newProvider)
|
||||
}
|
||||
|
||||
type nsone struct {
|
||||
*rest.Client
|
||||
}
|
||||
|
||||
func newProvider(creds map[string]string, meta json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||
if creds["api_token"] == "" {
|
||||
return nil, fmt.Errorf("api_token required for ns1")
|
||||
}
|
||||
return &nsone{rest.NewClient(http.DefaultClient, rest.SetAPIKey(creds["api_token"]))}, nil
|
||||
}
|
||||
|
||||
func (n *nsone) GetNameservers(domain string) ([]*models.Nameserver, error) {
|
||||
z, _, err := n.Zones.Get(domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return models.StringsToNameservers(z.DNSServers), nil
|
||||
}
|
||||
|
||||
func (n *nsone) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
|
||||
dc.Punycode()
|
||||
dc.CombineMXs()
|
||||
z, _, err := n.Zones.Get(dc.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
found := models.Records{}
|
||||
for _, r := range z.Records {
|
||||
zrs, err := convert(r, dc.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
found = append(found, zrs...)
|
||||
}
|
||||
foundGrouped := found.Grouped()
|
||||
desiredGrouped := dc.Records.Grouped()
|
||||
|
||||
differ := diff.New(dc)
|
||||
changedGroups := differ.ChangedGroups(found)
|
||||
corrections := []*models.Correction{}
|
||||
// each name/type is given to the api as a unit.
|
||||
for k, descs := range changedGroups {
|
||||
key := k
|
||||
desc := strings.Join(descs, "\n")
|
||||
_, current := foundGrouped[k]
|
||||
recs, wanted := desiredGrouped[k]
|
||||
if wanted && !current {
|
||||
// pure addition
|
||||
corrections = append(corrections, &models.Correction{
|
||||
Msg: desc,
|
||||
F: func() error { return n.add(recs, dc.Name) },
|
||||
})
|
||||
} else if current && !wanted {
|
||||
// pure deletion
|
||||
corrections = append(corrections, &models.Correction{
|
||||
Msg: desc,
|
||||
F: func() error { return n.remove(key, dc.Name) },
|
||||
})
|
||||
} else {
|
||||
// modification
|
||||
corrections = append(corrections, &models.Correction{
|
||||
Msg: desc,
|
||||
F: func() error { return n.modify(recs, dc.Name) },
|
||||
})
|
||||
}
|
||||
}
|
||||
return corrections, nil
|
||||
}
|
||||
|
||||
func (n *nsone) add(recs models.Records, domain string) error {
|
||||
_, err := n.Records.Create(buildRecord(recs, domain, ""))
|
||||
return err
|
||||
}
|
||||
|
||||
func (n *nsone) remove(key models.RecordKey, domain string) error {
|
||||
_, err := n.Records.Delete(domain, dnsutil.AddOrigin(key.Name, domain), key.Type)
|
||||
return err
|
||||
}
|
||||
|
||||
func (n *nsone) modify(recs models.Records, domain string) error {
|
||||
_, err := n.Records.Update(buildRecord(recs, domain, ""))
|
||||
return err
|
||||
}
|
||||
|
||||
func buildRecord(recs models.Records, domain string, id string) *dns.Record {
|
||||
r := recs[0]
|
||||
rec := &dns.Record{
|
||||
Domain: r.NameFQDN,
|
||||
Type: r.Type,
|
||||
ID: id,
|
||||
TTL: int(r.TTL),
|
||||
Zone: domain,
|
||||
}
|
||||
for _, r := range recs {
|
||||
ans := &dns.Answer{
|
||||
Rdata: strings.Split(r.Target, " "),
|
||||
}
|
||||
rec.AddAnswer(ans)
|
||||
}
|
||||
return rec
|
||||
}
|
||||
|
||||
func convert(zr *dns.ZoneRecord, domain string) ([]*models.RecordConfig, error) {
|
||||
found := []*models.RecordConfig{}
|
||||
for _, ans := range zr.ShortAns {
|
||||
rec := &models.RecordConfig{
|
||||
NameFQDN: zr.Domain,
|
||||
Name: dnsutil.TrimDomainName(zr.Domain, domain),
|
||||
TTL: uint32(zr.TTL),
|
||||
Target: ans,
|
||||
Original: zr,
|
||||
Type: zr.Type,
|
||||
}
|
||||
if zr.Type == "MX" {
|
||||
rec.CombinedTarget = true
|
||||
}
|
||||
found = append(found, rec)
|
||||
}
|
||||
return found, nil
|
||||
}
|
678
vendor/gopkg.in/ns1/ns1-go.v2/LICENSE.txt
generated
vendored
Normal file
678
vendor/gopkg.in/ns1/ns1-go.v2/LICENSE.txt
generated
vendored
Normal file
@ -0,0 +1,678 @@
|
||||
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.
|
||||
|
||||
|
||||
|
||||
APACHE HTTP SERVER SUBCOMPONENTS:
|
||||
|
||||
The Apache HTTP Server includes a number of subcomponents with
|
||||
separate copyright notices and license terms. Your use of the source
|
||||
code for the these subcomponents is subject to the terms and
|
||||
conditions of the following licenses.
|
||||
|
||||
For the mod_mime_magic component:
|
||||
|
||||
/*
|
||||
* mod_mime_magic: MIME type lookup via file magic numbers
|
||||
* Copyright (c) 1996-1997 Cisco Systems, Inc.
|
||||
*
|
||||
* This software was submitted by Cisco Systems to the Apache Group in July
|
||||
* 1997. Future revisions and derivatives of this source code must
|
||||
* acknowledge Cisco Systems as the original contributor of this module.
|
||||
* All other licensing and usage conditions are those of the Apache Group.
|
||||
*
|
||||
* Some of this code is derived from the free version of the file command
|
||||
* originally posted to comp.sources.unix. Copyright info for that program
|
||||
* is included below as required.
|
||||
* ---------------------------------------------------------------------------
|
||||
* - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone and
|
||||
* Telegraph Company or of the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on any
|
||||
* computer system, and to alter it and redistribute it freely, subject to
|
||||
* the following restrictions:
|
||||
*
|
||||
* 1. The author is not responsible for the consequences of use of this
|
||||
* software, no matter how awful, even if they arise from flaws in it.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Since few users ever read sources, credits
|
||||
* must appear in the documentation.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software. Since few users ever read
|
||||
* sources, credits must appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
For the modules\mappers\mod_imap.c component:
|
||||
|
||||
"macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
|
||||
|
||||
For the server\util_md5.c component:
|
||||
|
||||
/************************************************************************
|
||||
* NCSA HTTPd Server
|
||||
* Software Development Group
|
||||
* National Center for Supercomputing Applications
|
||||
* University of Illinois at Urbana-Champaign
|
||||
* 605 E. Springfield, Champaign, IL 61820
|
||||
* httpd@ncsa.uiuc.edu
|
||||
*
|
||||
* Copyright (C) 1995, Board of Trustees of the University of Illinois
|
||||
*
|
||||
************************************************************************
|
||||
*
|
||||
* md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
|
||||
*
|
||||
* Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
|
||||
* Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
|
||||
* University (see Copyright below).
|
||||
* Portions of Content-MD5 code Copyright (C) 1991 Bell Communications
|
||||
* Research, Inc. (Bellcore) (see Copyright below).
|
||||
* Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
|
||||
* Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
|
||||
/* (C) Copyright 1993,1994 by Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without
|
||||
* fee, provided that the above copyright notice appear in all copies
|
||||
* and that both that copyright notice and this permission notice
|
||||
* appear in supporting documentation, and that the name of Carnegie
|
||||
* Mellon University not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. Carnegie Mellon University makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this material
|
||||
* for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice and this permission notice
|
||||
* appear in all copies, and that the name of Bellcore not be
|
||||
* used in advertising or publicity pertaining to this
|
||||
* material without the specific, prior written permission
|
||||
* of an authorized representative of Bellcore. BELLCORE
|
||||
* MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
|
||||
* OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
|
||||
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
|
||||
*/
|
||||
|
||||
For the srclib\apr\include\apr_md5.h component:
|
||||
/*
|
||||
* This is work is derived from material Copyright RSA Data Security, Inc.
|
||||
*
|
||||
* The RSA copyright statement and Licence for that original material is
|
||||
* included below. This is followed by the Apache copyright statement and
|
||||
* licence for the modifications made to that material.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
|
||||
For the srclib\apr\passwd\apr_md5.c component:
|
||||
|
||||
/*
|
||||
* This is work is derived from material Copyright RSA Data Security, Inc.
|
||||
*
|
||||
* The RSA copyright statement and Licence for that original material is
|
||||
* included below. This is followed by the Apache copyright statement and
|
||||
* licence for the modifications made to that material.
|
||||
*/
|
||||
|
||||
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
/*
|
||||
* The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
|
||||
* MD5 crypt() function, which is licenced as follows:
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
For the srclib\apr-util\crypto\apr_md4.c component:
|
||||
|
||||
* This is derived from material copyright RSA Data Security, Inc.
|
||||
* Their notice is reproduced below in its entirety.
|
||||
*
|
||||
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
* rights reserved.
|
||||
*
|
||||
* License to copy and use this software is granted provided that it
|
||||
* is identified as the "RSA Data Security, Inc. MD4 Message-Digest
|
||||
* Algorithm" in all material mentioning or referencing this software
|
||||
* or this function.
|
||||
*
|
||||
* License is also granted to make and use derivative works provided
|
||||
* that such works are identified as "derived from the RSA Data
|
||||
* Security, Inc. MD4 Message-Digest Algorithm" in all material
|
||||
* mentioning or referencing the derived work.
|
||||
*
|
||||
* RSA Data Security, Inc. makes no representations concerning either
|
||||
* the merchantability of this software or the suitability of this
|
||||
* software for any particular purpose. It is provided "as is"
|
||||
* without express or implied warranty of any kind.
|
||||
*
|
||||
* These notices must be retained in any copies of any part of this
|
||||
* documentation and/or software.
|
||||
*/
|
||||
|
||||
For the srclib\apr-util\include\apr_md4.h component:
|
||||
|
||||
*
|
||||
* This is derived from material copyright RSA Data Security, Inc.
|
||||
* Their notice is reproduced below in its entirety.
|
||||
*
|
||||
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
* rights reserved.
|
||||
*
|
||||
* License to copy and use this software is granted provided that it
|
||||
* is identified as the "RSA Data Security, Inc. MD4 Message-Digest
|
||||
* Algorithm" in all material mentioning or referencing this software
|
||||
* or this function.
|
||||
*
|
||||
* License is also granted to make and use derivative works provided
|
||||
* that such works are identified as "derived from the RSA Data
|
||||
* Security, Inc. MD4 Message-Digest Algorithm" in all material
|
||||
* mentioning or referencing the derived work.
|
||||
*
|
||||
* RSA Data Security, Inc. makes no representations concerning either
|
||||
* the merchantability of this software or the suitability of this
|
||||
* software for any particular purpose. It is provided "as is"
|
||||
* without express or implied warranty of any kind.
|
||||
*
|
||||
* These notices must be retained in any copies of any part of this
|
||||
* documentation and/or software.
|
||||
*/
|
||||
|
||||
|
||||
For the srclib\apr-util\test\testdbm.c component:
|
||||
|
||||
/* ====================================================================
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Apache" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
* This file came from the SDBM package (written by oz@nexus.yorku.ca).
|
||||
* That package was under public domain. This file has been ported to
|
||||
* APR, updated to ANSI C and other, newer idioms, and added to the Apache
|
||||
* codebase under the above copyright and license.
|
||||
*/
|
||||
|
||||
|
||||
For the srclib\apr-util\test\testmd4.c component:
|
||||
|
||||
*
|
||||
* This is derived from material copyright RSA Data Security, Inc.
|
||||
* Their notice is reproduced below in its entirety.
|
||||
*
|
||||
* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
|
||||
* rights reserved.
|
||||
*
|
||||
* RSA Data Security, Inc. makes no representations concerning either
|
||||
* the merchantability of this software or the suitability of this
|
||||
* software for any particular purpose. It is provided "as is"
|
||||
* without express or implied warranty of any kind.
|
||||
*
|
||||
* These notices must be retained in any copies of any part of this
|
||||
* documentation and/or software.
|
||||
*/
|
||||
|
||||
For the srclib\apr-util\xml\expat\conftools\install-sh component:
|
||||
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||
#
|
||||
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||
#
|
||||
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||
# documentation for any purpose is hereby granted without fee, provided that
|
||||
# the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting
|
||||
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||
# publicity pertaining to distribution of the software without specific,
|
||||
# written prior permission. M.I.T. makes no representations about the
|
||||
# suitability of this software for any purpose. It is provided "as is"
|
||||
# without express or implied warranty.
|
||||
#
|
||||
|
||||
For the srclib\pcre\install-sh component:
|
||||
|
||||
#
|
||||
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||
#
|
||||
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||
# documentation for any purpose is hereby granted without fee, provided that
|
||||
# the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting
|
||||
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||
# publicity pertaining to distribution of the software without specific,
|
||||
# written prior permission. M.I.T. makes no representations about the
|
||||
# suitability of this software for any purpose. It is provided "as is"
|
||||
# without express or implied warranty.
|
||||
|
||||
For the pcre component:
|
||||
|
||||
PCRE LICENCE
|
||||
------------
|
||||
|
||||
PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England. Phone: +44 1223 334714.
|
||||
|
||||
Copyright (c) 1997-2001 University of Cambridge
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission. In practice, this means that if you use
|
||||
PCRE in software which you distribute to others, commercially or
|
||||
otherwise, you must put a sentence like this
|
||||
|
||||
Regular expression support is provided by the PCRE library package,
|
||||
which is open source software, written by Philip Hazel, and copyright
|
||||
by the University of Cambridge, England.
|
||||
|
||||
somewhere reasonably visible in your documentation and in any relevant
|
||||
files or online help data or similar. A reference to the ftp site for
|
||||
the source, that is, to
|
||||
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
|
||||
|
||||
should also be given in the documentation.
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
|
||||
then the terms of that licence shall supersede any condition above with
|
||||
which it is incompatible.
|
||||
|
||||
The documentation for PCRE, supplied in the "doc" directory, is distributed
|
||||
under the same terms as the software itself.
|
||||
|
||||
End PCRE LICENCE
|
||||
|
||||
|
||||
For the test\zb.c component:
|
||||
|
||||
/* ZeusBench V1.01
|
||||
===============
|
||||
|
||||
This program is Copyright (C) Zeus Technology Limited 1996.
|
||||
|
||||
This program may be used and copied freely providing this copyright notice
|
||||
is not removed.
|
||||
|
||||
This software is provided "as is" and any express or implied waranties,
|
||||
including but not limited to, the implied warranties of merchantability and
|
||||
fitness for a particular purpose are disclaimed. In no event shall
|
||||
Zeus Technology Ltd. be liable for any direct, indirect, incidental, special,
|
||||
exemplary, or consequential damaged (including, but not limited to,
|
||||
procurement of substitute good or services; loss of use, data, or profits;
|
||||
or business interruption) however caused and on theory of liability. Whether
|
||||
in contract, strict liability or tort (including negligence or otherwise)
|
||||
arising in any way out of the use of this software, even if advised of the
|
||||
possibility of such damage.
|
||||
|
||||
Written by Adam Twiss (adam@zeus.co.uk). March 1996
|
||||
|
||||
Thanks to the following people for their input:
|
||||
Mike Belshe (mbelshe@netscape.com)
|
||||
Michael Campanella (campanella@stevms.enet.dec.com)
|
||||
|
||||
*/
|
||||
|
||||
For the expat xml parser component:
|
||||
|
||||
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||
and Clark Cooper
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
====================================================================
|
140
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_apikey.go
generated
vendored
Normal file
140
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_apikey.go
generated
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/account"
|
||||
)
|
||||
|
||||
// APIKeysService handles 'account/apikeys' endpoint.
|
||||
type APIKeysService service
|
||||
|
||||
// List returns all api keys in the account.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#apikeys-get
|
||||
func (s *APIKeysService) List() ([]*account.APIKey, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "account/apikeys", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
kl := []*account.APIKey{}
|
||||
resp, err := s.client.Do(req, &kl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return kl, resp, nil
|
||||
}
|
||||
|
||||
// Get returns details of an api key, including permissions, for a single API Key.
|
||||
// Note: do not use the API Key itself as the keyid in the URL — use the id of the key.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#apikeys-id-get
|
||||
func (s *APIKeysService) Get(keyID string) (*account.APIKey, *http.Response, error) {
|
||||
path := fmt.Sprintf("account/apikeys/%s", keyID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var a account.APIKey
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "unknown api key" {
|
||||
return nil, resp, ErrKeyMissing
|
||||
}
|
||||
|
||||
}
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &a, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *APIKey and creates a new account apikey.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#apikeys-put
|
||||
func (s *APIKeysService) Create(a *account.APIKey) (*http.Response, error) {
|
||||
req, err := s.client.NewRequest("PUT", "account/apikeys", &a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update account fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == fmt.Sprintf("api key with name \"%s\" exists", a.Name) {
|
||||
return resp, ErrKeyExists
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update changes the name or access rights for an API Key.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#apikeys-id-post
|
||||
func (s *APIKeysService) Update(a *account.APIKey) (*http.Response, error) {
|
||||
path := fmt.Sprintf("account/apikeys/%s", a.ID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update apikey fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "unknown api key" {
|
||||
return resp, ErrKeyMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete deletes an apikey.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#apikeys-id-delete
|
||||
func (s *APIKeysService) Delete(keyID string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("account/apikeys/%s", keyID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "unknown api key" {
|
||||
return resp, ErrKeyMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrKeyExists bundles PUT create error.
|
||||
ErrKeyExists = errors.New("key already exists")
|
||||
// ErrKeyMissing bundles GET/POST/DELETE error.
|
||||
ErrKeyMissing = errors.New("key does not exist")
|
||||
)
|
46
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_setting.go
generated
vendored
Normal file
46
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_setting.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/account"
|
||||
)
|
||||
|
||||
// SettingsService handles 'account/settings' endpoint.
|
||||
type SettingsService service
|
||||
|
||||
// Get returns the basic contact details associated with the account.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#settings-get
|
||||
func (s *SettingsService) Get() (*account.Setting, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "account/settings", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var us account.Setting
|
||||
resp, err := s.client.Do(req, &us)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &us, resp, nil
|
||||
}
|
||||
|
||||
// Update changes most of the basic contact details, except customerid.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#settings-post
|
||||
func (s *SettingsService) Update(us *account.Setting) (*http.Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "account/settings", &us)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update usagewarnings fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &us)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
138
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_team.go
generated
vendored
Normal file
138
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_team.go
generated
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/account"
|
||||
)
|
||||
|
||||
// TeamsService handles 'account/teams' endpoint.
|
||||
type TeamsService service
|
||||
|
||||
// List returns all teams in the account.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#teams-get
|
||||
func (s *TeamsService) List() ([]*account.Team, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "account/teams", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
tl := []*account.Team{}
|
||||
resp, err := s.client.Do(req, &tl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return tl, resp, nil
|
||||
}
|
||||
|
||||
// Get returns details of a single team.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#teams-id-get
|
||||
func (s *TeamsService) Get(id string) (*account.Team, *http.Response, error) {
|
||||
path := fmt.Sprintf("account/teams/%s", id)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var t account.Team
|
||||
resp, err := s.client.Do(req, &t)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "Unknown team id" {
|
||||
return nil, resp, ErrTeamMissing
|
||||
}
|
||||
}
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &t, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *Team and creates a new account team.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#teams-put
|
||||
func (s *TeamsService) Create(t *account.Team) (*http.Response, error) {
|
||||
req, err := s.client.NewRequest("PUT", "account/teams", &t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update team fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &t)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == fmt.Sprintf("team with name \"%s\" exists", t.Name) {
|
||||
return resp, ErrTeamExists
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update changes the name or access rights for a team.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#teams-id-post
|
||||
func (s *TeamsService) Update(t *account.Team) (*http.Response, error) {
|
||||
path := fmt.Sprintf("account/teams/%s", t.ID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update team fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &t)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "unknown team id" {
|
||||
return resp, ErrTeamMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete deletes a team.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#teams-id-delete
|
||||
func (s *TeamsService) Delete(id string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("account/teams/%s", id)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "unknown team id" {
|
||||
return resp, ErrTeamMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrTeamExists bundles PUT create error.
|
||||
ErrTeamExists = errors.New("team already exists")
|
||||
// ErrTeamMissing bundles GET/POST/DELETE error.
|
||||
ErrTeamMissing = errors.New("team does not exist")
|
||||
)
|
138
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_user.go
generated
vendored
Normal file
138
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_user.go
generated
vendored
Normal file
@ -0,0 +1,138 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/account"
|
||||
)
|
||||
|
||||
// UsersService handles 'account/users' endpoint.
|
||||
type UsersService service
|
||||
|
||||
// List returns all users in the account.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#users-get
|
||||
func (s *UsersService) List() ([]*account.User, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "account/users", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ul := []*account.User{}
|
||||
resp, err := s.client.Do(req, &ul)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ul, resp, nil
|
||||
}
|
||||
|
||||
// Get returns details of a single user.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#users-user-get
|
||||
func (s *UsersService) Get(username string) (*account.User, *http.Response, error) {
|
||||
path := fmt.Sprintf("account/users/%s", username)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var u account.User
|
||||
resp, err := s.client.Do(req, &u)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "Unknown user" {
|
||||
return nil, resp, ErrUserMissing
|
||||
}
|
||||
}
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &u, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *User and creates a new account user.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#users-put
|
||||
func (s *UsersService) Create(u *account.User) (*http.Response, error) {
|
||||
req, err := s.client.NewRequest("PUT", "account/users", &u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update user fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &u)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "request failed:Login Name is already in use." {
|
||||
return resp, ErrUserExists
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update change contact details, notification settings, or access rights for a user.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#users-user-post
|
||||
func (s *UsersService) Update(u *account.User) (*http.Response, error) {
|
||||
path := fmt.Sprintf("account/users/%s", u.Username)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update user fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &u)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "Unknown user" {
|
||||
return resp, ErrUserMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete deletes a user.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#users-user-delete
|
||||
func (s *UsersService) Delete(username string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("account/users/%s", username)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "Unknown user" {
|
||||
return resp, ErrUserMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrUserExists bundles PUT create error.
|
||||
ErrUserExists = errors.New("user already exists")
|
||||
// ErrUserMissing bundles GET/POST/DELETE error.
|
||||
ErrUserMissing = errors.New("user does not exist")
|
||||
)
|
47
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_warning.go
generated
vendored
Normal file
47
vendor/gopkg.in/ns1/ns1-go.v2/rest/account_warning.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/account"
|
||||
)
|
||||
|
||||
// WarningsService handles 'account/usagewarnings' endpoint.
|
||||
type WarningsService service
|
||||
|
||||
// Get returns toggles and thresholds used when sending overage warning
|
||||
// alert messages to users with billing notifications enabled.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#usagewarnings-get
|
||||
func (s *WarningsService) Get() (*account.UsageWarning, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "account/usagewarnings", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var uw account.UsageWarning
|
||||
resp, err := s.client.Do(req, &uw)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &uw, resp, nil
|
||||
}
|
||||
|
||||
// Update changes alerting toggles and thresholds for overage warning alert messages.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#usagewarnings-post
|
||||
func (s *WarningsService) Update(uw *account.UsageWarning) (*http.Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "account/usagewarnings", &uw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update usagewarnings fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &uw)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
288
vendor/gopkg.in/ns1/ns1-go.v2/rest/client.go
generated
vendored
Normal file
288
vendor/gopkg.in/ns1/ns1-go.v2/rest/client.go
generated
vendored
Normal file
@ -0,0 +1,288 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
clientVersion = "2.0.0"
|
||||
defaultEndpoint = "https://api.nsone.net/v1/"
|
||||
defaultUserAgent = "go-ns1/" + clientVersion
|
||||
|
||||
headerAuth = "X-NSONE-Key"
|
||||
headerRateLimit = "X-Ratelimit-Limit"
|
||||
headerRateRemaining = "X-Ratelimit-Remaining"
|
||||
headerRatePeriod = "X-Ratelimit-Period"
|
||||
)
|
||||
|
||||
// Doer is a single method interface that allows a user to extend/augment an http.Client instance.
|
||||
// Note: http.Client satisfies the Doer interface.
|
||||
type Doer interface {
|
||||
Do(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// Client manages communication with the NS1 Rest API.
|
||||
type Client struct {
|
||||
// httpClient handles all rest api communication,
|
||||
// and expects an *http.Client.
|
||||
httpClient Doer
|
||||
|
||||
// NS1 rest endpoint, overrides default if given.
|
||||
Endpoint *url.URL
|
||||
|
||||
// NS1 api key (value for http request header 'X-NSONE-Key').
|
||||
APIKey string
|
||||
|
||||
// NS1 go rest user agent (value for http request header 'User-Agent').
|
||||
UserAgent string
|
||||
|
||||
// Func to call after response is returned in Do
|
||||
RateLimitFunc func(RateLimit)
|
||||
|
||||
// From the excellent github-go client.
|
||||
common service // Reuse a single struct instead of allocating one for each service on the heap.
|
||||
|
||||
// Services used for communicating with different components of the NS1 API.
|
||||
APIKeys *APIKeysService
|
||||
DataFeeds *DataFeedsService
|
||||
DataSources *DataSourcesService
|
||||
Jobs *JobsService
|
||||
Notifications *NotificationsService
|
||||
Records *RecordsService
|
||||
Settings *SettingsService
|
||||
Teams *TeamsService
|
||||
Users *UsersService
|
||||
Warnings *WarningsService
|
||||
Zones *ZonesService
|
||||
}
|
||||
|
||||
// NewClient constructs and returns a reference to an instantiated Client.
|
||||
func NewClient(httpClient Doer, options ...func(*Client)) *Client {
|
||||
endpoint, _ := url.Parse(defaultEndpoint)
|
||||
|
||||
if httpClient == nil {
|
||||
httpClient = http.DefaultClient
|
||||
}
|
||||
|
||||
c := &Client{
|
||||
httpClient: httpClient,
|
||||
Endpoint: endpoint,
|
||||
RateLimitFunc: defaultRateLimitFunc,
|
||||
UserAgent: defaultUserAgent,
|
||||
}
|
||||
|
||||
c.common.client = c
|
||||
c.APIKeys = (*APIKeysService)(&c.common)
|
||||
c.DataFeeds = (*DataFeedsService)(&c.common)
|
||||
c.DataSources = (*DataSourcesService)(&c.common)
|
||||
c.Jobs = (*JobsService)(&c.common)
|
||||
c.Notifications = (*NotificationsService)(&c.common)
|
||||
c.Records = (*RecordsService)(&c.common)
|
||||
c.Settings = (*SettingsService)(&c.common)
|
||||
c.Teams = (*TeamsService)(&c.common)
|
||||
c.Users = (*UsersService)(&c.common)
|
||||
c.Warnings = (*WarningsService)(&c.common)
|
||||
c.Zones = (*ZonesService)(&c.common)
|
||||
|
||||
for _, option := range options {
|
||||
option(c)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
type service struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// SetHTTPClient sets a Client instances' httpClient.
|
||||
func SetHTTPClient(httpClient Doer) func(*Client) {
|
||||
return func(c *Client) { c.httpClient = httpClient }
|
||||
}
|
||||
|
||||
// SetAPIKey sets a Client instances' APIKey.
|
||||
func SetAPIKey(key string) func(*Client) {
|
||||
return func(c *Client) { c.APIKey = key }
|
||||
}
|
||||
|
||||
// SetEndpoint sets a Client instances' Endpoint.
|
||||
func SetEndpoint(endpoint string) func(*Client) {
|
||||
return func(c *Client) { c.Endpoint, _ = url.Parse(endpoint) }
|
||||
}
|
||||
|
||||
// SetUserAgent sets a Client instances' user agent.
|
||||
func SetUserAgent(ua string) func(*Client) {
|
||||
return func(c *Client) { c.UserAgent = ua }
|
||||
}
|
||||
|
||||
// SetRateLimitFunc sets a Client instances' RateLimitFunc.
|
||||
func SetRateLimitFunc(ratefunc func(rl RateLimit)) func(*Client) {
|
||||
return func(c *Client) { c.RateLimitFunc = ratefunc }
|
||||
}
|
||||
|
||||
// Do satisfies the Doer interface.
|
||||
func (c Client) Do(req *http.Request, v interface{}) (*http.Response, error) {
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
err = CheckResponse(resp)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
rl := parseRate(resp)
|
||||
c.RateLimitFunc(rl)
|
||||
|
||||
if v != nil {
|
||||
// Try to unmarshal body into given type using streaming decoder.
|
||||
if err := json.NewDecoder(resp.Body).Decode(&v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// NewRequest constructs and returns a http.Request.
|
||||
func (c *Client) NewRequest(method, path string, body interface{}) (*http.Request, error) {
|
||||
rel, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
uri := c.Endpoint.ResolveReference(rel)
|
||||
|
||||
// Encode body as json
|
||||
buf := new(bytes.Buffer)
|
||||
if body != nil {
|
||||
err := json.NewEncoder(buf).Encode(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, uri.String(), buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add(headerAuth, c.APIKey)
|
||||
req.Header.Add("User-Agent", c.UserAgent)
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Response wraps stdlib http response.
|
||||
type Response struct {
|
||||
*http.Response
|
||||
}
|
||||
|
||||
// Error contains all http responses outside the 2xx range.
|
||||
type Error struct {
|
||||
Resp *http.Response
|
||||
Message string
|
||||
}
|
||||
|
||||
// Satisfy std lib error interface.
|
||||
func (re *Error) Error() string {
|
||||
return fmt.Sprintf("%v %v: %d %v", re.Resp.Request.Method, re.Resp.Request.URL, re.Resp.StatusCode, re.Message)
|
||||
}
|
||||
|
||||
// CheckResponse handles parsing of rest api errors. Returns nil if no error.
|
||||
func CheckResponse(resp *http.Response) error {
|
||||
if c := resp.StatusCode; c >= 200 && c <= 299 {
|
||||
return nil
|
||||
}
|
||||
|
||||
restErr := &Error{Resp: resp}
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(b) == 0 {
|
||||
return restErr
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, restErr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return restErr
|
||||
}
|
||||
|
||||
// RateLimitFunc is rate limiting strategy for the Client instance.
|
||||
type RateLimitFunc func(RateLimit)
|
||||
|
||||
// RateLimit stores X-Ratelimit-* headers
|
||||
type RateLimit struct {
|
||||
Limit int
|
||||
Remaining int
|
||||
Period int
|
||||
}
|
||||
|
||||
var defaultRateLimitFunc = func(rl RateLimit) {}
|
||||
|
||||
// PercentageLeft returns the ratio of Remaining to Limit as a percentage
|
||||
func (rl RateLimit) PercentageLeft() int {
|
||||
return rl.Remaining * 100 / rl.Limit
|
||||
}
|
||||
|
||||
// WaitTime returns the time.Duration ratio of Period to Limit
|
||||
func (rl RateLimit) WaitTime() time.Duration {
|
||||
return (time.Second * time.Duration(rl.Period)) / time.Duration(rl.Limit)
|
||||
}
|
||||
|
||||
// WaitTimeRemaining returns the time.Duration ratio of Period to Remaining
|
||||
func (rl RateLimit) WaitTimeRemaining() time.Duration {
|
||||
return (time.Second * time.Duration(rl.Period)) / time.Duration(rl.Remaining)
|
||||
}
|
||||
|
||||
// RateLimitStrategySleep sets RateLimitFunc to sleep by WaitTimeRemaining
|
||||
func (c *Client) RateLimitStrategySleep() {
|
||||
c.RateLimitFunc = func(rl RateLimit) {
|
||||
remaining := rl.WaitTimeRemaining()
|
||||
time.Sleep(remaining)
|
||||
}
|
||||
}
|
||||
|
||||
// parseRate parses rate related headers from http response.
|
||||
func parseRate(resp *http.Response) RateLimit {
|
||||
var rl RateLimit
|
||||
|
||||
if limit := resp.Header.Get(headerRateLimit); limit != "" {
|
||||
rl.Limit, _ = strconv.Atoi(limit)
|
||||
}
|
||||
if remaining := resp.Header.Get(headerRateRemaining); remaining != "" {
|
||||
rl.Remaining, _ = strconv.Atoi(remaining)
|
||||
}
|
||||
if period := resp.Header.Get(headerRatePeriod); period != "" {
|
||||
rl.Period, _ = strconv.Atoi(period)
|
||||
}
|
||||
|
||||
return rl
|
||||
}
|
||||
|
||||
// SetTimeParam sets a url timestamp query param given the parameters name.
|
||||
func SetTimeParam(key string, t time.Time) func(*url.Values) {
|
||||
return func(v *url.Values) { v.Set(key, strconv.Itoa(int(t.Unix()))) }
|
||||
}
|
||||
|
||||
// SetBoolParam sets a url boolean query param given the parameters name.
|
||||
func SetBoolParam(key string, b bool) func(*url.Values) {
|
||||
return func(v *url.Values) { v.Set(key, strconv.FormatBool(b)) }
|
||||
}
|
||||
|
||||
// SetStringParam sets a url string query param given the parameters name.
|
||||
func SetStringParam(key, val string) func(*url.Values) {
|
||||
return func(v *url.Values) { v.Set(key, val) }
|
||||
}
|
116
vendor/gopkg.in/ns1/ns1-go.v2/rest/data_feed.go
generated
vendored
Normal file
116
vendor/gopkg.in/ns1/ns1-go.v2/rest/data_feed.go
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/data"
|
||||
)
|
||||
|
||||
// DataFeedsService handles 'data/feeds' endpoint.
|
||||
type DataFeedsService service
|
||||
|
||||
// List returns all data feeds connected to a given data source.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#feeds-get
|
||||
func (s *DataFeedsService) List(sourceID string) ([]*data.Feed, *http.Response, error) {
|
||||
path := fmt.Sprintf("data/feeds/%s", sourceID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
dfl := []*data.Feed{}
|
||||
resp, err := s.client.Do(req, &dfl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return dfl, resp, nil
|
||||
}
|
||||
|
||||
// Get takes a data source ID and a data feed ID and returns the details of a single data feed
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#feeds-feed-get
|
||||
func (s *DataFeedsService) Get(sourceID string, feedID string) (*data.Feed, *http.Response, error) {
|
||||
path := fmt.Sprintf("data/feeds/%s/%s", sourceID, feedID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var df data.Feed
|
||||
resp, err := s.client.Do(req, &df)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &df, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *DataFeed and connects a new data feed to an existing data source.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#feeds-put
|
||||
func (s *DataFeedsService) Create(sourceID string, df *data.Feed) (*http.Response, error) {
|
||||
path := fmt.Sprintf("data/feeds/%s", sourceID)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", path, &df)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update datafeeds' fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &df)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update takes a *Feed and modifies and existing data feed.
|
||||
// Note:
|
||||
// - The 'data' portion of a feed does not actually
|
||||
// get updated during a POST. In order to update a feeds'
|
||||
// 'data' attribute, one must use the Publish method.
|
||||
// - Both the 'destinations' and 'networks' attributes are
|
||||
// not updated during a POST.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#feeds-post
|
||||
func (s *DataFeedsService) Update(sourceID string, df *data.Feed) (*http.Response, error) {
|
||||
path := fmt.Sprintf("data/feeds/%s/%s", sourceID, df.ID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &df)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update df instance fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &df)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete takes a data source ID and a data feed ID and disconnects the feed from the data source and all attached destination metadata tables.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#feeds-delete
|
||||
func (s *DataFeedsService) Delete(sourceID string, feedID string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("data/feeds/%s/%s", sourceID, feedID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
126
vendor/gopkg.in/ns1/ns1-go.v2/rest/data_source.go
generated
vendored
Normal file
126
vendor/gopkg.in/ns1/ns1-go.v2/rest/data_source.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/data"
|
||||
)
|
||||
|
||||
// DataSourcesService handles 'data/sources' endpoint.
|
||||
type DataSourcesService service
|
||||
|
||||
// List returns all connected data sources.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#sources-get
|
||||
func (s *DataSourcesService) List() ([]*data.Source, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "data/sources", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
dsl := []*data.Source{}
|
||||
resp, err := s.client.Do(req, &dsl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return dsl, resp, nil
|
||||
}
|
||||
|
||||
// Get takes an ID returns the details for a single data source.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#sources-source-get
|
||||
func (s *DataSourcesService) Get(id string) (*data.Source, *http.Response, error) {
|
||||
path := fmt.Sprintf("data/sources/%s", id)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ds data.Source
|
||||
resp, err := s.client.Do(req, &ds)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &ds, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *DataSource and creates a new data source.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#sources-put
|
||||
func (s *DataSourcesService) Create(ds *data.Source) (*http.Response, error) {
|
||||
req, err := s.client.NewRequest("PUT", "data/sources", &ds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update data sources' fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &ds)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update takes a *DataSource modifies basic details of a data source.
|
||||
// NOTE: This does not 'publish' data. See the Publish method.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#sources-post
|
||||
func (s *DataSourcesService) Update(ds *data.Source) (*http.Response, error) {
|
||||
path := fmt.Sprintf("data/sources/%s", ds.ID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &ds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update data sources' instance fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &ds)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete takes an ID and removes an existing data source and all connected feeds from the source.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#sources-delete
|
||||
func (s *DataSourcesService) Delete(id string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("data/sources/%s", id)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Publish takes a datasources' id and data to publish.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#feed-post
|
||||
func (s *DataSourcesService) Publish(dsID string, data interface{}) (*http.Response, error) {
|
||||
path := fmt.Sprintf("feed/%s", dsID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/doc.go
generated
vendored
Normal file
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package rest defines the api services used to communicate with NS1.
|
||||
package rest
|
13
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/apikey.go
generated
vendored
Normal file
13
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/apikey.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package account
|
||||
|
||||
// APIKey wraps an NS1 /account/apikeys resource
|
||||
type APIKey struct {
|
||||
// Read-only fields
|
||||
ID string `json:"id,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
LastAccess int `json:"last_access,omitempty"`
|
||||
|
||||
Name string `json:"name"`
|
||||
TeamIDs []string `json:"teams"`
|
||||
Permissions PermissionsMap `json:"permissions"`
|
||||
}
|
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/doc.go
generated
vendored
Normal file
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package account contains definitions for NS1 apikeys/teams/users/etc.
|
||||
package account
|
44
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/permissions.go
generated
vendored
Normal file
44
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/permissions.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
package account
|
||||
|
||||
// PermissionsMap wraps a User's "permissions" attribute
|
||||
type PermissionsMap struct {
|
||||
DNS PermissionsDNS `json:"dns"`
|
||||
Data PermissionsData `json:"data"`
|
||||
Account PermissionsAccount `json:"account"`
|
||||
Monitoring PermissionsMonitoring `json:"monitoring"`
|
||||
}
|
||||
|
||||
// PermissionsDNS wraps a User's "permissions.dns" attribute
|
||||
type PermissionsDNS struct {
|
||||
ViewZones bool `json:"view_zones"`
|
||||
ManageZones bool `json:"manage_zones"`
|
||||
ZonesAllowByDefault bool `json:"zones_allow_by_default"`
|
||||
ZonesDeny []string `json:"zones_deny"`
|
||||
ZonesAllow []string `json:"zones_allow"`
|
||||
}
|
||||
|
||||
// PermissionsData wraps a User's "permissions.data" attribute
|
||||
type PermissionsData struct {
|
||||
PushToDatafeeds bool `json:"push_to_datafeeds"`
|
||||
ManageDatasources bool `json:"manage_datasources"`
|
||||
ManageDatafeeds bool `json:"manage_datafeeds"`
|
||||
}
|
||||
|
||||
// PermissionsAccount wraps a User's "permissions.account" attribute
|
||||
type PermissionsAccount struct {
|
||||
ManageUsers bool `json:"manage_users"`
|
||||
ManagePaymentMethods bool `json:"manage_payment_methods"`
|
||||
ManagePlan bool `json:"manage_plan"`
|
||||
ManageTeams bool `json:"manage_teams"`
|
||||
ManageApikeys bool `json:"manage_apikeys"`
|
||||
ManageAccountSettings bool `json:"manage_account_settings"`
|
||||
ViewActivityLog bool `json:"view_activity_log"`
|
||||
ViewInvoices bool `json:"view_invoices"`
|
||||
}
|
||||
|
||||
// PermissionsMonitoring wraps a User's "permissions.monitoring" attribute
|
||||
type PermissionsMonitoring struct {
|
||||
ManageLists bool `json:"manage_lists"`
|
||||
ManageJobs bool `json:"manage_jobs"`
|
||||
ViewJobs bool `json:"view_jobs"`
|
||||
}
|
21
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/settings.go
generated
vendored
Normal file
21
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/settings.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
package account
|
||||
|
||||
// Setting represents an accounts' contact info.
|
||||
type Setting struct {
|
||||
CustomerID int `json:"customerid,omitempty"`
|
||||
FirstName string `json:"firstname,omitempty"`
|
||||
LastName string `json:"lastname,omitempty"`
|
||||
Company string `json:"company,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Address Address `json:"address,omitempty"`
|
||||
}
|
||||
|
||||
// Address for Setting struct.
|
||||
type Address struct {
|
||||
Country string `json:"country,omitempty"`
|
||||
Street string `json:"street,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
City string `json:"city,omitempty"`
|
||||
Postal string `json:"postalcode,omitempty"`
|
||||
}
|
8
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/team.go
generated
vendored
Normal file
8
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/team.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
package account
|
||||
|
||||
// Team wraps an NS1 /accounts/teams resource
|
||||
type Team struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Permissions PermissionsMap `json:"permissions"`
|
||||
}
|
19
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/user.go
generated
vendored
Normal file
19
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/user.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
package account
|
||||
|
||||
// User wraps an NS1 /account/users resource
|
||||
type User struct {
|
||||
// Read-only fields
|
||||
LastAccess float64 `json:"last_access"`
|
||||
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
TeamIDs []string `json:"teams"`
|
||||
Notify NotificationSettings `json:"notify"`
|
||||
Permissions PermissionsMap `json:"permissions"`
|
||||
}
|
||||
|
||||
// NotificationSettings wraps a User's "notify" attribute
|
||||
type NotificationSettings struct {
|
||||
Billing bool `json:"billing"`
|
||||
}
|
17
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/warning.go
generated
vendored
Normal file
17
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/account/warning.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
package account
|
||||
|
||||
// UsageWarning wraps an NS1 /account/usagewarnings resource
|
||||
type UsageWarning struct {
|
||||
Records Warning `json:"records"`
|
||||
Queries Warning `json:"queries"`
|
||||
}
|
||||
|
||||
// Warning contains alerting toggles and thresholds for overage warning alert messages.
|
||||
// First thresholds must be smaller than Second ones and all thresholds
|
||||
// must be percentages between 0 and 100.
|
||||
type Warning struct {
|
||||
Send bool `json:"send_warnings"`
|
||||
|
||||
First int `json:"warning_1"`
|
||||
Second int `json:"warning_2"`
|
||||
}
|
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/doc.go
generated
vendored
Normal file
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package data contains definitions for NS1 metadata/sources/feeds/etc.
|
||||
package data
|
38
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/feed.go
generated
vendored
Normal file
38
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/feed.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package data
|
||||
|
||||
// Destination is the target resource the receives data from a feed/source.
|
||||
type Destination struct {
|
||||
ID string `json:"destid"`
|
||||
|
||||
// All destinations must point to a record.
|
||||
RecordID string `json:"record"`
|
||||
|
||||
// Type is the 'level' at which to apply the filters(on the targeted record).
|
||||
// Options:
|
||||
// - answer (highest precedence)
|
||||
// - region
|
||||
// - record (lowest precendence)
|
||||
Type string `json:"desttype"`
|
||||
|
||||
SourceID string `json:"-"`
|
||||
}
|
||||
|
||||
// NewDestination returns an empty feed destination.
|
||||
func NewDestination() *Destination {
|
||||
return &Destination{}
|
||||
}
|
||||
|
||||
// Feed wraps an NS1 /data/feeds resource
|
||||
type Feed struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Config Config `json:"config,omitempty"`
|
||||
Data Meta `json:"data,omitempty"`
|
||||
|
||||
SourceID string
|
||||
}
|
||||
|
||||
// NewFeed returns a data feed with given name and config.
|
||||
func NewFeed(name string, cfg Config) *Feed {
|
||||
return &Feed{Name: name, Config: cfg}
|
||||
}
|
127
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go
generated
vendored
Normal file
127
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/meta.go
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
package data
|
||||
|
||||
// FeedPtr represents the dynamic metadata value in which a feed is providing the value.
|
||||
type FeedPtr struct {
|
||||
FeedID string `json:"feed,omitempty"`
|
||||
}
|
||||
|
||||
// Meta contains information on an entities metadata table. Metadata key/value
|
||||
// pairs are used by a records' filter pipeline during a dns query.
|
||||
// All values can be a feed id as well, indicating real-time updates of these values.
|
||||
// Structure/Precendence of metadata tables:
|
||||
// - Record
|
||||
// - Meta <- lowest precendence in filter
|
||||
// - Region(s)
|
||||
// - Meta <- middle precedence in filter chain
|
||||
// - ...
|
||||
// - Answer(s)
|
||||
// - Meta <- highest precedence in filter chain
|
||||
// - ...
|
||||
// - ...
|
||||
type Meta struct {
|
||||
// STATUS
|
||||
|
||||
// Indicates whether or not entity is considered 'up'
|
||||
// bool or FeedPtr.
|
||||
Up interface{} `json:"up,omitempty"`
|
||||
|
||||
// Indicates the number of active connections.
|
||||
// Values must be positive.
|
||||
// int or FeedPtr.
|
||||
Connections interface{} `json:"connections,omitempty"`
|
||||
|
||||
// Indicates the number of active requests (HTTP or otherwise).
|
||||
// Values must be positive.
|
||||
// int or FeedPtr.
|
||||
Requests interface{} `json:"requests,omitempty"`
|
||||
|
||||
// Indicates the "load average".
|
||||
// Values must be positive, and will be rounded to the nearest tenth.
|
||||
// float64 or FeedPtr.
|
||||
LoadAvg interface{} `json:"loadavg,omitempty"`
|
||||
|
||||
// The Job ID of a Pulsar telemetry gathering job and routing granularities
|
||||
// to associate with.
|
||||
// string or FeedPtr.
|
||||
Pulsar interface{} `json:"pulsar,omitempty"`
|
||||
|
||||
// GEOGRAPHICAL
|
||||
|
||||
// Must be between -180.0 and +180.0 where negative
|
||||
// indicates South and positive indicates North.
|
||||
// e.g., the longitude of the datacenter where a server resides.
|
||||
// float64 or FeedPtr.
|
||||
Latitude interface{} `json:"latitude,omitempty"`
|
||||
|
||||
// Must be between -180.0 and +180.0 where negative
|
||||
// indicates West and positive indicates East.
|
||||
// e.g., the longitude of the datacenter where a server resides.
|
||||
// float64 or FeedPtr.
|
||||
Longitude interface{} `json:"longitude,omitempty"`
|
||||
|
||||
// Valid geographic regions are: 'US-EAST', 'US-CENTRAL', 'US-WEST',
|
||||
// 'EUROPE', 'ASIAPAC', 'SOUTH-AMERICA', 'AFRICA'.
|
||||
// e.g., the rough geographic location of the Datacenter where a server resides.
|
||||
// []string or FeedPtr.
|
||||
Georegion interface{} `json:"georegion,omitempty"`
|
||||
|
||||
// Countr(ies) must be specified as ISO3166 2-character country code(s).
|
||||
// []string or FeedPtr.
|
||||
Country interface{} `json:"country,omitempty"`
|
||||
|
||||
// State(s) must be specified as standard 2-character state code(s).
|
||||
// []string or FeedPtr.
|
||||
USState interface{} `json:"us_state,omitempty"`
|
||||
|
||||
// Canadian Province(s) must be specified as standard 2-character province
|
||||
// code(s).
|
||||
// []string or FeedPtr.
|
||||
CAProvince interface{} `json:"ca_province,omitempty"`
|
||||
|
||||
// INFORMATIONAL
|
||||
|
||||
// Notes to indicate any necessary details for operators.
|
||||
// Up to 256 characters in length.
|
||||
// string or FeedPtr.
|
||||
Note interface{} `json:"note,omitempty"`
|
||||
|
||||
// NETWORK
|
||||
|
||||
// IP (v4 and v6) prefixes in CIDR format ("a.b.c.d/mask").
|
||||
// May include up to 1000 prefixes.
|
||||
// e.g., "1.2.3.4/24"
|
||||
// []string or FeedPtr.
|
||||
IPPrefixes interface{} `json:"ip_prefixes,omitempty"`
|
||||
|
||||
// Autonomous System (AS) number(s).
|
||||
// May include up to 1000 AS numbers.
|
||||
// []string or FeedPtr.
|
||||
ASN interface{} `json:"asn,omitempty"`
|
||||
|
||||
// TRAFFIC
|
||||
|
||||
// Indicates the "priority tier".
|
||||
// Lower values indicate higher priority.
|
||||
// Values must be positive.
|
||||
// int or FeedPtr.
|
||||
Priority interface{} `json:"priority,omitempty"`
|
||||
|
||||
// Indicates a weight.
|
||||
// Filters that use weights normalize them.
|
||||
// Any positive values are allowed.
|
||||
// Values between 0 and 100 are recommended for simplicity's sake.
|
||||
// float64 or FeedPtr.
|
||||
Weight interface{} `json:"weight,omitempty"`
|
||||
|
||||
// Indicates a "low watermark" to use for load shedding.
|
||||
// The value should depend on the metric used to determine
|
||||
// load (e.g., loadavg, connections, etc).
|
||||
// int or FeedPtr.
|
||||
LowWatermark interface{} `json:"low_watermark,omitempty"`
|
||||
|
||||
// Indicates a "high watermark" to use for load shedding.
|
||||
// The value should depend on the metric used to determine
|
||||
// load (e.g., loadavg, connections, etc).
|
||||
// int or FeedPtr.
|
||||
HighWatermark interface{} `json:"high_watermark,omitempty"`
|
||||
}
|
10
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/region.go
generated
vendored
Normal file
10
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/region.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
package data
|
||||
|
||||
// Region is a metadata table with a name/key.
|
||||
// Can be thought of as metadata groupings.
|
||||
type Region struct {
|
||||
Meta Meta `json:"meta,omitempty"`
|
||||
}
|
||||
|
||||
// Regions is simply a mapping of Regions inside a record.
|
||||
type Regions map[string]Region
|
28
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/source.go
generated
vendored
Normal file
28
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/data/source.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
package data
|
||||
|
||||
// Config is a flat mapping where values are simple (no slices/maps).
|
||||
type Config map[string]interface{}
|
||||
|
||||
// Source wraps an NS1 /data/sources resource
|
||||
type Source struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// Human readable name of the source.
|
||||
Name string `json:"name"`
|
||||
|
||||
Type string `json:"sourcetype"`
|
||||
Config Config `json:"config,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
Feeds []*Feed `json:"feeds,omitempty"`
|
||||
}
|
||||
|
||||
// NewSource takes a name and type t.
|
||||
func NewSource(name string, t string) *Source {
|
||||
return &Source{
|
||||
Name: name,
|
||||
Type: t,
|
||||
Config: Config{},
|
||||
Feeds: []*Feed{},
|
||||
}
|
||||
}
|
101
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/answer.go
generated
vendored
Normal file
101
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/answer.go
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/data"
|
||||
)
|
||||
|
||||
// Answer wraps the values of a Record's "filters" attribute
|
||||
type Answer struct {
|
||||
Meta *data.Meta `json:"meta,omitempty"`
|
||||
|
||||
// Answer response data. eg:
|
||||
// Av4: ["1.1.1.1"]
|
||||
// Av6: ["2001:db8:85a3::8a2e:370:7334"]
|
||||
// MX: [10, "2.2.2.2"]
|
||||
Rdata []string `json:"answer"`
|
||||
|
||||
// Region(grouping) that answer belongs to.
|
||||
RegionName string `json:"region,omitempty"`
|
||||
}
|
||||
|
||||
func (a Answer) String() string {
|
||||
return strings.Trim(fmt.Sprint(a.Rdata), "[]")
|
||||
}
|
||||
|
||||
// SetRegion associates a region with this answer.
|
||||
func (a *Answer) SetRegion(name string) {
|
||||
a.RegionName = name
|
||||
}
|
||||
|
||||
// NewAnswer creates a generic Answer with given rdata.
|
||||
func NewAnswer(rdata []string) *Answer {
|
||||
return &Answer{
|
||||
Meta: &data.Meta{},
|
||||
Rdata: rdata,
|
||||
}
|
||||
}
|
||||
|
||||
// NewAv4Answer creates an Answer for A record.
|
||||
func NewAv4Answer(host string) *Answer {
|
||||
return &Answer{
|
||||
Meta: &data.Meta{},
|
||||
Rdata: []string{host},
|
||||
}
|
||||
}
|
||||
|
||||
// NewAv6Answer creates an Answer for AAAA record.
|
||||
func NewAv6Answer(host string) *Answer {
|
||||
return &Answer{
|
||||
Meta: &data.Meta{},
|
||||
Rdata: []string{host},
|
||||
}
|
||||
}
|
||||
|
||||
// NewALIASAnswer creates an Answer for ALIAS record.
|
||||
func NewALIASAnswer(host string) *Answer {
|
||||
return &Answer{
|
||||
Meta: &data.Meta{},
|
||||
Rdata: []string{host},
|
||||
}
|
||||
}
|
||||
|
||||
// NewCNAMEAnswer creates an Answer for CNAME record.
|
||||
func NewCNAMEAnswer(name string) *Answer {
|
||||
return &Answer{
|
||||
Meta: &data.Meta{},
|
||||
Rdata: []string{name},
|
||||
}
|
||||
}
|
||||
|
||||
// NewTXTAnswer creates an Answer for TXT record.
|
||||
func NewTXTAnswer(text string) *Answer {
|
||||
return &Answer{
|
||||
Meta: &data.Meta{},
|
||||
Rdata: []string{text},
|
||||
}
|
||||
}
|
||||
|
||||
// NewMXAnswer creates an Answer for MX record.
|
||||
func NewMXAnswer(pri int, host string) *Answer {
|
||||
return &Answer{
|
||||
Meta: &data.Meta{},
|
||||
Rdata: []string{strconv.Itoa(pri), host},
|
||||
}
|
||||
}
|
||||
|
||||
// NewSRVAnswer creates an Answer for SRV record.
|
||||
func NewSRVAnswer(priority, weight, port int, target string) *Answer {
|
||||
return &Answer{
|
||||
Meta: &data.Meta{},
|
||||
Rdata: []string{
|
||||
strconv.Itoa(priority),
|
||||
strconv.Itoa(weight),
|
||||
strconv.Itoa(port),
|
||||
target,
|
||||
},
|
||||
}
|
||||
}
|
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/doc.go
generated
vendored
Normal file
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package dns contains definitions for NS1 zones/records/answers/etc.
|
||||
package dns
|
76
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/record.go
generated
vendored
Normal file
76
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/record.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/data"
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/filter"
|
||||
)
|
||||
|
||||
// Record wraps an NS1 /zone/{zone}/{domain}/{type} resource
|
||||
type Record struct {
|
||||
Meta *data.Meta `json:"meta,omitempty"`
|
||||
|
||||
ID string `json:"id,omitempty"`
|
||||
Zone string `json:"zone"`
|
||||
Domain string `json:"domain"`
|
||||
Type string `json:"type"`
|
||||
Link string `json:"link,omitempty"`
|
||||
TTL int `json:"ttl,omitempty"`
|
||||
UseClientSubnet *bool `json:"use_client_subnet,omitempty"`
|
||||
|
||||
// Answers must all be of the same type as the record.
|
||||
Answers []*Answer `json:"answers"`
|
||||
// The records' filter chain.
|
||||
Filters []*filter.Filter `json:"filters,omitempty"`
|
||||
// The records' regions.
|
||||
Regions data.Regions `json:"regions,omitempty"`
|
||||
}
|
||||
|
||||
func (r Record) String() string {
|
||||
return fmt.Sprintf("%s %s", r.Domain, r.Type)
|
||||
}
|
||||
|
||||
// NewRecord takes a zone, domain and record type t and creates a *Record with
|
||||
// UseClientSubnet: true & empty Answers.
|
||||
func NewRecord(zone string, domain string, t string) *Record {
|
||||
if !strings.HasSuffix(domain, zone) {
|
||||
domain = fmt.Sprintf("%s.%s", domain, zone)
|
||||
}
|
||||
return &Record{
|
||||
Meta: &data.Meta{},
|
||||
Zone: zone,
|
||||
Domain: domain,
|
||||
Type: t,
|
||||
Answers: []*Answer{},
|
||||
Regions: data.Regions{},
|
||||
}
|
||||
}
|
||||
|
||||
// LinkTo sets a Record Link to an FQDN.
|
||||
// to is the FQDN of the target record whose config should be used. Does
|
||||
// not have to be in the same zone.
|
||||
func (r *Record) LinkTo(to string) {
|
||||
r.Meta = nil
|
||||
r.Answers = []*Answer{}
|
||||
r.Link = to
|
||||
}
|
||||
|
||||
// AddAnswer adds an answer to the record.
|
||||
func (r *Record) AddAnswer(ans *Answer) {
|
||||
if r.Answers == nil {
|
||||
r.Answers = []*Answer{}
|
||||
}
|
||||
|
||||
r.Answers = append(r.Answers, ans)
|
||||
}
|
||||
|
||||
// AddFilter adds a filter to the records' filter chain(ordering of filters matters).
|
||||
func (r *Record) AddFilter(fil *filter.Filter) {
|
||||
if r.Filters == nil {
|
||||
r.Filters = []*filter.Filter{}
|
||||
}
|
||||
|
||||
r.Filters = append(r.Filters, fil)
|
||||
}
|
157
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/zone.go
generated
vendored
Normal file
157
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/dns/zone.go
generated
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
package dns
|
||||
|
||||
import "gopkg.in/ns1/ns1-go.v2/rest/model/data"
|
||||
|
||||
// Zone wraps an NS1 /zone resource
|
||||
type Zone struct {
|
||||
// Zones have metadata tables, but no filters act on 'zone-level' meta.
|
||||
Meta *data.Meta `json:"meta,omitempty"`
|
||||
|
||||
// Read-only fields
|
||||
DNSServers []string `json:"dns_servers,omitempty"`
|
||||
NetworkPools []string `json:"network_pools,omitempty"`
|
||||
Pool string `json:"pool,omitempty"` // Deprecated
|
||||
|
||||
ID string `json:"id,omitempty"`
|
||||
Zone string `json:"zone,omitempty"`
|
||||
|
||||
TTL int `json:"ttl,omitempty"`
|
||||
NxTTL int `json:"nx_ttl,omitempty"`
|
||||
Retry int `json:"retry,omitempty"`
|
||||
Serial int `json:"serial,omitempty"`
|
||||
Refresh int `json:"refresh,omitempty"`
|
||||
Expiry int `json:"expiry,omitempty"`
|
||||
Hostmaster string `json:"hostmaster,omitempty"`
|
||||
|
||||
// If this is a linked zone, Link points to an existing standard zone,
|
||||
// reusing its configuration and records. Link is a zones' domain name.
|
||||
Link *string `json:"link,omitempty"`
|
||||
|
||||
// Networks contains the network ids the zone is available. Most zones
|
||||
// will be in the NSONE Global Network(which is id 0).
|
||||
NetworkIDs []int `json:"networks,omitempty"`
|
||||
Records []*ZoneRecord `json:"records,omitempty"`
|
||||
|
||||
// Primary contains info to enable slaving of the zone by third party dns servers.
|
||||
Primary *ZonePrimary `json:"primary,omitempty"`
|
||||
// Secondary contains info for slaving the zone to a primary dns server.
|
||||
Secondary *ZoneSecondary `json:"secondary,omitempty"`
|
||||
}
|
||||
|
||||
func (z Zone) String() string {
|
||||
return z.Zone
|
||||
}
|
||||
|
||||
// ZoneRecord wraps Zone's "records" attribute
|
||||
type ZoneRecord struct {
|
||||
Domain string `json:"Domain,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Link string `json:"link,omitempty"`
|
||||
ShortAns []string `json:"short_answers,omitempty"`
|
||||
Tier int `json:"tier,omitempty"`
|
||||
TTL int `json:"ttl,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// ZonePrimary wraps a Zone's "primary" attribute
|
||||
type ZonePrimary struct {
|
||||
// Enabled determines whether AXFR queries (and optionally NOTIFY messages)
|
||||
// will be enabled for the zone.
|
||||
Enabled bool `json:"enabled"`
|
||||
Secondaries []ZoneSecondaryServer `json:"secondaries"`
|
||||
}
|
||||
|
||||
// ZoneSecondaryServer wraps elements of a Zone's "primary.secondary" attribute
|
||||
type ZoneSecondaryServer struct {
|
||||
// Read-Only
|
||||
NetworkIDs []int `json:"networks,omitempty"`
|
||||
|
||||
IP string `json:"ip"`
|
||||
Port int `json:"port,omitempty"`
|
||||
Notify bool `json:"notify"`
|
||||
}
|
||||
|
||||
// ZoneSecondary wraps a Zone's "secondary" attribute
|
||||
type ZoneSecondary struct {
|
||||
// Read-Only fields
|
||||
Expired bool `json:"expired,omitempty"`
|
||||
LastXfr int `json:"last_xfr,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Error *string `json:"error"`
|
||||
|
||||
PrimaryIP string `json:"primary_ip,omitempty"`
|
||||
PrimaryPort int `json:"primary_port,omitempty"`
|
||||
Enabled bool `json:"enabled"`
|
||||
|
||||
TSIG *TSIG `json:"tsig"`
|
||||
}
|
||||
|
||||
// TSIG is a zones transaction signature.
|
||||
type TSIG struct {
|
||||
// Key is the encrypted TSIG key(read-only)
|
||||
Key string `json:"key,omitempty"`
|
||||
|
||||
// Whether TSIG is enabled for a secondary zone.
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
// Which hashing algorithm
|
||||
Hash string `json:"hash,omitempty"`
|
||||
// Name of the TSIG key
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// NewZone takes a zone domain name and creates a new zone.
|
||||
func NewZone(zone string) *Zone {
|
||||
z := Zone{
|
||||
Zone: zone,
|
||||
}
|
||||
return &z
|
||||
}
|
||||
|
||||
// MakePrimary enables Primary, disables Secondary, and sets primary's
|
||||
// Secondaries to all provided ZoneSecondaryServers
|
||||
func (z *Zone) MakePrimary(secondaries ...ZoneSecondaryServer) {
|
||||
z.Secondary = nil
|
||||
z.Primary = &ZonePrimary{
|
||||
Enabled: true,
|
||||
Secondaries: secondaries,
|
||||
}
|
||||
if z.Primary.Secondaries == nil {
|
||||
z.Primary.Secondaries = make([]ZoneSecondaryServer, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// MakeSecondary enables Secondary, disables Primary, and sets secondary's
|
||||
// Primary_ip to provided ip.
|
||||
func (z *Zone) MakeSecondary(ip string) {
|
||||
z.Secondary = &ZoneSecondary{
|
||||
Enabled: true,
|
||||
PrimaryIP: ip,
|
||||
PrimaryPort: 53,
|
||||
}
|
||||
z.Primary = &ZonePrimary{
|
||||
Enabled: false,
|
||||
Secondaries: make([]ZoneSecondaryServer, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// LinkTo sets Link to a target zone domain name and unsets all other configuration properties.
|
||||
// No other zone configuration properties (such as refresh, retry, etc) may be specified,
|
||||
// since they are all pulled from the target zone. Linked zones, once created, cannot be
|
||||
// configured at all and cannot have records added to them. They may only be deleted, which
|
||||
// does not affect the target zone at all.
|
||||
func (z *Zone) LinkTo(to string) {
|
||||
z.Meta = nil
|
||||
z.TTL = 0
|
||||
z.NxTTL = 0
|
||||
z.Retry = 0
|
||||
z.Refresh = 0
|
||||
z.Expiry = 0
|
||||
z.Primary = nil
|
||||
z.DNSServers = nil
|
||||
z.NetworkIDs = nil
|
||||
z.NetworkPools = nil
|
||||
z.Hostmaster = ""
|
||||
z.Pool = ""
|
||||
z.Secondary = nil
|
||||
z.Link = &to
|
||||
}
|
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/filter/doc.go
generated
vendored
Normal file
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/filter/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package filter contains definitions for NS1 filter chains.
|
||||
package filter
|
182
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/filter/filter.go
generated
vendored
Normal file
182
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/filter/filter.go
generated
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
package filter
|
||||
|
||||
// Filter wraps the values of a Record's "filters" attribute
|
||||
type Filter struct {
|
||||
Type string `json:"filter"`
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
Config Config `json:"config"`
|
||||
}
|
||||
|
||||
// Enable a filter.
|
||||
func (f *Filter) Enable() {
|
||||
f.Disabled = false
|
||||
}
|
||||
|
||||
// Disable a filter.
|
||||
func (f *Filter) Disable() {
|
||||
f.Disabled = true
|
||||
}
|
||||
|
||||
// Config is a flat mapping where values are simple (no slices/maps).
|
||||
type Config map[string]interface{}
|
||||
|
||||
// NewSelFirstN returns a filter that eliminates all but the
|
||||
// first N answers from the list.
|
||||
func NewSelFirstN(n int) *Filter {
|
||||
return &Filter{
|
||||
Type: "select_first_n",
|
||||
Config: Config{"N": n},
|
||||
}
|
||||
}
|
||||
|
||||
// NewShuffle returns a filter that randomly sorts the answers.
|
||||
func NewShuffle() *Filter {
|
||||
return &Filter{Type: "shuffle", Config: Config{}}
|
||||
}
|
||||
|
||||
// GEOGRAPHICAL FILTERS
|
||||
|
||||
// NewSelFirstRegion returns a filter that keeps only the answers
|
||||
// that are in the same region as the first answer.
|
||||
func NewSelFirstRegion() *Filter {
|
||||
return &Filter{Type: "select_first_n", Config: Config{}}
|
||||
}
|
||||
|
||||
// NewStickyRegion first sorts regions uniquely depending on the IP
|
||||
// address of the requester, and then groups all answers together by
|
||||
// region. The same requester always gets the same ordering of regions,
|
||||
// but answers within each region may be in any order. byNetwork indicates
|
||||
// whether to apply the 'stickyness' by subnet(not individual IP).
|
||||
func NewStickyRegion(byNetwork bool) *Filter {
|
||||
return &Filter{
|
||||
Type: "sticky_region",
|
||||
Config: Config{"sticky_by_network": byNetwork},
|
||||
}
|
||||
}
|
||||
|
||||
// NewGeofenceCountry returns a filter that fences using "country",
|
||||
// "us_state", and "ca_province" metadata fields in answers. Only
|
||||
// answers in the same country/state/province as the user (or
|
||||
// answers with no specified location) are returned. rmNoLoc determines
|
||||
// whether to remove answers without location on any match.
|
||||
func NewGeofenceCountry(rmNoLoc bool) *Filter {
|
||||
return &Filter{
|
||||
Type: "geofence_country",
|
||||
Config: Config{"remove_no_location": rmNoLoc},
|
||||
}
|
||||
}
|
||||
|
||||
// NewGeofenceRegional returns a filter that restricts to answers in
|
||||
// same geographical region as requester. rmNoGeo determines whether
|
||||
// to remove answers without georegion on any match.
|
||||
func NewGeofenceRegional(rmNoGeo bool) *Filter {
|
||||
return &Filter{
|
||||
Type: "geofence_regional",
|
||||
Config: Config{"remove_no_georegion": rmNoGeo},
|
||||
}
|
||||
}
|
||||
|
||||
// NewGeotargetCountry returns a filter that sorts answers by distance
|
||||
// to requester by country, US state, and/or Canadian province.
|
||||
func NewGeotargetCountry() *Filter {
|
||||
return &Filter{Type: "geofence_country", Config: Config{}}
|
||||
}
|
||||
|
||||
// NewGeotargetLatLong returns a filter that sorts answers by distance
|
||||
// to user using lat/long.
|
||||
func NewGeotargetLatLong() *Filter {
|
||||
return &Filter{Type: "geotarget_latlong", Config: Config{}}
|
||||
}
|
||||
|
||||
// NewGeotargetRegional returns a filter that sorts answers by distance
|
||||
// to user by geographical region.
|
||||
func NewGeotargetRegional() *Filter {
|
||||
return &Filter{Type: "geotarget_regional", Config: Config{}}
|
||||
}
|
||||
|
||||
// NETWORK FILTERS
|
||||
|
||||
// NewSticky returns a filter that sorts answers uniquely depending
|
||||
// on the IP address of the requester. The same requester always
|
||||
// gets the same ordering of answers. byNetwork indicates whether
|
||||
// to apply the 'stickyness' by subnet(not individual IP).
|
||||
func NewSticky(byNetwork bool) *Filter {
|
||||
return &Filter{
|
||||
Type: "sticky",
|
||||
Config: Config{"sticky_by_network": byNetwork},
|
||||
}
|
||||
}
|
||||
|
||||
// NewWeightedSticky returns a filter that shuffles answers randomly
|
||||
// per-requester based on weight. byNetwork indicates whether to
|
||||
// apply the 'stickyness' by subnet(not individual IP).
|
||||
func NewWeightedSticky(byNetwork bool) *Filter {
|
||||
return &Filter{
|
||||
Type: "weighted_sticky",
|
||||
Config: Config{"sticky_by_network": byNetwork},
|
||||
}
|
||||
}
|
||||
|
||||
// NewIPv4PrefixShuffle returns a filter that randomly selects
|
||||
// IPv4 addresses from prefix list. This filter can only be used
|
||||
// A records. n is the number of IPs to randomly select per answer.
|
||||
func NewIPv4PrefixShuffle(n int) *Filter {
|
||||
return &Filter{
|
||||
Type: "ipv4_prefix_shuffle",
|
||||
Config: Config{"N": n},
|
||||
}
|
||||
}
|
||||
|
||||
// NewNetfenceASN returns a filter that restricts to answers where
|
||||
// the ASN of requester IP matches ASN list. rmNoASN determines
|
||||
// whether to remove answers without asn list on any match.
|
||||
func NewNetfenceASN(rmNoASN bool) *Filter {
|
||||
return &Filter{
|
||||
Type: "netfence_asn",
|
||||
Config: Config{"remove_no_asn": rmNoASN},
|
||||
}
|
||||
}
|
||||
|
||||
// NewNetfencePrefix returns a filter that restricts to answers where
|
||||
// requester IP matches prefix list. rmNoIPPrefix determines
|
||||
// whether to remove answers without ip prefixes on any match.
|
||||
func NewNetfencePrefix(rmNoIPPrefix bool) *Filter {
|
||||
return &Filter{
|
||||
Type: "netfence_prefix",
|
||||
Config: Config{"remove_no_ip_prefixes": rmNoIPPrefix},
|
||||
}
|
||||
}
|
||||
|
||||
// STATUS FILTERS
|
||||
|
||||
// NewUp returns a filter that eliminates all answers where
|
||||
// the 'up' metadata field is not true.
|
||||
func NewUp() *Filter {
|
||||
return &Filter{Type: "up", Config: Config{}}
|
||||
}
|
||||
|
||||
// NewPriority returns a filter that fails over according to
|
||||
// prioritized answer tiers.
|
||||
func NewPriority() *Filter {
|
||||
return &Filter{Type: "priority", Config: Config{}}
|
||||
}
|
||||
|
||||
// NewShedLoad returns a filter that "sheds" traffic to answers
|
||||
// based on load, using one of several load metrics. You must set
|
||||
// values for low_watermark, high_watermark, and the configured
|
||||
// load metric, for each answer you intend to subject to load
|
||||
// shedding.
|
||||
func NewShedLoad(metric string) *Filter {
|
||||
return &Filter{
|
||||
Type: "shed_load",
|
||||
Config: Config{"metric": metric},
|
||||
}
|
||||
}
|
||||
|
||||
// TRAFFIC FILTERS
|
||||
|
||||
// NewWeightedShuffle returns a filter that shuffles answers
|
||||
// randomly based on their weight.
|
||||
func NewWeightedShuffle() *Filter {
|
||||
return &Filter{Type: "weighted_shuffle", Config: Config{}}
|
||||
}
|
4
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/config.go
generated
vendored
Normal file
4
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/config.go
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
package monitor
|
||||
|
||||
// Config is a flat mapping where values are simple (no slices/maps).
|
||||
type Config map[string]interface{}
|
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/doc.go
generated
vendored
Normal file
2
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
// Package monitor contains definitions for NS1 monitoring jobs.
|
||||
package monitor
|
181
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job.go
generated
vendored
Normal file
181
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/job.go
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
package monitor
|
||||
|
||||
// Job wraps an NS1 /monitoring/jobs resource
|
||||
type Job struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// The id of the notification list to send notifications to.
|
||||
NotifyListID string `json:"notify_list"`
|
||||
|
||||
// Type of monitor to be run.
|
||||
// Available job types:
|
||||
// - http: Do an HTTP request against a webserver
|
||||
// - dns: Do a DNS lookup against a nameserver
|
||||
// - tcp: Connect to a TCP port on a host
|
||||
// - ping: Ping a host using ICMP packets
|
||||
Type string `json:"job_type"`
|
||||
|
||||
// Configuration dictionary(key/vals depend on the jobs' type).
|
||||
Config Config `json:"config"`
|
||||
|
||||
// The current status of the monitor.
|
||||
Status map[string]*Status `json:"status,omitempty"`
|
||||
|
||||
// Rules for determining failure conditions.
|
||||
Rules []*Rule `json:"rules,omitempty"`
|
||||
|
||||
// List of regions in which to run the monitor.
|
||||
// eg, ["dal", "sin", "sjc", "lga", "ams"]
|
||||
Regions []string `json:"regions"`
|
||||
|
||||
// Indicates if the job is active or temporarily disabled.
|
||||
Active bool `json:"active"`
|
||||
|
||||
// Frequency(in seconds), at which to run the monitor.
|
||||
Frequency int `json:"frequency"`
|
||||
|
||||
// The policy for determining the monitor's global status based
|
||||
// on the status of the job in all regions.
|
||||
// Available policies:
|
||||
// - quorum: Status change when majority status
|
||||
// - all: Status change only when all regions are in agreement
|
||||
// - one: Status change if any region changes
|
||||
Policy string `json:"policy"`
|
||||
|
||||
// Controls behavior of how the job is assigned to monitoring regions.
|
||||
// Currently this must be fixed — indicating monitoring regions are explicitly chosen.
|
||||
RegionScope string `json:"region_scope"`
|
||||
|
||||
// Freeform notes to be included in any notifications about this job,
|
||||
// e.g., instructions for operators who will receive the notifications.
|
||||
Notes string `json:"notes,omitempty"`
|
||||
|
||||
// A free-form display name for the monitoring job.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Time(in seconds) between repeat notifications of a failed job.
|
||||
// Set to 0 to disable repeating notifications.
|
||||
NotifyRepeat int `json:"notify_repeat"`
|
||||
|
||||
// If true, on any apparent state change, the job is quickly re-run after
|
||||
// one second to confirm the state change before notification.
|
||||
RapidRecheck bool `json:"rapid_recheck"`
|
||||
|
||||
// Time(in seconds) after a failure to wait before sending a notification.
|
||||
NotifyDelay int `json:"notify_delay"`
|
||||
|
||||
// If true, notifications are sent for any regional failure (and failback if desired),
|
||||
// in addition to global state notifications.
|
||||
NotifyRegional bool `json:"notify_regional"`
|
||||
|
||||
// If true, a notification is sent when a job returns to an "up" state.
|
||||
NotifyFailback bool `json:"notify_failback"`
|
||||
}
|
||||
|
||||
// Activate a monitoring job.
|
||||
func (j *Job) Activate() {
|
||||
j.Active = true
|
||||
|
||||
}
|
||||
|
||||
// Deactivate a monitoring job.
|
||||
func (j *Job) Deactivate() {
|
||||
j.Active = false
|
||||
}
|
||||
|
||||
// Result wraps an element of a JobType's "results" attribute
|
||||
type Result struct {
|
||||
Comparators []string `json:"comparators"`
|
||||
Metric bool `json:"metric"`
|
||||
Validator string `json:"validator"`
|
||||
ShortDesc string `json:"shortdesc"`
|
||||
Type string `json:"type"`
|
||||
Desc string `json:"desc"`
|
||||
}
|
||||
|
||||
// Status wraps an value of a Job's "status" attribute
|
||||
type Status struct {
|
||||
Since int `json:"since"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
// StatusLog wraps an NS1 /monitoring/history resource
|
||||
type StatusLog struct {
|
||||
Job string `json:"job"`
|
||||
Region string `json:"region"`
|
||||
Status string `json:"status"`
|
||||
Since int `json:"since"`
|
||||
Until int `json:"until"`
|
||||
}
|
||||
|
||||
// Rule wraps an element of a Job's "rules" attribute
|
||||
type Rule struct {
|
||||
Key string `json:"key"`
|
||||
Value interface{} `json:"value"`
|
||||
Comparison string `json:"comparison"`
|
||||
}
|
||||
|
||||
// NewHTTPConfig constructs/returns a job configuration for HTTP type jobs.
|
||||
// url is the URL to query. (Required)
|
||||
// method is the HTTP method(valid methods are HEAD, GET, and POST).
|
||||
// ua is the user agent text in the request header.
|
||||
// auth is the authorization header to use in request.
|
||||
// connTimeout is the timeout(in sec) to wait for query output.
|
||||
func NewHTTPConfig(url, method, ua, auth string, connTimeout int) *Config {
|
||||
return &Config{
|
||||
"url": url, // Required
|
||||
"method": method,
|
||||
"user_agent": ua,
|
||||
"auth": auth,
|
||||
"connection_timeout": connTimeout,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// NewDNSConfig constructs/returns a job configuration for DNS type jobs.
|
||||
// host is the IP address or hostname of the nameserver to query. (Required)
|
||||
// domain name to query. (Required)
|
||||
// port is the dns port to query on host.
|
||||
// t is the type of the DNS record type to query.
|
||||
// respTimeout is the timeout(in ms) after sending query to wait for the output.
|
||||
func NewDNSConfig(host, domain string, port int, t string, respTimeout int) *Config {
|
||||
return &Config{
|
||||
"host": host, // Required
|
||||
"domain": domain, // Required
|
||||
"port": port,
|
||||
"type": t,
|
||||
"response_timeout": respTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewTCPConfig constructs/returns a job configuration for TCP type jobs.
|
||||
// host is the IP address or hostname to connect to. (Required)
|
||||
// port is the tcp port to connect to on host. (Required)
|
||||
// connTimeout is the timeout(in ms) before giving up on trying to connect.
|
||||
// respTimeout is the timeout(in sec) after connecting to wait for output.
|
||||
// send is the string to send to the host upon connecting.
|
||||
// ssl determines whether to attempt negotiating an SSL connection.
|
||||
func NewTCPConfig(host string, port, connTimeout, respTimeout int, send string, ssl bool) *Config {
|
||||
return &Config{
|
||||
"host": host, // Required
|
||||
"port": port, // Required
|
||||
"connection_timeout": connTimeout,
|
||||
"response_timeout": respTimeout,
|
||||
"send": send,
|
||||
"ssl": ssl,
|
||||
}
|
||||
}
|
||||
|
||||
// NewPINGConfig constructs/returns a job configuration for PING type jobs.
|
||||
// host is the IP address or hostname to ping. (Required)
|
||||
// timeout is the timeout(in ms) before marking the host as failed.
|
||||
// count is the number of packets to send.
|
||||
// interval is the minimum time(in ms) to wait between sending each packet.
|
||||
func NewPINGConfig(host string, timeout, count, interval int) *Config {
|
||||
return &Config{
|
||||
"host": host, // Required
|
||||
"timeout": timeout,
|
||||
"count": count,
|
||||
"interval": interval,
|
||||
}
|
||||
}
|
72
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/notify.go
generated
vendored
Normal file
72
vendor/gopkg.in/ns1/ns1-go.v2/rest/model/monitor/notify.go
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
package monitor
|
||||
|
||||
// NotifyList wraps notifications.
|
||||
type NotifyList struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Notifications []*Notification `json:"notify_list,omitempty"`
|
||||
}
|
||||
|
||||
// Notification represents endpoint to alert to.
|
||||
type Notification struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Config Config `json:"config,omitempty"`
|
||||
}
|
||||
|
||||
// NewNotifyList returns a notify list that alerts via the given notifications.
|
||||
func NewNotifyList(name string, nl ...*Notification) *NotifyList {
|
||||
if nl == nil {
|
||||
nl = []*Notification{}
|
||||
}
|
||||
|
||||
return &NotifyList{Name: name, Notifications: nl}
|
||||
}
|
||||
|
||||
// NewUserNotification returns a notification that alerts via user.
|
||||
func NewUserNotification(username string) *Notification {
|
||||
return &Notification{
|
||||
Type: "user",
|
||||
Config: Config{"user": username}}
|
||||
}
|
||||
|
||||
// NewEmailNotification returns a notification that alerts via email.
|
||||
func NewEmailNotification(email string) *Notification {
|
||||
return &Notification{
|
||||
Type: "email",
|
||||
Config: Config{"email": email}}
|
||||
}
|
||||
|
||||
// NewFeedNotification returns a notification that alerts via datafeed.
|
||||
func NewFeedNotification(sourceID string) *Notification {
|
||||
return &Notification{
|
||||
Type: "datafeed",
|
||||
Config: Config{"sourceid": sourceID}}
|
||||
}
|
||||
|
||||
// NewWebNotification returns a notification that alerts via webhook.
|
||||
func NewWebNotification(url string) *Notification {
|
||||
return &Notification{
|
||||
Type: "webhook",
|
||||
Config: Config{"url": url}}
|
||||
}
|
||||
|
||||
// NewPagerDutyNotification returns a notification that alerts via pagerduty.
|
||||
func NewPagerDutyNotification(key string) *Notification {
|
||||
return &Notification{
|
||||
Type: "pagerduty",
|
||||
Config: Config{"service_key": key}}
|
||||
}
|
||||
|
||||
// NewHipChatNotification returns a notification that alerts via hipchat.
|
||||
func NewHipChatNotification(token, room string) *Notification {
|
||||
return &Notification{
|
||||
Type: "hipchat",
|
||||
Config: Config{"token": token, "room": room}}
|
||||
}
|
||||
|
||||
// NewSlackNotification returns a notification that alerts via slack.
|
||||
func NewSlackNotification(url, username, channel string) *Notification {
|
||||
return &Notification{
|
||||
Type: "slack",
|
||||
Config: Config{"url": url, "username": username, "channel": channel}}
|
||||
}
|
134
vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_job.go
generated
vendored
Normal file
134
vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_job.go
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/monitor"
|
||||
)
|
||||
|
||||
// JobsService handles 'monitoring/jobs' endpoint.
|
||||
type JobsService service
|
||||
|
||||
// List returns all monitoring jobs for the account.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#jobs-get
|
||||
func (s *JobsService) List() ([]*monitor.Job, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "monitoring/jobs", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
mjl := []*monitor.Job{}
|
||||
resp, err := s.client.Do(req, &mjl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return mjl, resp, nil
|
||||
}
|
||||
|
||||
// Get takes an ID and returns details for a specific monitoring job.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#jobs-jobid-get
|
||||
func (s *JobsService) Get(id string) (*monitor.Job, *http.Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", "monitoring/jobs", id)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var mj monitor.Job
|
||||
resp, err := s.client.Do(req, &mj)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &mj, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *MonitoringJob and creates a new monitoring job.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#jobs-put
|
||||
func (s *JobsService) Create(mj *monitor.Job) (*http.Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", "monitoring/jobs", mj.ID)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", path, &mj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update mon jobs' fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &mj)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update takes a *MonitoringJob and change the configuration details of an existing monitoring job.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#jobs-jobid-post
|
||||
func (s *JobsService) Update(mj *monitor.Job) (*http.Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", "monitoring/jobs", mj.ID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &mj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update mon jobs' fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &mj)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete takes an ID and immediately terminates and deletes and existing monitoring job.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#jobs-jobid-delete
|
||||
func (s *JobsService) Delete(id string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", "monitoring/jobs", id)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// History takes an ID and returns status log history for a specific monitoring job.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#history-get
|
||||
func (s *JobsService) History(id string, opts ...func(*url.Values)) ([]*monitor.StatusLog, *http.Response, error) {
|
||||
v := url.Values{}
|
||||
for _, opt := range opts {
|
||||
opt(&v)
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s/%s?%s", "monitoring/history", id, v.Encode())
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var slgs []*monitor.StatusLog
|
||||
resp, err := s.client.Do(req, &slgs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return slgs, resp, nil
|
||||
}
|
126
vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_notify.go
generated
vendored
Normal file
126
vendor/gopkg.in/ns1/ns1-go.v2/rest/monitor_notify.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/monitor"
|
||||
)
|
||||
|
||||
// NotificationsService handles 'monitoring/lists' endpoint.
|
||||
type NotificationsService service
|
||||
|
||||
// List returns all configured notification lists.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#lists-get
|
||||
func (s *NotificationsService) List() ([]*monitor.NotifyList, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "lists", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
nl := []*monitor.NotifyList{}
|
||||
resp, err := s.client.Do(req, &nl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return nl, resp, nil
|
||||
}
|
||||
|
||||
// Get returns the details and notifiers associated with a specific notification list.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#lists-listid-get
|
||||
func (s *NotificationsService) Get(listID string) (*monitor.NotifyList, *http.Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", "lists", listID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var nl monitor.NotifyList
|
||||
resp, err := s.client.Do(req, &nl)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "unknown notification list" {
|
||||
return nil, resp, ErrListMissing
|
||||
}
|
||||
}
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &nl, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *NotifyList and creates a new notify list.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#lists-put
|
||||
func (s *NotificationsService) Create(nl *monitor.NotifyList) (*http.Response, error) {
|
||||
req, err := s.client.NewRequest("PUT", "lists", &nl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update notify list fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &nl)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == fmt.Sprintf("notification list with name \"%s\" exists", nl.Name) {
|
||||
return resp, ErrListExists
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update adds or removes entries or otherwise update a notification list.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#list-listid-post
|
||||
func (s *NotificationsService) Update(nl *monitor.NotifyList) (*http.Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", "lists", nl.ID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &nl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update mon lists' fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &nl)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete immediately deletes an existing notification list.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#lists-listid-delete
|
||||
func (s *NotificationsService) Delete(listID string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("%s/%s", "lists", listID)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrListExists bundles PUT create error.
|
||||
ErrListExists = errors.New("notify List already exists")
|
||||
// ErrListMissing bundles GET/POST/DELETE error.
|
||||
ErrListMissing = errors.New("notify List does not exist")
|
||||
)
|
130
vendor/gopkg.in/ns1/ns1-go.v2/rest/record.go
generated
vendored
Normal file
130
vendor/gopkg.in/ns1/ns1-go.v2/rest/record.go
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/dns"
|
||||
)
|
||||
|
||||
// RecordsService handles 'zones/ZONE/DOMAIN/TYPE' endpoint.
|
||||
type RecordsService service
|
||||
|
||||
// Get takes a zone, domain and record type t and returns full configuration for a DNS record.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#record-get
|
||||
func (s *RecordsService) Get(zone, domain, t string) (*dns.Record, *http.Response, error) {
|
||||
path := fmt.Sprintf("zones/%s/%s/%s", zone, domain, t)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var r dns.Record
|
||||
resp, err := s.client.Do(req, &r)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "record not found" {
|
||||
return nil, resp, ErrRecordMissing
|
||||
}
|
||||
}
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &r, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *Record and creates a new DNS record in the specified zone, for the specified domain, of the given record type.
|
||||
//
|
||||
// The given record must have at least one answer.
|
||||
// NS1 API docs: https://ns1.com/api/#record-put
|
||||
func (s *RecordsService) Create(r *dns.Record) (*http.Response, error) {
|
||||
path := fmt.Sprintf("zones/%s/%s/%s", r.Zone, r.Domain, r.Type)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", path, &r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update record fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &r)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
switch err.(*Error).Message {
|
||||
case "zone not found":
|
||||
return resp, ErrZoneMissing
|
||||
case "record already exists":
|
||||
return resp, ErrRecordExists
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update takes a *Record and modifies configuration details for an existing DNS record.
|
||||
//
|
||||
// Only the fields to be updated are required in the given record.
|
||||
// NS1 API docs: https://ns1.com/api/#record-post
|
||||
func (s *RecordsService) Update(r *dns.Record) (*http.Response, error) {
|
||||
path := fmt.Sprintf("zones/%s/%s/%s", r.Zone, r.Domain, r.Type)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update records fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &r)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
switch err.(*Error).Message {
|
||||
case "zone not found":
|
||||
return resp, ErrZoneMissing
|
||||
case "record already exists":
|
||||
return resp, ErrRecordExists
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete takes a zone, domain and record type t and removes an existing record and all associated answers and configuration details.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#record-delete
|
||||
func (s *RecordsService) Delete(zone string, domain string, t string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("zones/%s/%s/%s", zone, domain, t)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "record not found" {
|
||||
return resp, ErrRecordMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrRecordExists bundles PUT create error.
|
||||
ErrRecordExists = errors.New("record already exists")
|
||||
// ErrRecordMissing bundles GET/POST/DELETE error.
|
||||
ErrRecordMissing = errors.New("record does not exist")
|
||||
)
|
15
vendor/gopkg.in/ns1/ns1-go.v2/rest/stat.go
generated
vendored
Normal file
15
vendor/gopkg.in/ns1/ns1-go.v2/rest/stat.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
package rest
|
||||
|
||||
// // GetQPSStats returns current queries per second (QPS) for the account
|
||||
// func (c APIClient) GetQPSStats() (v float64, err error) {
|
||||
// var s map[string]float64
|
||||
// _, err = c.doHTTPUnmarshal("GET", "https://api.nsone.net/v1/stats/qps", nil, &s)
|
||||
// if err != nil {
|
||||
// return v, err
|
||||
// }
|
||||
// v, found := s["qps"]
|
||||
// if !found {
|
||||
// return v, errors.New("Could not find 'qps' key in returned data")
|
||||
// }
|
||||
// return v, nil
|
||||
// }
|
42
vendor/gopkg.in/ns1/ns1-go.v2/rest/util.go
generated
vendored
Normal file
42
vendor/gopkg.in/ns1/ns1-go.v2/rest/util.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// DoerFunc satisfies Interface. DoerFuncs are useful for adding
|
||||
// logging/instrumentation to the http.Client that is used
|
||||
// within the rest.APIClient.
|
||||
type DoerFunc func(*http.Request) (*http.Response, error)
|
||||
|
||||
// Do is implementation of rest.Doer interface. Calls itself on the
|
||||
// given http.Request.
|
||||
func (f DoerFunc) Do(r *http.Request) (*http.Response, error) {
|
||||
return f(r)
|
||||
}
|
||||
|
||||
// A Decorator wraps a Doer with extra behavior, and doesnt
|
||||
// affect the behavior of other instances of the same type.
|
||||
type Decorator func(Doer) Doer
|
||||
|
||||
// Decorate decorates a Doer c with all the given Decorators, in order.
|
||||
// Core object(Doer instance) that we want to apply layers(Decorator slice) to.
|
||||
func Decorate(d Doer, ds ...Decorator) Doer {
|
||||
decorated := d
|
||||
for _, decorate := range ds {
|
||||
decorated = decorate(decorated)
|
||||
}
|
||||
return decorated
|
||||
}
|
||||
|
||||
// Logging returns a Decorator that logs a Doer's requests.
|
||||
// Dependency injection for the logger instance(inside the closures environment).
|
||||
func Logging(l *log.Logger) Decorator {
|
||||
return func(d Doer) Doer {
|
||||
return DoerFunc(func(r *http.Request) (*http.Response, error) {
|
||||
l.Printf("%s: %s %s", r.UserAgent(), r.Method, r.URL)
|
||||
return d.Do(r)
|
||||
})
|
||||
}
|
||||
}
|
140
vendor/gopkg.in/ns1/ns1-go.v2/rest/zone.go
generated
vendored
Normal file
140
vendor/gopkg.in/ns1/ns1-go.v2/rest/zone.go
generated
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/ns1/ns1-go.v2/rest/model/dns"
|
||||
)
|
||||
|
||||
// ZonesService handles 'zones' endpoint.
|
||||
type ZonesService service
|
||||
|
||||
// List returns all active zones and basic zone configuration details for each.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#zones-get
|
||||
func (s *ZonesService) List() ([]*dns.Zone, *http.Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "zones", nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
zl := []*dns.Zone{}
|
||||
resp, err := s.client.Do(req, &zl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return zl, resp, nil
|
||||
}
|
||||
|
||||
// Get takes a zone name and returns a single active zone and its basic configuration details.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#zones-zone-get
|
||||
func (s *ZonesService) Get(zone string) (*dns.Zone, *http.Response, error) {
|
||||
path := fmt.Sprintf("zones/%s", zone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var z dns.Zone
|
||||
resp, err := s.client.Do(req, &z)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "zone not found" {
|
||||
return nil, resp, ErrZoneMissing
|
||||
}
|
||||
}
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return &z, resp, nil
|
||||
}
|
||||
|
||||
// Create takes a *Zone and creates a new DNS zone.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#zones-put
|
||||
func (s *ZonesService) Create(z *dns.Zone) (*http.Response, error) {
|
||||
path := fmt.Sprintf("zones/%s", z.Zone)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", path, &z)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update zones fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &z)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "zone already exists" {
|
||||
return resp, ErrZoneExists
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Update takes a *Zone and modifies basic details of a DNS zone.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#zones-post
|
||||
func (s *ZonesService) Update(z *dns.Zone) (*http.Response, error) {
|
||||
path := fmt.Sprintf("zones/%s", z.Zone)
|
||||
|
||||
req, err := s.client.NewRequest("POST", path, &z)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update zones fields with data from api(ensure consistent)
|
||||
resp, err := s.client.Do(req, &z)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "zone not found" {
|
||||
return resp, ErrZoneMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Delete takes a zone and destroys an existing DNS zone and all records in the zone.
|
||||
//
|
||||
// NS1 API docs: https://ns1.com/api/#zones-delete
|
||||
func (s *ZonesService) Delete(zone string) (*http.Response, error) {
|
||||
path := fmt.Sprintf("zones/%s", zone)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", path, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *Error:
|
||||
if err.(*Error).Message == "zone not found" {
|
||||
return resp, ErrZoneMissing
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrZoneExists bundles PUT create error.
|
||||
ErrZoneExists = errors.New("zone already exists")
|
||||
// ErrZoneMissing bundles GET/POST/DELETE error.
|
||||
ErrZoneMissing = errors.New("zone does not exist")
|
||||
)
|
36
vendor/vendor.json
vendored
36
vendor/vendor.json
vendored
@ -626,6 +626,42 @@
|
||||
"revision": "c7b8227c83007befd67b324a64c969ebc1d7475d",
|
||||
"revisionTime": "2016-11-07T22:51:02Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "e7eKqt/2RnmGPYJtcJd4IY2M/DU=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest",
|
||||
"revision": "e2aebc8e980e326990999e4351c1c026c9d00c4a",
|
||||
"revisionTime": "2017-03-21T06:31:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "tdMxXKsUHn3yZpur14ZNLMVyQJM=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/account",
|
||||
"revision": "e2aebc8e980e326990999e4351c1c026c9d00c4a",
|
||||
"revisionTime": "2017-03-21T06:31:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "gBVND8veklEQV0gxF3lERV6mSZk=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/data",
|
||||
"revision": "e2aebc8e980e326990999e4351c1c026c9d00c4a",
|
||||
"revisionTime": "2017-03-21T06:31:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "GbL7ThrBZfKs1lhzguxzscIynac=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/dns",
|
||||
"revision": "e2aebc8e980e326990999e4351c1c026c9d00c4a",
|
||||
"revisionTime": "2017-03-21T06:31:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "CuurmNep8iMdYFodxRxAeewowsQ=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/filter",
|
||||
"revision": "e2aebc8e980e326990999e4351c1c026c9d00c4a",
|
||||
"revisionTime": "2017-03-21T06:31:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "B0C8F5th11AHl1fo8k0I8+DvrjE=",
|
||||
"path": "gopkg.in/ns1/ns1-go.v2/rest/model/monitor",
|
||||
"revision": "e2aebc8e980e326990999e4351c1c026c9d00c4a",
|
||||
"revisionTime": "2017-03-21T06:31:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "XvQ3McEKtKXKcU4lL447qeKi1RM=",
|
||||
"path": "gopkg.in/sourcemap.v1",
|
||||
|
Reference in New Issue
Block a user